diff --git a/.github/workflows/submit.yml b/.github/workflows/submit.yml index 9d19715a9862a7aed3803170feef90cd35ba527e..acf46c615ce6e9f392bc929f8a4260a3eefcee8e 100644 --- a/.github/workflows/submit.yml +++ b/.github/workflows/submit.yml @@ -341,6 +341,7 @@ jobs: run: > if ! grep --include=test-summary.txt -lqr build/*/test-results -e "TEST SUCCESS" ; then cat build/*/test-results/*/text/newfailures.txt ; + cat build/*/test-results/*/text/other_errors.txt ; exit 1 ; fi @@ -807,6 +808,7 @@ jobs: run: > if ! grep --include=test-summary.txt -lqr build/*/test-results -e "TEST SUCCESS" ; then cat build/*/test-results/*/text/newfailures.txt ; + cat build/*/test-results/*/text/other_errors.txt ; exit 1 ; fi @@ -1218,6 +1220,7 @@ jobs: run: > if ((Get-ChildItem -Path build\*\test-results\test-summary.txt -Recurse | Select-String -Pattern "TEST SUCCESS" ).Count -eq 0) { Get-Content -Path build\*\test-results\*\*\newfailures.txt ; + Get-Content -Path build\*\test-results\*\*\other_errors.txt ; exit 1 } @@ -1611,6 +1614,7 @@ jobs: run: > if ! grep --include=test-summary.txt -lqr build/*/test-results -e "TEST SUCCESS" ; then cat build/*/test-results/*/text/newfailures.txt ; + cat build/*/test-results/*/text/other_errors.txt ; exit 1 ; fi diff --git a/.hgtags b/.hgtags deleted file mode 100644 index ef4ec35e2f27ed951ce5306b393547235e25a97f..0000000000000000000000000000000000000000 --- a/.hgtags +++ /dev/null @@ -1,664 +0,0 @@ -3cc80be736f24704e505ad8ddaa598dec3fa2ed3 jdk-9+181 -e2b70be325bd10dae4c06f74c46d70d480854916 jdk-9+179 -5b16a1c3ccffff2a82c88bb7ea894c4ff1c9ebde jdk-9+180 -43bf6f30fcba031ecf0cc7e511efe3a8179d0f77 jdk-9+176 -d9f6bc6ba599d0487dc18b2fbdb6c34eedf6f958 jdk-9+177 -bc9df7dd63ec76f50fafeb4acc44465044662f0a jdk-9+178 -994036e74ab805bcc09afa0646be17a725bec42f jdk-9+175 -94680c6d60ecd9ed3ffd1847706efde7eb947afc jdk-9+174 -6dd7fda42bab7ecf648cafb0a4e9b4ca11b3094f jdk-9+173 -dad6746278facbbea57dd462cb56fb743dc0a5f0 jdk-9+172 -643b5f18c2656fe91b69fea85b07b98d5fad394d jdk-9+171 -898cbe31fbdae2d25d141384fac746cc244a730c jdk-9+170 -c7efde2b60fc1ec04630be769d9ad60efb39c39c jdk-9+169 -8fd0a4569191f33c98ee90c2709174a342fefb0d jdk-9+167 -fcabc74bd44e56c7419d111d59b95669ecb33c55 jdk-9+168 -d3e973f1809606c67412361041ad197e50fe8cec jdk-9+166 -3965b747cfe1e6cbd66b8739da5a1ea6ec6985e9 jdk-9+165 -d16aebbb56d37f12e0c0b0a4fb427db65e1fb1a8 jdk-9+162 -18c41483a082e097ac2f5f983c1226ed94aa4215 jdk-9+163 -32db52c675e7d5bc413605d2e89b68b608b19be0 jdk-9+164 -fd1497902bbe3aa24b21f270ecdcb8de5f7aa9ac jdk-9+159 -6aa8be0c4e054fe8b3ab016ae00d16d680f92145 jdk-9+160 -f6883b1a5a6478437cd4181c4bd45328ab24feaf jdk-9+161 -fa3e76b477829afc4476f0b725cfaa440a6fd917 jdk-9+157 -b5015f742ba648184bb7fc547197bd33ebfde30d jdk-9+158 -1cc8dd79fd1cd13d36b385196271a29632c67c3b jdk7-b24 -bf2517e15f0c0f950e5b3143c4ca11e2df73dcc1 jdk7-b25 -5ae7db536e3fcf6be78e45b240a9058095e0ed38 jdk7-b26 -67052ac87fc927d048e62ec54ff42adb230d3f7c jdk7-b27 -18dc4ba4739a537fd146f77da51db16efce28da2 jdk7-b28 -bfe4572fd301a6fcd120373cdb2eff5d2da0c72c jdk7-b29 -bee4731164a06ddece1297ae58db24aca6a1c626 jdk7-b30 -cd8b8f500face60d1566d850857a7fccadbd383a jdk7-b31 -a9f1805e3ba9ca520cad199d522c84af5433e85a jdk7-b32 -6838c1a3296aaa3572364d2ce7d70826cee96286 jdk7-b33 -90cf935adb353bb0af4b46fb0677e841fd24c000 jdk7-b34 -6d909d5803e3a22850e6c4e5a75b888742ee7e20 jdk7-b35 -d718a441936196b93d8bc9f084933af9a4c2a350 jdk7-b36 -c2036bf76829c03b99108fffab52e20910a9be4f jdk7-b37 -a2879b2837f5a4c87e9542efe69ef138194af8ff jdk7-b38 -126f365cec6c3c2c72de934fa1c64b5f082b55b5 jdk7-b39 -3c53424bbe3bb77e01b468b4b0140deec33e11fc jdk7-b40 -3cb2a607c347934f8e7e86f840a094c28b08d9ea jdk7-b41 -caf58ffa084568990cbb3441f9ae188e36b31770 jdk7-b42 -41bd0a702bc8ec6feebd725a63e7c3227f82ab11 jdk7-b43 -5843778bda89b1d5ac8e1aa05e26930ac90b3145 jdk7-b44 -54dffad0bf066791a2793305875250c395011d5f jdk7-b45 -04b2620edc72de93671646e4720c5992c74ac8b5 jdk7-b46 -0c4657194eec95c08ba478aee9cfc3c295e41657 jdk7-b47 -1bf51a4c2627c2f0e0cbcc2cf0421bdb37f1f2b2 jdk7-b48 -6b84b04a80afe23262377c60913eebfc898f14c4 jdk7-b49 -5da0e6b9f4f18ef483c977337214b12ee0e1fc8f jdk7-b50 -a25c5ec5e40e07733d1ff9898a0abe36159288ff jdk7-b51 -7a90e89e36d103038f8667f6a7daae34ecfa1ad8 jdk7-b52 -d52186ee770dac57950536cd00ccbfdef360b04c jdk7-b53 -15096652c4d48dfb9fc0b2cb135304db94c65ba0 jdk7-b54 -c8b275d62d6b0a980c510e839b70292245863e85 jdk7-b55 -a8134c4ee2cf451cf9b5e1609f39d83ecd53acc5 jdk7-b56 -b44f05654c26fcd1f995e712992f9b07ffd7c0c6 jdk7-b57 -d60a9ce3c3eabf28f5d50ae839d18be04a551bc2 jdk7-b58 -c33e7d38c9210741dbc285507403a4b20bd802a0 jdk7-b59 -5a10e4d0b14d7beac53a7b2213ae6864afe1fd3e jdk7-b60 -dbb955b1ee59b876dd1f133952b557b48b1d7732 jdk7-b61 -6107cbff3130c747d243c25a7874cd59db5744a8 jdk7-b62 -dfd8506f74c3731bb169ce93c72612d78ee0413b jdk7-b63 -d22867c5f1b295a0a2b3b4bc8999a2676f6e20c3 jdk7-b64 -7d3bf00f3cc4f8125de1842521e7567f37dc84b8 jdk7-b65 -62109d1b9e7310f29ab51ca6f1d71b899c0ce6b0 jdk7-b66 -eb24af1404aec8aa140c4cd4d13d2839b150dd41 jdk7-b67 -bca2225b66d78c4bf4d9801f54cac7715a598650 jdk7-b68 -1b662b1ed14eb4ae31d5138a36c433b13d941dc5 jdk7-b69 -207f694795c448c17753eff1a2f50363106960c2 jdk7-b70 -c5d39b6be65cba0effb5f466ea48fe43764d0e0c jdk7-b71 -df4bcd06e1d0ab306efa5a44f24a409dc0c0c742 jdk7-b72 -ce74bd35ce948d629a356e168797f44b593b1578 jdk7-b73 -4e7661eaa211e186674f6cbefec4aef1144ac2a0 jdk7-b74 -946518568340c4e511549318f19f47f06b7f5f9b jdk7-b75 -09e0b33177af2b98a03c9ca19eedf61440bd1cf6 jdk7-b76 -1d0121b741f029dc4b828e4b36ba6fda92907dd7 jdk7-b77 -4061c66ba1af1a2e27c2c839ba887407dd3ce050 jdk7-b78 -e9c98378f6b9256c0595ef2985ca5899f0c0e274 jdk7-b79 -e6abd38682d237306d6c147c17538ec9e7f8e3a7 jdk7-b80 -dcc938ac40cc45f1ef454d76020b5db5d943001c jdk7-b81 -a30062be6d9ca1d48579826f870f85974300004e jdk7-b82 -34c8199936a1682aa8587857f44cfaf37c2b6381 jdk7-b83 -b1e55627a6980b9508854ed0c0f21d4f981b4494 jdk7-b84 -b6f633a93ae0ec4555ff4bf756f5e2150c9bdede jdk7-b85 -c94d9cc81f495d97817eba9d71b84fc45f7661a5 jdk7-b86 -b7456c473862048fa70ed8092313a4ef0a55d403 jdk7-b87 -7077b95d42f6b3942a8751bba033801ff50e5889 jdk7-b88 -44158f6d3b94c0fa020e33632532473d92d1ea96 jdk7-b89 -1d1927f9ec097b62c913921e2dfa5dbaf5dc325b jdk7-b90 -308ad8f68b8dd68e22d73dd490e110059b732422 jdk7-b91 -ff9031a745d9cc52318f2148e43ca3b07ee08098 jdk7-b92 -b5dab6a313fdff4c043250e4d9c8f66fd624d27e jdk7-b93 -8bb281f0f91582104d65d032be22522bfd2d8110 jdk7-b94 -654298d26561b76dfe3cfcffbbd7078080837300 jdk7-b95 -d260f892491e040ae385a8e6df59557a7d721abf jdk7-b96 -7e406ebed9a5968b584f3c3e6b60893b5d6d9741 jdk7-b97 -db6e660120446c407e2d908d52ec046592b21726 jdk7-b98 -c4c8a5bc54f66abc68cd185d9294042121922154 jdk7-b99 -2d6ba7a221915bdf0311acc5641c7f3875cb793e jdk7-b100 -2548ac036b8fca3326d058d758e6df8355a42469 jdk7-b101 -88db80c8e49cea352c2900f689600dc410761c1f jdk7-b102 -64770970865839b0443066370e7d476ef47e90cd jdk7-b103 -10bc903a228d3a8efdf46fb8c3fcf82a59b88bc5 jdk7-b104 -1ce7938efb03224ccc8b3cdd7803eb39e889539c jdk7-b105 -6bdae472f77205046703b685eff2ac4f7a0ecf4e jdk7-b106 -439de530aac531a360beedba6e2fe51e17292cc0 jdk7-b107 -044d31b99ef5609389fc771c422e722e5e224228 jdk7-b108 -e02b4d709e177d08d56130a4bc68061e4bbacc7d jdk7-b109 -a6442d6bc38a44152e0662688213ce4d2701f42a jdk7-b110 -69f3edf083477955b5bd2f754252c7504167d8e1 jdk7-b111 -f960f117f1623629f64203e2b09a92a8f6f14ff5 jdk7-b112 -1fee41c7ed2b3388970a756a85aa693c0de8407a jdk7-b113 -750c1ccb2f2d1ddfa95ab6c7f897fdab2f87f7e9 jdk7-b114 -9cb24917216bc68997154f6e9566c3de62acb2f4 jdk7-b115 -a4e6aa1f45ad23a6f083ed98d970b5006ea4d292 jdk7-b116 -228e73f288c543a8c34e2a54227103ae5649e6af jdk7-b117 -2e876e59938a853934aa738c811b26c452bd9fe8 jdk7-b118 -4951967a61b4dbbf514828879f57bd1a0d4b420b jdk7-b119 -8c840d3ab24f8d0f422b991638acb44b6ab1d98c jdk7-b120 -0ce0a2c3a6926677dc507839a820ab6625541e5a jdk7-b121 -6f09ea1c034f087916d2a8cf0d22be768400118f jdk7-b122 -142129d8599d1f56b29387e7f9a5fad53b6d61df jdk7-b123 -aa894c225b1a517b665ac2a58295217ea2245134 jdk7-b124 -f658ec2730fa29323c36d23c27e54c7219ef5e16 jdk7-b125 -f1df068076986679ea1105532a65529d63a89060 jdk7-b126 -f83cd8bd35c678f94e526990e03dc838d0ec2717 jdk7-b127 -7da3f5f30855dec6bf3a86529e87dee883b90c72 jdk7-b128 -6823ea7eb8eb6fab405d7edb7a5c2f690887a2fa jdk7-b129 -a36beda9b9de91231d92a2c529f21cc218fcf8d5 jdk7-b130 -d8af56da89bc0fc02a6b6ad78f51157a46d665ab jdk7-b131 -d61280d36755d1941fb487f554e8b7a6d0bca6a1 jdk7-b132 -fd444c61e7ed3d92b2a730da7c737b02191b682f jdk7-b133 -def8e16dd237a47fc067d66d4c616d7baaec6001 jdk7-b134 -f75a1efb141210901aabe00a834e0fc32bb8b337 jdk7-b135 -46acf76a533954cfd594bb88fdea79938abfbe20 jdk7-b136 -d1cf7d4ee16c341f5b8c7e7f1d68a8c412b6c693 jdk7-b137 -62b8e328f8c8c66c14b0713222116f2add473f3f jdk7-b138 -955488f34ca418f6cdab843d61c20d2c615637d9 jdk7-b139 -f4298bc3f4b6baa315643be06966f09684290068 jdk7-b140 -5d86d0c7692e8f4a58d430d68c03594e2d3403b3 jdk7-b141 -92bf0655022d4187e9b49c1400f98fb3392a4630 jdk7-b142 -4a05062d8c4dfa3edec3faf1052af28baba5adff jdk7-b143 -07a8728ad49ef6dfa469c3a8bf5ab1e9c80bed5c jdk7-b144 -8294c99e685a1f6d1d37c45cd97854cf74be771e jdk7-b145 -dca1e8a87e8f756f95b99bac8fe795750d42e1b0 jdk7-b146 -a2a589fc29543ed32919c78a1810ad93a6fcf5bc jdk7-b147 -de9223c94f9c710b3eebb599cd3586f36c8b94a9 jdk8-b01 -1b9d19620eb4606a25b1e28f86d66c8bfa867e06 jdk8-b02 -6815e85bf96d6d3875954f9777660372cd70d065 jdk8-b03 -31f5c34d78081572ad9a2401c0bb0c6b9711dd65 jdk8-b04 -c4f9ea1ecb55ff44e0dd21d2888ead308c86a3aa jdk8-b05 -429da7734bf491bccde2a752fae97e9f225896dc jdk8-b06 -bc5710332b294676661103bb20d47d2ea3ba8def jdk8-b07 -24ee504f80412770c6874836cd9e55b536427b1d jdk8-b08 -fbf3cabc9e3bb1fcf710941d777cb0400505fbe6 jdk8-b09 -f651ce87127980c58e3599daba964eba2f3b4026 jdk8-b10 -cc1f5ce8e504d350e0b0c28c5f84333f8d540132 jdk8-b11 -86db042b3385c338e17f7664447fdc7d406dd19e jdk8-b12 -4cc0ef72c812943743ef4765f1100e2fbe2b1a08 jdk8-b13 -9ffaa48dbfb0f5936c2b789867d0785faec7071d jdk8-b14 -b5060eae3b32fd9f884a09774338cd8186d7fafa jdk8-b15 -736a63b854f321c7824b7e47890135f80aee05e3 jdk8-b16 -f0eccb2946986fb9626efde7d8ed9c8192623f5c jdk8-b17 -885050364691ac1ac978305c63f3368a197fb04d jdk8-b18 -0ff7113a0882ec82d642cb9f0297b4e497807ced jdk8-b19 -6561530ea757c3f3a6fb171c9cc7b3885cdeca85 jdk8-b20 -b3a426170188f52981cf4573a2f14d487fddab0d jdk8-b21 -e8f03541af27e38aafb619b96863e17f65ffe53b jdk8-b22 -498124337041ad53cbaa7eb110f3d7acd6d4eac4 jdk8-b23 -7d3720d8c595d1519c31e9ff7366203fc2c61350 jdk8-b24 -0071a6d64113a35ba345bb1580c256de5ce17d3e jdk8-b25 -6c805d8ed4e5449ea5e4d158c7bdbd7b0b70efd1 jdk8-b26 -c51754cddc037b9609e202b9ed38363d8683e7a8 jdk8-b27 -16ba58282d117247f480aae7a79b88141ade52a3 jdk8-b28 -e070119aa56ee4dc5506c19d2c4d2eecab8ad429 jdk8-b29 -23da7804aca0c9c4e6e86532a1453125a76d95ee jdk8-b30 -bac81e9f7d57b75fba5ab31b571f3fe0dc08af69 jdk8-b31 -2c5208ccb863db936eab523f49450b3fcd230348 jdk8-b32 -a6e6d42203e6d35f9e8b31eac25b0021b4dd58ad jdk8-b33 -0ae89825c75c9492e44efb3aca3d9ee3d8a209df jdk8-b34 -f151d5833912a82cd4f203944da0305c3be83ecc jdk8-b35 -98ce9816ae089c959ba1e70fba98423a31c4e9fa jdk8-b36 -b3a91113026c99b0da010d41055719ab0d8938f0 jdk8-b37 -4cc5610a6dd6227da766ebf9742eb11ff5ded6c0 jdk8-b38 -35a5397278779a2f8f3013f81586dc8f30cb149d jdk8-b39 -6e4e654931b976304bf6e7b4d0d6db8f75bac5d9 jdk8-b40 -c029c972396cea042a0dc67c0f7ccf2fe68007d4 jdk8-b41 -5c5a64ec0839df5affe9394b99ff338c363acbca jdk8-b42 -69d8a827cdf9236be9694a46d75c710d71dac7d7 jdk8-b43 -7e981cb0ad6a194f1fa859f9ad47586db461f269 jdk8-b44 -9b19b2302c28f4da6d4078f66234abecfed5688a jdk8-b45 -600c9a1feb01633cbcf2341a43d1d21e6497ecd0 jdk8-b46 -b820143a6f1ce993c6e6f31db4d64de990f42654 jdk8-b47 -086271e35b0a419b38e8bda9bebd70693811df0a jdk8-b48 -cecd7026f30cbd83b0601925a7a5e059aec98138 jdk8-b49 -38fe5ab028908cf64dd73a43336ba3211577bfc3 jdk8-b50 -382651d28f2502d371eca751962232c0e535e57a jdk8-b51 -b67041a6cb508da18d2f5c7687e6a31e08bea4fc jdk8-b52 -c7aa5cca1c01689a7b1a92411daf83684af05a33 jdk8-b53 -7c6aa31ff1b2ae48c1c686ebe1aadf0c3da5be15 jdk8-b54 -319f583f66db47395fa86127dd3ddb729eb7c64f jdk8-b55 -ffe6bce5a521be40146af2ac03c509b7bac30595 jdk8-b56 -2c21c080b11b93efb3851e39e1363e45da805943 jdk8-b57 -479d3302a26d7607ba271d66973e59ebf58825b6 jdk8-b58 -3bd874584fc01aae92fbc8827e2bd04d8b6ace04 jdk8-b59 -5e3adc681779037a2d33b7be6f75680619085492 jdk8-b60 -cdaa6122185f9bf512dcd6600f56bfccc4824e8c jdk8-b61 -8d9d430b4244b95f5cf1ebe719f834a1ac5d6cd5 jdk8-b62 -21ee1dd7b809639284900a128b9b656a592ebc7a jdk8-b63 -70fa4b11f26522e69b51fd652215f60ce350bac3 jdk8-b64 -a2cf4d4a484378caea2e827ed604b2bbae58bdba jdk8-b65 -17820b958ae84f7c1cc6719319c8e2232f7a4f1d jdk8-b66 -76cc9bd3ece407d3a15d3bea537b57927973c5e7 jdk8-b67 -cb33628d4e8f11e879c371959e5948b66a53376f jdk8-b68 -adb5171c554e14cd86f618b5584f6e3d693d5889 jdk8-b69 -0d625373c69e2ad6f546fd88ab50c6c9aad01271 jdk8-b70 -a41ada2ed4ef735449531c6ebe6cec593d890a1c jdk8-b71 -6725b3961f987cf40f446d1c11cd324a3bec545f jdk8-b72 -fe94b40ffd9390f6cffcdf51c0389b0e6dde0c13 jdk8-b73 -f627eff819628822a0777af8062244352f2a29cf jdk8-b74 -f1478a6d25fddd311a84dcbfac50824cc1858bdd jdk8-b75 -f407160c280d1c5b00d314c535441ac26f195fee jdk8-b76 -d17eb2e13e362085e866d46235314c50cc4661cc jdk8-b77 -6d3dcd34b5b962ea1ef9eed0dafdee9e812401bc jdk8-b78 -a1313a8d90d17d363a3b2a645dc4030ec204b168 jdk8-b79 -3fa21fbf9be7e6b482af43aacb6a09acfa30bdb6 jdk8-b80 -e41d716405b209d3eddef8bd4240cec2bd34dcca jdk8-b81 -5e8c55025644730385a6f8fa029ecdb2d2c98a07 jdk8-b82 -bcebd3fdefc91abb9d7fa0c5af6211b3f8720da6 jdk8-b83 -d7ad0dfaa41151bd3a9ae46725b0aec3730a9cd0 jdk8-b84 -1872c12529090e1c1dbf567f02ad7ae6231b8f0c jdk8-b85 -da9a4c9312816451884aa6db6f18be51a07bff13 jdk8-b86 -5ebf6c63714de2c9dcf831074086d31daec819df jdk8-b87 -e517701a4d0e25ae9c7945bca6e1762a8c5d8aa6 jdk8-b88 -4dec41b3c5e3bb616f0c6f15830d940905aa5d16 jdk8-b89 -f09ab0c416185e3cba371e81bcb6a16060c90f44 jdk8-b90 -80b6c3172dc2cfceb022411292d290a967f9c728 jdk8-b91 -2fd6acba737b01e705e1f7c33588c922a3787f13 jdk8-b92 -b72ae39e1329fefae50d4690db4fde43f3841a95 jdk8-b93 -0d804e3b955dce406af6a79ac1cc35c696aff7fb jdk8-b94 -49fe9c8049132647ad38837a877dd473e6c9b0e5 jdk8-b95 -ea73f01b9053e7165e7ba80f242bafecbc6af712 jdk8-b96 -0a85476a0b9cb876d5666d45097dac68bef3fce1 jdk8-b97 -711eb4aa87de68de78250e0549980936bab53d54 jdk8-b98 -2d3875b0d18b3ad1c2bebf385a697e309e4005a4 jdk8-b99 -3d34036aae4ea90b2ca59712d5a69db3221f0875 jdk8-b100 -edb01c460d4cab21ff0ff13512df7b746efaa0e7 jdk8-b101 -bbe43d712fe08e650808d774861b256ccb34e500 jdk8-b102 -30a1d677a20c6a95f98043d8f20ce570304e3818 jdk8-b103 -b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104 -589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105 -514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106 -892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107 -74049f7a28b48c14910106a75d9f2504169c352e jdk8-b108 -af9a674e12a16da1a4bd53e4990ddb1121a21ef1 jdk8-b109 -b5d2bf482a3ea1cca08c994512804ffbc73de0a1 jdk8-b110 -b9a0f6c693f347a6f4b9bb994957f4eaa05bdedd jdk8-b111 -ad67c34f79c28a8e755f4a49f313868619d6702c jdk8-b112 -4a4dbcf7cb7d3e1a81beaa3b11cd909f69ebc79a jdk8-b113 -dfa34ab293faad9b543a24646dbb381bc3ab5586 jdk8-b114 -3dd9732b17034f45d111996d1d50287b05a3998c jdk8-b115 -aaf663f591aba43ec942263b15ba62759ce26a1e jdk8-b116 -31b0e03fcad73d7886b306b4c2e57ad270780d0d jdk8-b117 -f5b521ade7a35cea18df78ee86322207729f5611 jdk8-b118 -87b743b2263cc53955266411b7797b365a0fb050 jdk8-b119 -a1ee9743f4ee165eae59389a020f2552f895dac8 jdk8-b120 -13b877757b0b1c0d5813298df85364f41d7ba6fe jdk9-b00 -f130ca87de6637acae7d99fcd7a8573eea1cbaed jdk9-b01 -b32e2219736e42baaf45daf0ad67ed34f6033799 jdk9-b02 -7f655f31f9bcee618cf832f08176ad8c1ed3fdd3 jdk9-b03 -099891b1d86f3719e116ac717ffdafc90d037fb7 jdk9-b04 -dd311791ad6895a3989020dd6c6c46db87972ab8 jdk9-b05 -85dbdc227c5e11429b4fc4a8ba763f50107edd6e jdk9-b06 -c826d05f1fb0773f6a28caa763307dd30d90d36e jdk9-b07 -b47e021195757f8f45582124ea7cad48ccf5f872 jdk9-b08 -efe7dbc6088691757404e0c8745f894e3ca9c022 jdk9-b09 -8c0bdeecd7c0f9ce3f3762a51991f755cb3a972c jdk9-b10 -0809c9a4d36e6291f1c4384604c4bbf29e975722 jdk9-b11 -0d1f816217dce5e72187f167cc1816080cbeb453 jdk9-b12 -1a30593dcb9802faec3b6edb24d86ca088594e4e jdk9-b13 -97932f6ad950ae5a73a9da5c96e6e58503ff646b jdk9-b14 -74eb0778e4f2dbff6628e718378449fba27c4265 jdk9-b15 -4a09f5d30be844ac6f714bdb0f63d8c3c08b9a98 jdk9-b16 -410bccbded9e9cce80f1e13ad221e37ae97a3986 jdk9-b17 -c5495e25c7258ab5f96a1ae14610887d76d2be63 jdk9-b18 -2dcf544eb7ed5ac6a3f7813a32e33acea7442405 jdk9-b19 -89731ae72a761afdf4262e8b9513f302f6563f89 jdk9-b20 -28dd0c7beb3cad9cf95f17b4b5ad87eb447a4084 jdk9-b21 -9678e0db8ff6ed845d4c2ee4a3baf7f386a777e5 jdk9-b22 -39cfdc2dcaf3f195c55398e4e677ab053b07e3d2 jdk9-b23 -d9ce05f36ffec3e5e8af62a92455c1c66a63c320 jdk9-b24 -13a5c76976fe48e55c9727c25fae2d2ce7c05da0 jdk9-b25 -cd6f4557e7fea5799ff3762ed7a80a743e75d5fd jdk9-b26 -d06a6d3c66c08293b2a9650f3cc01fd55c620e65 jdk9-b27 -f4269e8f454eb77763ecee228a88ae102a9aef6e jdk9-b28 -c36c0092693707a8255561433647e8c3cd724ccd jdk9-b29 -b2287cac7813c70ed7f679d9a46fe774bd4005f8 jdk9-b30 -9d0e6639a4d71b63507dd94b1a028e963b27e798 jdk9-b31 -1b1ec4291abc0ba6da7bf79b754f08dd759a4a0c jdk9-b32 -f0c5e4b732da823bdaa4184133675f384e7cd68d jdk9-b33 -9618201c5df28a460631577fad1f61e96f775c34 jdk9-b34 -a137992d750c72f6f944f341aa19b0d0d96afe0c jdk9-b35 -41df50e7303daf73c0d661ef601c4fe250915de5 jdk9-b36 -b409bc51bc23cfd51f2bd04ea919ec83535af9d0 jdk9-b37 -948cceef81ba4cb34bc233e7cc5952951ff04e88 jdk9-b38 -4e7c4d692e934cb9023af8201e7c2b510e9c4ee1 jdk9-b39 -82f4cb44b2d7af2352f48568a64b7b6a5ae960cd jdk9-b40 -9fffb959eb4197ff806e4ac12244761815b4deee jdk9-b41 -3107be2ba9c6e208a0b86bc7100a141abbc5b5fb jdk9-b42 -6494b13f88a867026ee316b444d9a4fa589dd6bd jdk9-b43 -abbfccd659b91a7bb815d5e36fed635dcdd40f31 jdk9-b44 -bfc24ae2b900187585079bb11e66e459d1e525fe jdk9-b45 -722378bc599e38d9a1dd484de30f10dfd7b21438 jdk9-b46 -8327024a99559982b848e9c2191da9c0bf8838fd jdk9-b47 -b2f9702efbe95527ea3a991474fda23987ff1c5c jdk9-b48 -5b8db585a33c3cc48e70e688ceee57dd9271dc5d jdk9-b49 -1550b2f6b63d1411fa84dc7bbc6f04809aedb43f jdk9-b50 -6efe265424e3f1ea596408a1f71baf2de316c772 jdk9-b51 -d6224d6021459ac8b3832e822f5acc849fa944af jdk9-b52 -874d76e4699dfcd61ae1826c9fe0ddc1610ad598 jdk9-b53 -82cd31c5d6ca8d4c1653f4eb1c09eb2d9a3b2813 jdk9-b54 -c97e2d1bad9708d379793ba2a4c848eda14c741e jdk9-b55 -47544495db2d3d2edf0f85862d8715592fdb919f jdk9-b56 -ddb95d8f169b09544cc17e72a6baaff2400092f5 jdk9-b57 -f40752db7773ca0c737f2ad88371e35c57fdfed7 jdk9-b58 -da950f343762a856d69751570a4c07cfa68a415b jdk9-b59 -38f98cb6b33562a926ec3b79c7b34128be37647d jdk9-b60 -ac3f5a39d4ff14d70c365e12cf5ec8f2abd52a04 jdk9-b61 -e7dbbef69d12b6a74dfad331b7188e7f893e8d29 jdk9-b62 -989253a902c34dcb7564695161c9200a5fbb7412 jdk9-b63 -8ffdeabc7c2b9a8280bf46cae026ac46b4d31c26 jdk9-b64 -4915246064b2f89d5f00c96e758686b7fdad36a6 jdk9-b65 -ff3fc75f3214ad7e03595be1b0d0f38d887b6f0e jdk9-b66 -56166ce66037952fa21e9f680b31bf8eb47312c0 jdk9-b67 -5b500c93ce4822d47061cd518ff3f72d9d8cb5b5 jdk9-b68 -d69c968463f0ae5d0b45de3fc14fe65171b23948 jdk9-b69 -43d0179ee9de3bfffae3417f09e07eb6d8efc963 jdk9-b70 -f66c185284727f6e6ffd27e9c45ed2dd9da0a691 jdk9-b71 -61d2d0629b6dbf4c091dc86151ade1b3ef34fffe jdk9-b72 -9b3a9d72f07b40c648de79961679f42283af1bb5 jdk9-b73 -7c577fda1855d03c04546694d514678f596508c9 jdk9-b74 -f55df5cfe11c97e4b58998b76f5bd00a73cde12d jdk9-b75 -eeea9adfd1e3d075ef82148c00a4847a1aab4d26 jdk9-b76 -c25e882cee9622ec75c4e9d60633539a2f0a8809 jdk9-b77 -c8753d0be1778944dc512ec86a459941ea1ad2c3 jdk9-b78 -3966bd3b8167419aa05c6718a4af1cf54b1e3c58 jdk9-b79 -3c9f5bd909ae7187f24622ee4b69f8a5756a9271 jdk9-b80 -2050b3a0aadcb0e024bf798197421d58e54ec8bf jdk9-b81 -6521875cb63e1d0121b30af56ebbc36db078c4c6 jdk9-b82 -f61a63b7d1e52e307abc0bfc751203155d362ec4 jdk9-b83 -51b2db2fa04c16d767b66113dbf08c5349ce382a jdk9-b84 -8392405ab038b22e69a3728e17dbdd9e3d3a22ed jdk9-b85 -7db0663a5e968059fa7c772172187ebd60b6492d jdk9-b86 -1a52a30674cd28c24d4d388150336121f2e9ddf9 jdk9-b87 -16b4968f9bb8f34371b42c0ba483d76e91ba84d8 jdk9-b88 -4a0312f2894bcbe1fd20266c8fda8d983bd2fcf6 jdk9-b89 -d131f4b8433a79408f935eff9bf92a0664229b60 jdk9-b90 -8077fd2f055d31e50b46fcf62d9c035bc385a215 jdk9-b91 -f242d4332f563648426a1b0fa02d8741beba19ef jdk9-b92 -09206c6513b300e1ac8541f3be012e1a49312104 jdk9-b93 -25a2cab05cfbe6034b71d9e72d64c65b0572ce63 jdk9-b94 -5ac6287ec71aafe021cc839d8bc828108d23aaba jdk-9+95 -139f19d70350238e15e107945cea75082b6380b3 jdk-9+96 -4edcff1b9a8875eb6380a2165dfec599e8e3f7c0 jdk-9+97 -d00ad2d9049ac60815f70bff445e95df85648bd2 jdk-9+98 -f9bcdce2df26678c3fe468130b535c0342c69b89 jdk-9+99 -4379223f8806626852c46c52d4e7a27a584b406e jdk-9+100 -80f67512daa15cf37b4825c1c62a675d524d7c49 jdk-9+101 -2dc4c11fe48831854916d53c3913bdb7d49023ea jdk-9+102 -4a652e4ca9523422149958673033e0ac740d5e1e jdk-9+103 -086c682bd8c5f195c324f61e2c61fbcd0226d63b jdk-9+104 -db483b34fa7148d257a429acddbde9c13687dcae jdk-9+105 -6c644cca3f3fc2763e2ff7d669849a75d34543ba jdk-9+106 -1c076468bf7dad5b8f2ee5dcf66e2279caa3e208 jdk-9+107 -257b579d813201682931d6b42f0445ffe5b4210d jdk-9+108 -c870cb782aca71093d2584376f27f0cfbfec0e3a jdk-9+109 -4a95f4b1bd8bfce85dc02a593896749feab96c34 jdk-9+110 -a6614ff7bf09da74be1d0ef3d9755090d244697a jdk-9+111 -7359994942f8d8e723b584d66a3a92c2e9e95e5c jdk-9+112 -6072af7a98be3922f26bdce71b53bb3646cb2ac9 jdk-9+113 -c84d0cce090e161d736de69e941830adf8c2f87a jdk-9+114 -8d78fb40648dd221ce4ef19f9d5aa41ee1a3a884 jdk-9+115 -84aba7335005a3a47751dcf1f37935f97df9f99a jdk-9+116 -82b8d12a553f5617737c238cec060281d52e351c jdk-9+117 -7c04fcb12bd4a31570a238e663fa846dfa5ec3b8 jdk-9+118 -caf97b37ebec84288c112d21d3a60cb628cba1e8 jdk-9+119 -9330543436402b8f3bd070524846a464d8143557 jdk-9+120 -18e5cdecb37a2f03ba74f6c8f022858bcbaacf56 jdk-9+121 -7693aa00e131493ceb42b93305e2f014c9922a3b jdk-9+122 -d53037a90c441cb528dc41c30827985de0e67c62 jdk-9+123 -2a5697a98620c4f40e4a1a71478464399b8878de jdk-9+124 -3aa52182b3ad7c5b3a61cf05a59dd07e4c5884e5 jdk-9+125 -03e7b2c5ae345be3caf981d76ceb3efe5ff447f8 jdk-9+126 -8e45018bde9de4ad15b972ae62874bba52dba2d5 jdk-9+127 -5bf88dce615f6804f9e101a96ffa7c9dfb4fbbbe jdk-9+128 -e8373543a3f0f60589b7d72b1f9b172721124caf jdk-9+129 -e613affb88d178dc7c589f1679db113d589bddb4 jdk-9+130 -4d2a15091124488080d65848b704e25599b2aaeb jdk-9+131 -2e83d21d78cd9c1d52e6cd2599e9c8aa36ea1f52 jdk-9+132 -e17429a7e843c4a4ed3651458d0f950970edcbcc jdk-9+133 -a71210c0d9800eb6925b61ecd6198abd554f90ee jdk-9+134 -e384420383a5b79fa0012ebcb25d8f83cff7f777 jdk-9+135 -1b4b5d01aa11edf24b6fadbe3d2f3e411e3b02cd jdk-9+136 -9cb87c88ed851c0575b8ead753ea238ed5b544e9 jdk-9+137 -d273dfe9a126d3bffe92072547fef2cd1361b0eb jdk-9+138 -65477538bec32963dc41153d89c4417eb46c45fc jdk-9+139 -0875007901f7d364a08220b052f0c81003e9c8c5 jdk-9+140 -9aadd2163b568d76f8969ad2fb404a63733da359 jdk-9+141 -df0e03e3ca0ed1307793017dfc1a054c8726131c jdk-9+142 -d62173b931bf5b6bffc6e80a9060bb2e8b8efc75 jdk-9+143 -31f5023200d42185b70c4c00ba5672391e4642d0 jdk-9+144 -3ee4e7827413fa5c5c4fca58597b0ad89e921bfb jdk-9+145 -581331db696a62dd411926ba7fd437252252a71d jdk-9+146 -f4e854a77aa38749bd90f722b06974a56e7233d5 jdk-9+147 -5c71ea43933b6c7e8a85eb1a4eb2213011b95d82 jdk-9+148 -cf139f925da04c8bd7efd33270a0315d72b338d3 jdk-9+149 -17469f16fbb406ec9f0dd262ce776ab6efbc38f1 jdk-9+150 -37b95df0042ae0687324e1f7dc4a2519e230e704 jdk-9+151 -ab2c8b03c3284fcbdd157551a66f807e3a182d9b jdk-9+152 -d7034ff7f8e257e81c9f95c7785dd4eaaa3c2afc jdk-9+153 -8c70d170e62c0c58b5bc3ba666bd140399b98c9c jdk-10+0 -45b751afd11e6c05991cf4913c5a0ac3304fcc4e jdk-9+154 -f4aff695ffe05cfdb69d8af25a4ddc6a029754ea jdk-9+155 -06bce0388880b5ff8e040e4a9d72a3ea11dac321 jdk-9+156 -74116beae88a8f17a80301aa6c83865c82f10ece jdk-10+1 -4a79ad46e578112fce68f1af9dd931025cc235cb jdk-10+2 -d1cab6c7e608479be4ebfad48a25b0ed48600f62 jdk-10+3 -02253db2ace1422f576f58502fc7831ead77424b jdk-10+4 -f113ce12fe24fbd24acf02711372d9f1e1c12426 jdk-10+5 -1407b19a2ddf6baae162f5a1a5b96af473f4d7d1 jdk-10+6 -30e75693ae99fd8e47fd2f5116527aff1b59aff9 jdk-10+7 -c42dc7b58b4d4301ea676a76326fd9bbd403d595 jdk-10+8 -aa5b01f5e5620438fd39efdb2e2f6365a2c7d898 jdk-10+9 -b0f2b8ff25a2209b2c807785d75f20e5086bbfc2 jdk-10+10 -036dbf8b381798e5d31065109714d04d97bf98a4 jdk-10+11 -e6d70017f5b9adbb2ec82d826973d0251800a3c3 jdk-10+12 -9927a9f16738e240ab7014f0118f41e314ef8f99 jdk-10+13 -9ef5029b247b4d940080417a287440bbdbab995b jdk-10+14 -878e216039322cb3f0ecbd0944642a2b4e2593f3 jdk-10+15 -4bbea012e5676e8025ade2bcfab4d6581e6e9f4b jdk-10+16 -7db699468b4f84abbcc01647e5a964409737411a jdk-10+17 -3739654290616e533fc6f51bf9ad69ed47a6abba jdk-10+18 -14df107500cc3b8ab238c3e4ad2c74e12bfe6067 jdk-10+19 -4586bc5d28d13d3147b993e6237eaf29a7073bbb jdk-10+20 -a85884d55ce32799f5c7382b7ea4839052b362a2 jdk-10+21 -e5357aa85dadacc6562175ff74714fecfb4470cf jdk-10+22 -22850b3a55240253841b9a425ad60a7fcdb22d47 jdk-10+23 -3b201865d5c1f244f555cad58da599c9261286d8 jdk-10+24 -8eb5e3ccee560c28ac9b1df2670adac2b3d36fad jdk-10+25 -1129253d3bc728a2963ba411ab9dd1adf358fb6b jdk-10+26 -b87d7b5d5dedc1185e5929470f945b7378cdb3ad jdk-10+27 -92f08900cb3c0d694e5c529a676c1c9e5909193f jdk-10+28 -a6e591e12f122768f675428e1e5a838fd0e9c7ec jdk-10+29 -8fee80b92e65149f7414250fd5e34b6f35d417b4 jdk-10+30 -e6278add9ff28fab70fe1cc4c1d65f7363dc9445 jdk-10+31 -a2008587c13fa05fa2dbfcb09fe987576fbedfd1 jdk-10+32 -bbd692ad4fa300ecca7939ffbe3b1d5e52a28cc6 jdk-10+33 -89deac44e51517841491ba86ff44aa82a5ca96b3 jdk-10+34 -d8c634b016c628622c9abbdc6bf50509e5dedbec jdk-10+35 -0ee20aad71c4f33c426372b4c8bcc1235ce2ec08 jdk-11+0 -959f2f7cbaa6d2ee45d50029744efb219721576c jdk-10+36 -4f830b447edf04fb4a52151a5ad44d9bb60723cd jdk-10+37 -e569e83139fdfbecfeb3cd9014d560917787f158 jdk-10+38 -5b834ec962366e00d4445352a999a3ac14e26f64 jdk-10+39 -860326263d1f6a83996d7da0f4c66806ae4aa1eb jdk-10+40 -3eae36c6baa5f916a3024cf1513e22357e00185d jdk-10+41 -4b62b815b4f49970b91a952929cf50115c263cb3 jdk-10+42 -107413b070b92c88bde6230ceb4a19b579781068 jdk-10+43 -dfa46cfe56346884a61efdc30dc50f7505d66761 jdk-11+1 -03ae177c26b016353e5ea1cab6ffd051dfa086ca jdk-11+2 -663f20fc51091bd7f95d18448850ba091207b7bd jdk-10+44 -4f96cf952e71cb8a127334494faf28880c26181b jdk-10+45 -1fd4d6068f54561cfc67d54fc9ca84af7212c4f8 jdk-11+3 -e59941f7247d451fa7df9eaef3fce0f492f8420c jdk-11+4 -d5c43e9f08fb9a7c74aae0d48daf17f2ad2afaef jdk-11+5 -3acb379b86725c47e7f33358cb22efa8752ae532 jdk-11+6 -f7363de371c9a1f668bd0a01b7df3d1ddb9cc58b jdk-11+7 -755e1b55a4dff510f9639cdb5c5e82549a7e09b3 jdk-11+8 -0c3e252cea44f06aef570ef464950ab97c669970 jdk-11+9 -6fa770f9f8ab296e1ce255ec17ccf6d4e1051886 jdk-10+46 -69d7398038c54774d9395b6810e0cca335edc02c jdk-11+10 -e1e60f75cd39312a7f59d2a4f91d624e5aecc95e jdk-11+11 -3ab6ba9f94a9045a526d645af26c933235371d6f jdk-11+12 -758deedaae8406ae60147486107a54e9864aa7b0 jdk-11+13 -3595bd343b65f8c37818ebe6a4c343ddeb1a5f88 jdk-11+14 -a11c1cb542bbd1671d25b85efe7d09b983c48525 jdk-11+15 -02934b0d661b82b7fe1052a04998d2091352e08d jdk-11+16 -64e4b1686141e57a681936a8283983341484676e jdk-11+17 -e1b3def126240d5433902f3cb0e91a4c27f6db50 jdk-11+18 -36ca515343e00b021dcfc902e986d26ec994a2e5 jdk-11+19 -95aad0c785e497f1bade3955c4e4a677b629fa9d jdk-12+0 -9816d7cc655e53ba081f938b656e31971b8f097a jdk-11+20 -14708e1acdc3974f4539027cbbcfa6d69f83cf51 jdk-11+21 -00b16d0457e43d23f6ca5ade6b243edce62750a0 jdk-12+1 -9937ef7499dcd7673714517fd5e450410c14ba4e jdk-11+22 -69b438908512d3dfef5852c6a843a5778333a309 jdk-12+2 -1edcf36fe15f79d6228d1a63eb680878e2386480 jdk-11+23 -990db216e7199b2ba9989d8fa20b657e0ca7d969 jdk-12+3 -ea900a7dc7d77dee30865c60eabd87fc24b1037c jdk-11+24 -499b873761d8e8a1cc4aa649daf04cbe98cbce77 jdk-12+4 -331888ea4a788df801b1edf8836646cd25fc758b jdk-11+25 -f8696e0ab9b795030429fc3374ec03e378fd9ed7 jdk-12+5 -945ba9278a272a5477ffb1b3ea1b04174fed8036 jdk-11+26 -7939b3c4e4088bf4f70ec5bbd8030393b653372f jdk-12+6 -9d7d74c6f2cbe522e39fa22dc557fdd3f79b32ad jdk-11+27 -ef57958c7c511162da8d9a75f0b977f0f7ac464e jdk-12+7 -76072a077ee1d815152d45d1692c4b36c53c5c49 jdk-11+28 -492b366f8e5784cc4927c2c98f9b8a3f16c067eb jdk-12+8 -31b159f30fb281016c5f0c103552809aeda84063 jdk-12+9 -8f594f75e0547d4ca16649cb3501659e3155e81b jdk-12+10 -f0f5d23449d31f1b3580c8a73313918cafeaefd7 jdk-12+11 -15094d12a632f452a2064318a4e416d0c7a9ce0c jdk-12+12 -511a9946f83e3e3c7b9dbe1840367063fb39b4e1 jdk-12+13 -8897e41b327c0a5601c6ba2bba5d07f15a3ffc91 jdk-12+14 -8897e41b327c0a5601c6ba2bba5d07f15a3ffc91 jdk-12+14 -6f04692c7d5137ee34a6bd94c0c8a6c9219cb127 jdk-12+14 -f8626bcc169813a4b2a15880386b952719d1d6d1 jdk-12+15 -199658d1ef860cdc17055b4fd3e94b057f292fe9 jdk-12+16 -eefa65e142af305923d2adcd596fab9c639723a1 jdk-12+17 -e38473506688e0995e701fc7f77d5a91b438ef93 jdk-12+18 -dc1f9dec2018a37fedba47d8a2aedef99faaec64 jdk-12+19 -40098289d5804c3b5e7074bc75501a81e70d9b0d jdk-12+20 -f8fb0c86f2b3d24294d39c5685a628e1beb14ba7 jdk-12+21 -732bec44c89e8b93a38296bf690f97b7230c5b6d jdk-12+22 -eef755718cb24813031a842bbfc716a6cea18e9a jdk-12+23 -cc4098b3bc10d1c390384289025fea7b0d4b9e93 jdk-13+0 -7d4397b43fa305806160785a4c7210600d59581a jdk-12+24 -11033c4ada542f9c9a873314b6ecf60af19e8256 jdk-13+1 -7496df94b3b79f3da53925d2d137317715f11d97 jdk-12+25 -50677f43ac3df9a8684222b8893543c60f3aa0bd jdk-13+2 -de9fd809bb475401aad188eab2264226788aad81 jdk-12+26 -642346a11059b9f283110dc301a24ed43b76a94e jdk-13+3 -f15d443f97318e9b40e6f451e327ff69ed4ec361 jdk-12+27 -a47b8125b7cc9ef59619745c163975fe935b57ed jdk-13+4 -659b004b6a1bd8c31e766cbdf328d8f8473fd4d7 jdk-12+28 -e3ed960609927b5fdfd0a797159835cd83a81a31 jdk-13+5 -44f41693631f9b5ac78ff4d2bfabd6734fe46df2 jdk-12+29 -b5f05fe4a6f8b3996a000c20078b356d991ca8ec jdk-13+6 -6c377af36a5c4203f16aed8a5e4c2ecc08fcd8bd jdk-12+30 -021917019cda1c0c5853255322274f37693a2431 jdk-13+7 -b5f7bb57de2f797be34f6c75d45c3245ad37ab97 jdk-12+31 -a535ba736cabc6886acdff36de3a096c46e5ddc5 jdk-13+8 -4ce47bc1fb92cf94c6e3d1f49d582f02dcb851ab jdk-12+32 -c081f3ea6b9300265a4a34e38f970b1e3ddaae9f jdk-13+9 -b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12+33 -8e069f7b4fabfe05d9f500783e6d56cb0196d25c jdk-13+10 -21ea4076a275a0f498afa517e9ee1b94a9cf0255 jdk-13+11 -1d7aec80147a6d92b101a76aef92f3ddc88bedf4 jdk-13+12 -b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12-ga -83cace4142c8563b6a921787db02388e1bc48d01 jdk-13+13 -46cf212cdccaf4fb064d913b12004007d3322b67 jdk-13+14 -f855ec13aa2501ae184c8b3e0626a8cec9966116 jdk-13+15 -9d0ae9508d5337b0dc7cc4684be42888c4023755 jdk-13+16 -93b702d2a0cb9e32160208f6700aede1f8492773 jdk-13+17 -bebb82ef3434a25f8142edafec20165f07ac562d jdk-13+18 -a43d6467317d8f1e160f67aadec37919c9d64443 jdk-13+19 -6ccc7cd7931e34129f6b7e04988fc9a63958dde0 jdk-13+20 -f2f11d7f7f4e7128f8aba6ffa576cfa76fbf7d1a jdk-13+21 -181986c5476468bc2dd4532af49599003ee8af37 jdk-13+22 -b034d2dee5fc93d42a81b65e58ce3f91e42586ff jdk-13+23 -7e2238451585029680f126ccbb46d01f2ff5607f jdk-13+24 -22b3b7983adab54e318f75aeb94471f7a4429c1e jdk-14+0 -22b3b7983adab54e318f75aeb94471f7a4429c1e jdk-13+25 -2f4e214781a1d597ed36bf5a36f20928c6c82996 jdk-14+1 -0692b67f54621991ba7afbf23e55b788f3555e69 jdk-13+26 -43627549a488b7d0b4df8fad436e36233df89877 jdk-14+2 -b7f68ddec66f996ae3aad03291d129ca9f02482d jdk-13+27 -e64383344f144217c36196c3c8a2df8f588a2af3 jdk-14+3 -1e95931e7d8fa7e3899340a9c7cb28dbea50c10c jdk-13+28 -19d0b382f0869f72d4381b54fa129f1c74b6e766 jdk-14+4 -3081f39a3d30d63b112098386ac2bb027c2b7223 jdk-13+29 -0f1e29c77e50c7da11d83df410026392c4d1a28c jdk-14+5 -2e63fb0a885fa908a97bbb0da8d7c3de11536aca jdk-13+30 -443f7359b34d60e7821216ffc60f88b6ffe0ccdd jdk-14+6 -6a159c6c23ccd0029140ab91653442e412305ce5 jdk-13+31 -28ab01c067551ef158abaef08e154e1051ca0893 jdk-14+7 -929f37a9c35d530d4e866f6e832001aeb4cfb371 jdk-13+32 -c0023e364b6f130cb1e93747b796d8718d544db1 jdk-14+8 -9c250a7600e12bdb1e611835250af3204d4aa152 jdk-13+33 -18f189e69b29f8215a3500b875127ed4fb2d977a jdk-14+9 -ececb6dae777e622abda42c705fd984a42f46b5a jdk-14+10 -bf4c808a4488025a415f867e54c8b088417e08a0 jdk-14+11 -8570f22b9b6ac6bec673899b582150865696e425 jdk-14+12 -fbbe6672ae15deaf350a9e935290a36f57ba9c25 jdk-14+13 -cddef3bde924f3ff4f17f3d369280cf69d0450e5 jdk-14+14 -9c250a7600e12bdb1e611835250af3204d4aa152 jdk-13-ga -778fc2dcbdaa8981e07e929a2cacef979c72261e jdk-14+15 -d29f0181ba424a95d881aba5eabf2e393abcc70f jdk-14+16 -5c83830390baafb76a1fbe33443c57620bd45fb9 jdk-14+17 -e84d8379815ba0d3e50fb096d28c25894cb50b8c jdk-14+18 -9b67dd88a9313e982ec5f710a7747161bc8f0c23 jdk-14+19 -54ffb15c48399dd59922ee22bb592d815307e77c jdk-14+20 -c16ac7a2eba4e73cb4f7ee9294dd647860eebff0 jdk-14+21 -83810b7d12e7ff761ad3dd91f323a22dad96f108 jdk-14+22 -15936b142f86731afa4b1a2c0fe4a01e806c4944 jdk-14+23 -438337c846fb071900ddb6922bddf8b3e895a514 jdk-14+24 -17d242844fc9e7d18b3eac97426490a9c246119e jdk-14+25 -288777cf0702914e5266bc1e5d380eed9032ca41 jdk-14+26 -2c724dba4c3cf9516b2152e151c9aea66b21b30b jdk-15+0 -91a3f092682fc715d991a87eb6ec6f28886d2035 jdk-14+27 -63e17cf29bed191ea21020b4648c9cdf893f80f5 jdk-15+1 -2069b4bfd23b56b6fc659fba8b75aaaa23debbe0 jdk-14+28 -f33197adda9ad82fdef46ac0f7dc0126204f35b2 jdk-15+2 -563fa900fa17c290ae516c7a3a69e8c069dde304 jdk-14+29 -d05fcdf25717d85e80a3a39a6b719458b22be5fe jdk-15+3 -d54ce919da90dab361995bb4d87be9851f00537a jdk-14+30 -bb0a7975b31ded63d594ee8dbfc4d4ead587f79b jdk-15+4 -decd3d2953b640f1043ee76953ff89238bff92e8 jdk-14+31 -b97c1773ccafae4a8c16cc6aedb10b2a4f9a07ed jdk-15+5 -2776da28515e087cc8849acf1e131a65ea7e77b6 jdk-14+32 -ef7d53b4fccd4a0501b17d974e84f37aa99fa813 jdk-15+6 -f728b6c7f4910d6bd6070cb4dde8393f4ba95113 jdk-14+33 -e2bc57500c1b785837982f7ce8af6751387ed73b jdk-15+7 -a96bc204e3b31ddbf909b20088964112f052927e jdk-14+34 -c7d4f2849dbfb755fc5860b362a4044ea0c9e082 jdk-15+8 -4a87bb7ebfd7f6a25ec59a5982fe3607242777f8 jdk-14+35 -62b5bfef8d618e08e6f3a56cf1fb0e67e89e9cc2 jdk-15+9 -bc54620a3848c26cff9766e5e2a6e5ddab98ed18 jdk-14+36 -1bee69801aeea1a34261c93f35bc9de072a98704 jdk-15+10 -b2dd4028a6de4e40dda8b76109e4b5c6b294f980 jdk-15+11 -2ec0ff3042630ddbd3587e340fe0dd40391cb6c4 jdk-15+12 -1c06a8ee8acad4d93c782626a233693a73de0add jdk-15+13 -1d6ceb13e142665ea833fca01c8c8598e0ddd211 jdk-15+14 -bc54620a3848c26cff9766e5e2a6e5ddab98ed18 jdk-14-ga -82b7c62cf4cc56828a8fb724f57087967232a2a7 jdk-15+15 -5c7ec21f5d13f6eb5cd32288c69b8be2f9cac256 jdk-15+16 -dd5198db2e5b1ebcafe065d987c03ba9fcb50fc3 jdk-15+17 -44aef192b488a48cce12422394691a6b1d16b98e jdk-15+18 -7cc27caabe6e342151e8baf549beb07a9c755ec2 jdk-15+19 -46bca5e5e6fb26efd07245d26fe96a9c3260f51e jdk-15+20 -12b55fad80f30d24b1f8fdb3b947ea6465ef9518 jdk-15+21 -7223c6d610343fd8323af9d07d501e01fa1a7696 jdk-15+22 -f143729ca00ec14a98ea5c7f73acba88da97746e jdk-15+23 -497fd9f9129c4928fd5a876dd55e0daf6298b511 jdk-15+24 -90b266a84c06f1b3dc0ed8767856793e8c1c357e jdk-15+25 -0a32396f7a690015d22ca3328ac441a358295d90 jdk-15+26 -93813843680bbe1b7efbca56c03fd137f20a2c31 jdk-16+0 -93813843680bbe1b7efbca56c03fd137f20a2c31 jdk-15+27 -4a485c89d5a08b495961835f5308a96038678aeb jdk-16+1 -06c9f89459daba98395fad726100feb44f89ba71 jdk-15+28 -bcbe7b8a77b8971bc221c0be1bd2abb6fb68c2d0 jdk-16+2 -b58fc60580550a4a587cab729d8fd87223ad6932 jdk-15+29 -76810b3a88c8c641ae3850a8dfd7c40c984aea9d jdk-16+3 -6909e4a1f25bfe9a2727026f5845fc1fc44a36aa jdk-15+30 -e2622818f0bd30e736252eba101fe7d2c27f400b jdk-16+4 -a32f58c6b8be81877411767de7ba9c4cf087c1b5 jdk-15+31 -143e258f64af490010eb7e0bacc1cfaeceff0993 jdk-16+5 -2dad000726b8d5db9f3df647fb4949d88f269dd4 jdk-15+32 -4a8fd81d64bafa523cddb45f82805536edace106 jdk-16+6 -6b65f4e7a975628df51ef755b02642075390041d jdk-15+33 -c3a4a7ea7c304cabdacdc31741eb94c51351668d jdk-16+7 -b0817631d2f4395508cb10e81c3858a94d9ae4de jdk-15+34 -0a73d6f3aab48ff6d7e61e47f0bc2d87a054f217 jdk-16+8 -fd60c3146a024037cdd9be34c645bb793995a7cc jdk-15+35 -c075a286cc7df767cce28e8057d6ec5051786490 jdk-16+9 -b01985b4f88f554f97901e53e1ba314681dd9c19 jdk-16+10 -e3f940bd3c8fcdf4ca704c6eb1ac745d155859d5 jdk-15+36 -5c18d696c7ce724ca36df13933aa53f50e12b9e0 jdk-16+11 -fc8e62b399bd93d06e8d13dc3b384c450e853dcd jdk-16+12 -fd07cdb26fc70243ef23d688b545514f4ddf1c2b jdk-16+13 -36b29df125dc88f11657ce93b4998aa9ff5f5d41 jdk-16+14 diff --git a/.jcheck/conf b/.jcheck/conf index 42c3716369ea45aef1693b447d60146073e3b9bc..58d09d2b614a8f24f7802cdd4369ac85556380a9 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,6 +1,7 @@ [general] project=jdk jbs=JDK +version=19 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff --git a/doc/building.html b/doc/building.html index 97c9b2a4bb693d81a2a523047d65fbca18088497..9cb1807345c905e42be6d1b7969d3b3b32e374d2 100644 --- a/doc/building.html +++ b/doc/building.html @@ -196,7 +196,7 @@

Windows

Windows XP is not a supported platform, but all newer Windows should be able to build the JDK.

On Windows, it is important that you pay attention to the instructions in the Special Considerations.

-

Windows is the only non-POSIX OS supported by the JDK, and as such, requires some extra care. A POSIX support layer is required to build on Windows. Currently, the only supported such layers are Cygwin and Windows Subsystem for Linux (WSL). (Msys is no longer supported due to a too old bash; msys2 would likely be possible to support in a future version but that would require effort to implement.)

+

Windows is the only non-POSIX OS supported by the JDK, and as such, requires some extra care. A POSIX support layer is required to build on Windows. Currently, the only supported such layers are Cygwin, Windows Subsystem for Linux (WSL), and MSYS2. (MSYS is no longer supported due to an outdated bash; While OpenJDK can be built with MSYS2, support for it is still experimental, so build failures and unusual errors are not uncommon.)

Internally in the build system, all paths are represented as Unix-style paths, e.g. /cygdrive/c/git/jdk/Makefile rather than C:\git\jdk\Makefile. This rule also applies to input to the build system, e.g. in arguments to configure. So, use --with-msvcr-dll=/cygdrive/c/msvcr100.dll rather than --with-msvcr-dll=c:\msvcr100.dll. For details on this conversion, see the section on Fixpath.

Cygwin

A functioning Cygwin environment is required for building the JDK on Windows. If you have a 64-bit OS, we strongly recommend using the 64-bit version of Cygwin.

@@ -298,7 +298,7 @@

It is advisable to keep an older version of Xcode for building the JDK when updating Xcode. This blog page has good suggestions on managing multiple Xcode versions. To use a specific version of Xcode, use xcode-select -s before running configure, or use --with-toolchain-path to point to the version of Xcode to use, e.g. configure --with-toolchain-path=/Applications/Xcode8.app/Contents/Developer/usr/bin

If you have recently (inadvertently) updated your OS and/or Xcode version, and the JDK can no longer be built, please see the section on Problems with the Build Environment, and Getting Help to find out if there are any recent, non-merged patches available for this update.

Microsoft Visual Studio

-

The minimum accepted version of Visual Studio is 2017. Older versions will not be accepted by configure and will not work. The maximum accepted version of Visual Studio is 2019.

+

For aarch64 machines running Windows the minimum accepted version is Visual Studio 2019 (16.8 or higher). For all other platforms the minimum accepted version of Visual Studio is 2017. Older versions will not be accepted by configure and will not work. For all platforms the maximum accepted version of Visual Studio is 2022.

If you have multiple versions of Visual Studio installed, configure will by default pick the latest. You can request a specific version to be used by setting --with-toolchain-version, e.g. --with-toolchain-version=2017.

If you have Visual Studio installed but configure fails to detect it, it may be because of spaces in path.

IBM XL C/C++

diff --git a/doc/building.md b/doc/building.md index 033f99d3f5a8bc92970864728030e6c372984b02..459dbaa4c410109f14246746a217a8a33027284b 100644 --- a/doc/building.md +++ b/doc/building.md @@ -179,10 +179,10 @@ On Windows, it is important that you pay attention to the instructions in the Windows is the only non-POSIX OS supported by the JDK, and as such, requires some extra care. A POSIX support layer is required to build on Windows. -Currently, the only supported such layers are Cygwin and Windows Subsystem for -Linux (WSL). (Msys is no longer supported due to a too old bash; msys2 would -likely be possible to support in a future version but that would require effort -to implement.) +Currently, the only supported such layers are Cygwin, Windows Subsystem for +Linux (WSL), and MSYS2. (MSYS is no longer supported due to an outdated bash; +While OpenJDK can be built with MSYS2, support for it is still experimental, so +build failures and unusual errors are not uncommon.) Internally in the build system, all paths are represented as Unix-style paths, e.g. `/cygdrive/c/git/jdk/Makefile` rather than `C:\git\jdk\Makefile`. This @@ -374,9 +374,10 @@ available for this update. ### Microsoft Visual Studio -The minimum accepted version of Visual Studio is 2017. Older versions will not -be accepted by `configure` and will not work. The maximum accepted -version of Visual Studio is 2019. +For aarch64 machines running Windows the minimum accepted version is Visual Studio 2019 +(16.8 or higher). For all other platforms the minimum accepted version of +Visual Studio is 2017. Older versions will not be accepted by `configure` and will +not work. For all platforms the maximum accepted version of Visual Studio is 2022. If you have multiple versions of Visual Studio installed, `configure` will by default pick the latest. You can request a specific version to be used by diff --git a/doc/hotspot-style.html b/doc/hotspot-style.html index fe72cbbdf80c1cca160571c8e4b9cd51e122c9f1..5e8f0e9e174a10af5c203e2c18c8ec1610d58254 100644 --- a/doc/hotspot-style.html +++ b/doc/hotspot-style.html @@ -195,7 +195,7 @@ while ( test_foo(args...) ) { // No, excess spaces around controlSimilar discussions for some other projects:

diff --git a/doc/hotspot-style.md b/doc/hotspot-style.md index 6d167cad9d6c20a2c7e6713aca40994de6da9a3f..57c0c38e2b013fab3d8d0e9e0209a6ab4ad9718f 100644 --- a/doc/hotspot-style.md +++ b/doc/hotspot-style.md @@ -409,7 +409,7 @@ Similar discussions for some other projects: * [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) — Currently (2020) targeting C++17. -* [C++11 and C++14 use in Chromium](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++11.md) — +* [C++11 and C++14 use in Chromium](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-features.md) — Categorizes features as allowed, banned, or to be discussed. * [llvm Coding Standards](https://llvm.org/docs/CodingStandards.html) — diff --git a/doc/ide.html b/doc/ide.html index 1730eb0bef5b5bb1e6d18aed43b61ee4155a5aaa..288a477e538f80f3c3f7c01cfcafa2e32b18b627 100644 --- a/doc/ide.html +++ b/doc/ide.html @@ -41,14 +41,20 @@
make vscode-project-clangd

Additional instructions for configuring the given indexer will be displayed after the workspace has been generated.

Visual Studio

-

This section is a work in progress.

-
make ide-project
+

The make system can generate a Visual Studio project for the Hotspot native source. After configuring, the project is generated using:

+
make hotspot-ide-project
+

This creates a file named jvm.vcxproj in ide\hotspot-visualstudio subfolder of the build output folder. The file can be opened in Visual Studio via File -> Open -> Project/Solution.

Compilation Database

The make system can generate generic native code indexing support in the form of a Compilation Database that can be used by many different IDEs and source code indexers.

make compile-commands

It's also possible to generate the Compilation Database for the HotSpot source code only, which is a bit faster as it includes less information.

make compile-commands-hotspot

IDE support for Java code

-

This section is a work in progress.

+

IntelliJ IDEA

+

The JDK project has a script that can be used for indexing the project with IntelliJ. After configuring and building the JDK, an IntelliJ workspace can be generated by running the following command in the top-level folder of the cloned repository:

+
bash bin/idea.sh
+

To use it, choose File -> Open... in IntelliJ and select the folder where you ran the above script.

+

Next, configure the project SDK in IntelliJ. Open File -> Project Structure -> Project and select build/<config>/images/jdk as the SDK to use.

+

In order to run the tests from the IDE, you can use the JTReg plugin. Instructions for building and using the plugin can be found here.

diff --git a/doc/ide.md b/doc/ide.md index 4a692efd22f03f9dd6f14eec95387002598c4d19..f0a419c948ba98683f00d43c890f07375a2debf9 100644 --- a/doc/ide.md +++ b/doc/ide.md @@ -45,12 +45,17 @@ after the workspace has been generated. #### Visual Studio -This section is a work in progress. +The make system can generate a Visual Studio project for the Hotspot +native source. After configuring, the project is generated using: ```shell -make ide-project +make hotspot-ide-project ``` +This creates a file named `jvm.vcxproj` in `ide\hotspot-visualstudio` +subfolder of the build output folder. The file can be opened in Visual Studio +via `File -> Open -> Project/Solution`. + #### Compilation Database The make system can generate generic native code indexing support in the form of @@ -70,4 +75,24 @@ make compile-commands-hotspot ### IDE support for Java code -This section is a work in progress. \ No newline at end of file +#### IntelliJ IDEA + +The JDK project has a script that can be used for indexing the project +with IntelliJ. After configuring and building the JDK, an IntelliJ workspace +can be generated by running the following command in the top-level folder +of the cloned repository: + +```shell +bash bin/idea.sh +``` + +To use it, choose `File -> Open...` in IntelliJ and select the folder where +you ran the above script. + +Next, configure the project SDK in IntelliJ. Open +`File -> Project Structure -> Project` and select `build//images/jdk` +as the SDK to use. + +In order to run the tests from the IDE, you can use the JTReg plugin. +Instructions for building and using the plugin can be found +[here](https://github.com/openjdk/jtreg/tree/master/plugins/idea). diff --git a/doc/testing.html b/doc/testing.html index 1146400df805f5d5cc84536ea96b8b484c7dcf09..213e23664c37c9afadfd3be808e8d5388a9d9a57 100644 --- a/doc/testing.html +++ b/doc/testing.html @@ -193,7 +193,9 @@ TEST FAILURE

AOT_MODULES

Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value %20).

RETRY_COUNT

-

Retry failed tests up to a set number of times. Defaults to 0.

+

Retry failed tests up to a set number of times, until they pass. This allows to pass the tests with intermittent failures. Defaults to 0.

+

REPEAT_COUNT

+

Repeat the tests up to a set number of times, stopping at first failure. This helps to reproduce intermittent test failures. Defaults to 0.

Gtest keywords

REPEAT

The number of times to repeat the tests (--gtest_repeat).

diff --git a/doc/testing.md b/doc/testing.md index 5dde4d11804d67a4450c7c2a1beb9227ccb8a221..3ab7079ea07f7a681354cafea7a593a67dbe0e06 100644 --- a/doc/testing.md +++ b/doc/testing.md @@ -419,7 +419,15 @@ modules. If multiple modules are specified, they should be separated by space #### RETRY_COUNT -Retry failed tests up to a set number of times. Defaults to 0. +Retry failed tests up to a set number of times, until they pass. +This allows to pass the tests with intermittent failures. +Defaults to 0. + +#### REPEAT_COUNT + +Repeat the tests up to a set number of times, stopping at first failure. +This helps to reproduce intermittent test failures. +Defaults to 0. ### Gtest keywords diff --git a/make/CompileInterimLangtools.gmk b/make/CompileInterimLangtools.gmk index a6a42f6a9cd3c72e9b66c443d45ee27571bcde80..3fff64db1f81a4c26fe4988f58f2e0bf6acfc421 100644 --- a/make/CompileInterimLangtools.gmk +++ b/make/CompileInterimLangtools.gmk @@ -71,7 +71,7 @@ define SetupInterimModule SRC := $(BUILDTOOLS_OUTPUTDIR)/gensrc/$1.interim \ $$(wildcard $(SUPPORT_OUTPUTDIR)/gensrc/$1) \ $(TOPDIR)/src/$1/share/classes, \ - EXCLUDES := sun, \ + EXCLUDES := sun javax/tools/snippet-files, \ EXCLUDE_FILES := $(TOPDIR)/src/$1/share/classes/module-info.java \ Standard.java, \ EXTRA_FILES := $(BUILDTOOLS_OUTPUTDIR)/gensrc/$1.interim/module-info.java, \ diff --git a/make/CreateJmods.gmk b/make/CreateJmods.gmk index d9e5f415fe787c5d0b7721464f15a339b6d15ead..ec1e377bc078428fcb0544715cb1cbde27474e0e 100644 --- a/make/CreateJmods.gmk +++ b/make/CreateJmods.gmk @@ -226,6 +226,13 @@ else JMOD_FLAGS += --exclude '**{_the.*,_*.marker*,*.diz,*.debuginfo,*.dSYM/**,*.dSYM}' endif +# For reproducible builds specify the jmod --date using SOURCE_DATE in ISO-8601 +ifeq ($(ENABLE_REPRODUCIBLE_BUILD), true) + JMOD_SOURCE_DATE := --date $(SOURCE_DATE_ISO_8601) +else + JMOD_SOURCE_DATE := +endif + # Create jmods in the support dir and then move them into place to keep the # module path in $(IMAGES_OUTPUTDIR)/jmods valid at all times. $(eval $(call SetupExecute, create_$(JMOD_FILE), \ @@ -237,6 +244,7 @@ $(eval $(call SetupExecute, create_$(JMOD_FILE), \ COMMAND := $(JMOD) create --module-version $(VERSION_SHORT) \ --target-platform '$(OPENJDK_MODULE_TARGET_PLATFORM)' \ --module-path $(JMODS_DIR) $(JMOD_FLAGS) \ + $(JMOD_SOURCE_DATE) \ $(JMODS_SUPPORT_DIR)/$(JMOD_FILE), \ POST_COMMAND := $(MV) $(JMODS_SUPPORT_DIR)/$(JMOD_FILE) $(JMODS_DIR)/$(JMOD_FILE), \ )) diff --git a/make/InitSupport.gmk b/make/InitSupport.gmk index 8ee2e9098babc0e49c06cf8e6584344e5a2ba0bf..d2291c50f2161c41ebd5681cecebc4c9b2a11471 100644 --- a/make/InitSupport.gmk +++ b/make/InitSupport.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -313,6 +313,15 @@ else # $(HAS_SPEC)=true SOURCE_DATE := $$(shell $$(DATE) +"%s") endif export SOURCE_DATE_EPOCH := $$(SOURCE_DATE) + ifeq ($$(IS_GNU_DATE), yes) + export SOURCE_DATE_ISO_8601 := $$(shell $$(DATE) --utc \ + --date="@$$(SOURCE_DATE_EPOCH)" \ + +"%Y-%m-%dT%H:%M:%SZ" 2> /dev/null) + else + export SOURCE_DATE_ISO_8601 := $$(shell $$(DATE) -u \ + -j -f "%s" "$$(SOURCE_DATE_EPOCH)" \ + +"%Y-%m-%dT%H:%M:%SZ" 2> /dev/null) + endif endef # Parse COMPARE_BUILD into COMPARE_BUILD_* diff --git a/make/RunTests.gmk b/make/RunTests.gmk index a2c8ea8101eac3fbdca236ec0a3f087acae94cc0..81540266ec0c68d8fd3f416dcc5a5fe9480cbf28 100644 --- a/make/RunTests.gmk +++ b/make/RunTests.gmk @@ -200,7 +200,7 @@ $(eval $(call SetTestOpt,FAILURE_HANDLER_TIMEOUT,JTREG)) $(eval $(call ParseKeywordVariable, JTREG, \ SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR FAILURE_HANDLER_TIMEOUT \ TEST_MODE ASSERT VERBOSE RETAIN MAX_MEM RUN_PROBLEM_LISTS \ - RETRY_COUNT MAX_OUTPUT $(CUSTOM_JTREG_SINGLE_KEYWORDS), \ + RETRY_COUNT REPEAT_COUNT MAX_OUTPUT $(CUSTOM_JTREG_SINGLE_KEYWORDS), \ STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS KEYWORDS \ EXTRA_PROBLEM_LISTS LAUNCHER_OPTIONS \ $(CUSTOM_JTREG_STRING_KEYWORDS), \ @@ -745,6 +745,15 @@ define SetupRunJtregTestBody JTREG_RETAIN ?= fail,error JTREG_RUN_PROBLEM_LISTS ?= false JTREG_RETRY_COUNT ?= 0 + JTREG_REPEAT_COUNT ?= 0 + + ifneq ($$(JTREG_RETRY_COUNT), 0) + ifneq ($$(JTREG_REPEAT_COUNT), 0) + $$(info Error: Cannot use both JTREG_RETRY_COUNT and JTREG_REPEAT_COUNT together.) + $$(info Please choose one or the other.) + $$(error Cannot continue) + endif + endif ifneq ($$(JTREG_LAUNCHER_OPTIONS), ) $1_JTREG_LAUNCHER_OPTIONS += $$(JTREG_LAUNCHER_OPTIONS) @@ -869,6 +878,18 @@ define SetupRunJtregTestBody done endif + ifneq ($$(JTREG_REPEAT_COUNT), 0) + $1_COMMAND_LINE := \ + for i in {1..$$(JTREG_REPEAT_COUNT)}; do \ + $$(PRINTF) "\nRepeating Jtreg run: $$$$i out of $$(JTREG_REPEAT_COUNT)\n"; \ + $$($1_COMMAND_LINE); \ + if [ "`$$(CAT) $$($1_EXITCODE)`" != "0" ]; then \ + $$(PRINTF) "\nFailures detected, no more repeats.\n"; \ + break; \ + fi; \ + done + endif + run-test-$1: pre-run-test clean-workdir-$1 $$(call LogWarn) $$(call LogWarn, Running test '$$($1_TEST)') diff --git a/make/autoconf/basic.m4 b/make/autoconf/basic.m4 index e7fdab53050710b5ae499bab9fed5b720e6d62de..65558e83c7209feefbce5914b468a897044c3137 100644 --- a/make/autoconf/basic.m4 +++ b/make/autoconf/basic.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -438,7 +438,9 @@ AC_DEFUN([BASIC_CHECK_DIR_ON_LOCAL_DISK], AC_DEFUN_ONCE([BASIC_CHECK_SRC_PERMS], [ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - file_to_test="$TOPDIR/LICENSE" + # The choice of file here is somewhat arbitrary, it just needs to be there + # in the source tree when configure runs + file_to_test="$TOPDIR/Makefile" if test `$STAT -c '%a' "$file_to_test"` -lt 400; then AC_MSG_ERROR([Bad file permissions on src files. This is usually caused by cloning the repositories with a non cygwin hg in a directory not created in cygwin.]) fi diff --git a/make/autoconf/basic_tools.m4 b/make/autoconf/basic_tools.m4 index 06dd87dce79d6dab10294ad1b1c8388d944dca79..9ce90303d452d5f9705d9e195b0f5e6d59fff808 100644 --- a/make/autoconf/basic_tools.m4 +++ b/make/autoconf/basic_tools.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -356,13 +356,17 @@ AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS], fi AC_SUBST(IS_GNU_TIME) - # Check if it's GNU date - check_date=`$DATE --version 2>&1 | $GREP GNU` + # Check if it's a GNU date compatible version + AC_MSG_CHECKING([if date is a GNU compatible version]) + check_date=`$DATE --version 2>&1 | $GREP "GNU\|BusyBox"` if test "x$check_date" != x; then + AC_MSG_RESULT([yes]) IS_GNU_DATE=yes else + AC_MSG_RESULT([no]) IS_GNU_DATE=no fi + AC_SUBST(IS_GNU_DATE) if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then UTIL_REQUIRE_PROGS(DSYMUTIL, dsymutil) diff --git a/make/autoconf/boot-jdk.m4 b/make/autoconf/boot-jdk.m4 index 9c0f9018bfcc10e4b47e96f17edf39edcc284dd6..7b82cdb2543ab918693bc7b6c4496432e537f71f 100644 --- a/make/autoconf/boot-jdk.m4 +++ b/make/autoconf/boot-jdk.m4 @@ -379,6 +379,16 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK], # Finally, set some other options... + # Determine if the boot jdk jar supports the --date option + if $JAR --help 2>&1 | $GREP -q "\-\-date=TIMESTAMP"; then + BOOT_JDK_JAR_SUPPORTS_DATE=true + else + BOOT_JDK_JAR_SUPPORTS_DATE=false + fi + AC_MSG_CHECKING([if Boot JDK jar supports --date=TIMESTAMP]) + AC_MSG_RESULT([$BOOT_JDK_JAR_SUPPORTS_DATE]) + AC_SUBST(BOOT_JDK_JAR_SUPPORTS_DATE) + # When compiling code to be executed by the Boot JDK, force compatibility with the # oldest supported bootjdk. OLDEST_BOOT_JDK=`$ECHO $DEFAULT_ACCEPTABLE_BOOT_VERSIONS \ diff --git a/make/autoconf/flags.m4 b/make/autoconf/flags.m4 index 2171ca10ba238cea1e8a8610048348754513309d..0f05c9edac4052a0f1cb49e6ef5e11f958153544 100644 --- a/make/autoconf/flags.m4 +++ b/make/autoconf/flags.m4 @@ -215,8 +215,21 @@ AC_DEFUN([FLAGS_SETUP_SYSROOT_FLAGS], $1SYSROOT_CFLAGS="--sysroot=[$]$1SYSROOT" $1SYSROOT_LDFLAGS="--sysroot=[$]$1SYSROOT" elif test "x$TOOLCHAIN_TYPE" = xclang; then - $1SYSROOT_CFLAGS="-isysroot [$]$1SYSROOT" - $1SYSROOT_LDFLAGS="-isysroot [$]$1SYSROOT" + if test "x$OPENJDK_TARGET_OS" = "xlinux"; then + # -isysroot has no effect on linux + # https://bugs.llvm.org/show_bug.cgi?id=11503 + $1SYSROOT_CFLAGS="--sysroot=[$]$1SYSROOT" + $1SYSROOT_LDFLAGS="--sysroot=[$]$1SYSROOT" + if test -d "$DEVKIT_TOOLCHAIN_PATH"; then + # In devkits, gcc is not located in the sysroot. + # use --gcc-toolchain to let clang find the gcc installation. + $1SYSROOT_CFLAGS="[$]$1SYSROOT_CFLAGS --gcc-toolchain=$DEVKIT_TOOLCHAIN_PATH/.." + $1SYSROOT_LDFLAGS="[$]$1SYSROOT_LDFLAGS --gcc-toolchain=$DEVKIT_TOOLCHAIN_PATH/.." + fi + else + $1SYSROOT_CFLAGS="-isysroot [$]$1SYSROOT" + $1SYSROOT_LDFLAGS="-isysroot [$]$1SYSROOT" + fi fi fi diff --git a/make/autoconf/help.m4 b/make/autoconf/help.m4 index f36aa2819dfcc943e80509ec32113bf14eb7908a..09e82e36c94cd3ba3e1391e3b3703ca3cacb445a 100644 --- a/make/autoconf/help.m4 +++ b/make/autoconf/help.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ AC_DEFUN_ONCE([HELP_SETUP_DEPENDENCY_HELP], [ - UTIL_LOOKUP_PROGS(PKGHANDLER, zypper apt-get yum brew port pkgutil pkgadd pacman) + UTIL_LOOKUP_PROGS(PKGHANDLER, zypper apt-get yum brew port pkgutil pkgadd pacman apk) ]) AC_DEFUN([HELP_MSG_MISSING_DEPENDENCY], @@ -58,6 +58,8 @@ AC_DEFUN([HELP_MSG_MISSING_DEPENDENCY], zypper_help $MISSING_DEPENDENCY ;; *pacman) pacman_help $MISSING_DEPENDENCY ;; + *apk) + apk_help $MISSING_DEPENDENCY ;; esac if test "x$PKGHANDLER_COMMAND" != x; then @@ -192,6 +194,27 @@ pkgadd_help() { PKGHANDLER_COMMAND="" } +apk_help() { + case $1 in + devkit) + PKGHANDLER_COMMAND="sudo apk add alpine-sdk linux-headers" ;; + alsa) + PKGHANDLER_COMMAND="sudo apk add alsa-lib-dev" ;; + cups) + PKGHANDLER_COMMAND="sudo apk add cups-dev" ;; + fontconfig) + PKGHANDLER_COMMAND="sudo apk add fontconfig-dev" ;; + freetype) + PKGHANDLER_COMMAND="sudo apk add freetype-dev" ;; + harfbuzz) + PKGHANDLER_COMMAND="sudo apk add harfbuzz-dev" ;; + x11) + PKGHANDLER_COMMAND="sudo apk add libxtst-dev libxt-dev libxrender-dev libxrandr-dev" ;; + ccache) + PKGHANDLER_COMMAND="sudo apk add ccache" ;; + esac +} + # This function will check if we're called from the "configure" wrapper while # printing --help. If so, we will print out additional information that can # only be extracted within the autoconf script, and then exit. This must be diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 index cc4a44d39c96a872117af81095983daffc25f5ca..0a7145c9116a4f4d90f1e9f354c7b78aef25a7b6 100644 --- a/make/autoconf/jdk-options.m4 +++ b/make/autoconf/jdk-options.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -847,6 +847,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_HSDIS], AC_CHECK_LIB(opcodes, disassembler, [ HSDIS_LIBS="$HSDIS_LIBS -lopcodes" ], [ binutils_system_error="libopcodes not found" ]) AC_CHECK_LIB(iberty, xmalloc, [ HSDIS_LIBS="$HSDIS_LIBS -liberty" ], [ binutils_system_error="libiberty not found" ]) AC_CHECK_LIB(z, deflate, [ HSDIS_LIBS="$HSDIS_LIBS -lz" ], [ binutils_system_error="libz not found" ]) + HSDIS_CFLAGS="-DLIBARCH_$OPENJDK_TARGET_CPU_LEGACY_LIB" elif test "x$BINUTILS_DIR" != x; then if test -e $BINUTILS_DIR/bfd/libbfd.a && \ test -e $BINUTILS_DIR/opcodes/libopcodes.a && \ @@ -864,7 +865,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_HSDIS], AC_MSG_ERROR([binutils on system is supported for Linux only]) elif test "x$binutils_system_error" = x; then AC_MSG_RESULT([system]) - HSDIS_CFLAGS="-DSYSTEM_BINUTILS" + HSDIS_CFLAGS="$HSDIS_CFLAGS -DSYSTEM_BINUTILS" else AC_MSG_RESULT([invalid]) AC_MSG_ERROR([$binutils_system_error]) diff --git a/make/autoconf/jvm-features.m4 b/make/autoconf/jvm-features.m4 index 906a2857877216e7fdc80d406230105fbba07fe2..70457149edcb0fd053dd71f7d8c773ed44f12ce2 100644 --- a/make/autoconf/jvm-features.m4 +++ b/make/autoconf/jvm-features.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ m4_define(jvm_features_valid, m4_normalize( \ ifdef([custom_jvm_features_valid], custom_jvm_features_valid) \ \ cds compiler1 compiler2 dtrace epsilongc g1gc jfr jni-check \ - jvmci jvmti link-time-opt management minimal nmt opt-size parallelgc \ + jvmci jvmti link-time-opt management minimal opt-size parallelgc \ serialgc services shenandoahgc static-build vm-structs zero zgc \ )) @@ -68,7 +68,6 @@ m4_define(jvm_feature_desc_jvmti, [enable Java Virtual Machine Tool Interface (J m4_define(jvm_feature_desc_link_time_opt, [enable link time optimization]) m4_define(jvm_feature_desc_management, [enable java.lang.management API support]) m4_define(jvm_feature_desc_minimal, [support building variant 'minimal']) -m4_define(jvm_feature_desc_nmt, [include native memory tracking (NMT)]) m4_define(jvm_feature_desc_opt_size, [optimize the JVM library for size]) m4_define(jvm_feature_desc_parallelgc, [include the parallel garbage collector]) m4_define(jvm_feature_desc_serialgc, [include the serial garbage collector]) @@ -443,7 +442,7 @@ AC_DEFUN([JVM_FEATURES_PREPARE_VARIANT], JVM_FEATURES_VARIANT_FILTER="compiler2 jvmci link-time-opt opt-size" elif test "x$variant" = "xminimal"; then JVM_FEATURES_VARIANT_FILTER="cds compiler2 dtrace epsilongc g1gc \ - jfr jni-check jvmci jvmti management nmt parallelgc services \ + jfr jni-check jvmci jvmti management parallelgc services \ shenandoahgc vm-structs zgc" if test "x$OPENJDK_TARGET_CPU" = xarm ; then JVM_FEATURES_VARIANT_FILTER="$JVM_FEATURES_VARIANT_FILTER opt-size" @@ -538,10 +537,6 @@ AC_DEFUN([JVM_FEATURES_VERIFY], AC_MSG_ERROR([Specified JVM feature 'jvmti' requires feature 'services' for variant '$variant']) fi - if JVM_FEATURES_IS_ACTIVE(management) && ! JVM_FEATURES_IS_ACTIVE(nmt); then - AC_MSG_ERROR([Specified JVM feature 'management' requires feature 'nmt' for variant '$variant']) - fi - # For backwards compatibility, disable a feature "globally" if one variant # is missing the feature. if ! JVM_FEATURES_IS_ACTIVE(cds); then diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index bc13f30e5f185b2df88cbddcce1e3ca13515a119..a9ddd56bd315e27f03d645dfb1b1b10ea41e2527 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -371,6 +371,9 @@ BUILD_JDK:=@BUILD_JDK@ CREATE_BUILDJDK:=@CREATE_BUILDJDK@ EXTERNAL_BUILDJDK:=@EXTERNAL_BUILDJDK@ +# Whether the boot jdk jar supports --date=TIMESTAMP +BOOT_JDK_JAR_SUPPORTS_DATE:=@BOOT_JDK_JAR_SUPPORTS_DATE@ + # When compiling Java source to be run by the boot jdk # use these extra flags, eg -source 6 -target 6 BOOT_JDK_SOURCETARGET:=@BOOT_JDK_SOURCETARGET@ @@ -707,6 +710,7 @@ CODESIGN:=@CODESIGN@ CP:=@CP@ CUT:=@CUT@ DATE:=@DATE@ +IS_GNU_DATE:=@IS_GNU_DATE@ DIFF:=@DIFF@ DIRNAME:=@DIRNAME@ DSYMUTIL:=@DSYMUTIL@ diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4 index 9666d9a6d9dd6c0d360fc89f5a89a25d7e011e93..5280520b78bf18dad743c1d03e70deb4c7d52b9a 100644 --- a/make/autoconf/toolchain.m4 +++ b/make/autoconf/toolchain.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -234,7 +234,7 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETERMINE_TOOLCHAIN_TYPE], if test "x$OPENJDK_TARGET_OS" = xmacosx; then if test -n "$XCODEBUILD"; then # On Mac OS X, default toolchain to clang after Xcode 5 - XCODE_VERSION_OUTPUT=`"$XCODEBUILD" -version 2>&1 | $HEAD -n 1` + XCODE_VERSION_OUTPUT=`"$XCODEBUILD" -version | $HEAD -n 1` $ECHO "$XCODE_VERSION_OUTPUT" | $GREP "Xcode " > /dev/null if test $? -ne 0; then AC_MSG_NOTICE([xcodebuild output: $XCODE_VERSION_OUTPUT]) diff --git a/make/autoconf/toolchain_microsoft.m4 b/make/autoconf/toolchain_microsoft.m4 index 2600b431cfb79143b00c2cd6b24f4009e2d1942a..2e02c531da7818f41327803802b0891fec8cf02c 100644 --- a/make/autoconf/toolchain_microsoft.m4 +++ b/make/autoconf/toolchain_microsoft.m4 @@ -103,6 +103,7 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT], vc/auxiliary/build/vcvarsx86_amd64.bat vc/auxiliary/build/vcvars64.bat" elif test "x$TARGET_CPU" = xaarch64; then # for host x86-64, target aarch64 + # aarch64 requires Visual Studio 16.8 or higher VCVARSFILES="vc/auxiliary/build/vcvarsamd64_arm64.bat \ vc/auxiliary/build/vcvarsx86_arm64.bat" fi diff --git a/make/autoconf/util.m4 b/make/autoconf/util.m4 index 9ececc55e5ee8a420e7a9030e4374ed065b51a3f..877165ab3a364e62a5157856ccf554869084fbb7 100644 --- a/make/autoconf/util.m4 +++ b/make/autoconf/util.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -236,13 +236,15 @@ AC_DEFUN([UTIL_GET_MATCHING_VALUES], # $2: input date/time string AC_DEFUN([UTIL_GET_EPOCH_TIMESTAMP], [ - timestamp=$($DATE --utc --date=$2 +"%s" 2> /dev/null) - if test "x$timestamp" = x; then - # GNU date format did not work, try BSD date options - timestamp=$($DATE -j -f "%F %T" "$2" "+%s" 2> /dev/null) + if test "x$IS_GNU_DATE" = xyes; then + # GNU date + timestamp=$($DATE --utc --date=$2 +"%s" 2> /dev/null) + else + # BSD date + timestamp=$($DATE -u -j -f "%F %T" "$2" "+%s" 2> /dev/null) if test "x$timestamp" = x; then # Perhaps the time was missing - timestamp=$($DATE -j -f "%F %T" "$2 00:00:00" "+%s" 2> /dev/null) + timestamp=$($DATE -u -j -f "%F %T" "$2 00:00:00" "+%s" 2> /dev/null) # If this did not work, we give up and return the empty string fi fi diff --git a/make/common/JarArchive.gmk b/make/common/JarArchive.gmk index d2a4ec103c455c62b98cfccd10cf79e72f20a0d0..5a87e4714288ff3dc570bb9747b3af45b29023e3 100644 --- a/make/common/JarArchive.gmk +++ b/make/common/JarArchive.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -193,7 +193,7 @@ define SetupJarArchiveBody $1_UPDATE_CONTENTS=\ if [ "`$(WC) -l $$($1_BIN)/_the.$$($1_JARNAME)_contents | $(AWK) '{ print $$$$1 }'`" -gt "0" ]; then \ $(ECHO) " updating" `$(WC) -l $$($1_BIN)/_the.$$($1_JARNAME)_contents | $(AWK) '{ print $$$$1 }'` files && \ - $$($1_JAR_CMD) $$($1_JAR_UPDATE_OPTIONS) $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents; \ + $$($1_JAR_CMD) --update $$($1_JAR_OPTIONS) --file $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents; \ fi $$(NEWLINE) # The s-variants of the above macros are used when the jar is created from scratch. # NOTICE: please leave the parentheses space separated otherwise the AIX build will break! @@ -212,25 +212,27 @@ define SetupJarArchiveBody | $(SED) 's|$$(src)/|-C $$(src) |g' >> \ $$($1_BIN)/_the.$$($1_JARNAME)_contents) $$(NEWLINE) ) endif - $1_SUPDATE_CONTENTS=$$($1_JAR_CMD) $$($1_JAR_UPDATE_OPTIONS) $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents $$(NEWLINE) + $1_SUPDATE_CONTENTS=$$($1_JAR_CMD) --update $$($1_JAR_OPTIONS) --file $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents $$(NEWLINE) # Use a slightly shorter name for logging, but with enough path to identify this jar. $1_NAME:=$$(subst $$(OUTPUTDIR)/,,$$($1_JAR)) + # If reproducible build and the boot jdk jar supports --date option + # then specify the --date using SOURCE_DATE in ISO-8601 + $1_JAR_OPTIONS := + ifeq ($$(ENABLE_REPRODUCIBLE_BUILD), true) + ifeq ($$(BOOT_JDK_JAR_SUPPORTS_DATE), true) + $1_JAR_OPTIONS += --date $(SOURCE_DATE_ISO_8601) + endif + endif ifneq (,$$($1_CHECK_COMPRESS_JAR)) - $1_JAR_CREATE_OPTIONS := c0fm - $1_JAR_UPDATE_OPTIONS := u0f - ifeq ($(COMPRESS_JARS), true) - $1_JAR_CREATE_OPTIONS := cfm - $1_JAR_UPDATE_OPTIONS := uf + ifneq ($(COMPRESS_JARS), true) + $1_JAR_OPTIONS += --no-compress endif - else - $1_JAR_CREATE_OPTIONS := cfm - $1_JAR_UPDATE_OPTIONS := uf endif # Include all variables of significance in the vardeps file - $1_VARDEPS := $$($1_JAR_CMD) $$($1_JAR_CREATE_OPTIONS) $$($1_MANIFEST) \ + $1_VARDEPS := $$($1_JAR_CMD) $$($1_JAR_OPTIONS) $$($1_MANIFEST) \ $$($1_JARMAIN) $$($1_EXTRA_MANIFEST_ATTR) $$($1_ORIG_DEPS) $$($1_SRCS) \ $$($1_INCLUDES) $$($1_EXCLUDES) $$($1_EXCLUDE_FILES) $$($1_EXTRA_FILES) $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$($1_BIN)/_the.$$($1_JARNAME).vardeps) @@ -255,7 +257,7 @@ define SetupJarArchiveBody $$(if $$($1_EXTRA_MANIFEST_ATTR), \ $(PRINTF) "$$($1_EXTRA_MANIFEST_ATTR)\n" >> $$($1_MANIFEST_FILE) $$(NEWLINE)) \ $(ECHO) Creating $$($1_NAME) $$(NEWLINE) \ - $$($1_JAR_CMD) $$($1_JAR_CREATE_OPTIONS) $$@ $$($1_MANIFEST_FILE) $$(NEWLINE) \ + $$($1_JAR_CMD) --create $$($1_JAR_OPTIONS) --file $$@ --manifest $$($1_MANIFEST_FILE) $$(NEWLINE) \ $$($1_SCAPTURE_CONTENTS) \ $$($1_SCAPTURE_METAINF) \ $$($1_SUPDATE_CONTENTS) \ diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 24aeea9893df63d5dd918c5ad5eed3b6764881c8..e0041e9185130fb591ae6577c61ae9fe2bc9cc47 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -1165,19 +1165,12 @@ var getJibProfilesDependencies = function (input, common) { jmh: { organization: common.organization, ext: "tar.gz", - revision: "1.33+1.0" + revision: "1.34+1.0" }, jcov: { - // Use custom build of JCov - // See CODETOOLS-7902734 for more info. - // server: "jpg", - // product: "jcov", - // version: "3.0", - // build_number: "b07", - // file: "bundles/jcov-3_0.zip", organization: common.organization, - revision: "3.0-9-jdk-asm+1.0", + revision: "3.0-12-jdk-asm+1.0", ext: "zip", environment_name: "JCOV_HOME", }, diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 191579c4bfaa479f5d93d4cc74a31296d13eeff7..3cb6b4341b52b0117a47495f6af8161df8a7c076 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -26,17 +26,17 @@ # Default version, product, and vendor information to use, # unless overridden by configure -DEFAULT_VERSION_FEATURE=18 +DEFAULT_VERSION_FEATURE=19 DEFAULT_VERSION_INTERIM=0 DEFAULT_VERSION_UPDATE=0 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2022-03-22 -DEFAULT_VERSION_CLASSFILE_MAJOR=62 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" +DEFAULT_VERSION_DATE=2022-09-20 +DEFAULT_VERSION_CLASSFILE_MAJOR=63 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 -DEFAULT_ACCEPTABLE_BOOT_VERSIONS="17 18" -DEFAULT_JDK_SOURCE_TARGET_VERSION=18 +DEFAULT_ACCEPTABLE_BOOT_VERSIONS="17 18 19" +DEFAULT_JDK_SOURCE_TARGET_VERSION=19 DEFAULT_PROMOTED_VERSION_PRE=ea diff --git a/make/data/hotspot-symbols/symbols-unix b/make/data/hotspot-symbols/symbols-unix index d735f61b3a456bc9878949861043ebb995eceed7..d51fcb3727d2b97601d790d1a2d52eb559348c14 100644 --- a/make/data/hotspot-symbols/symbols-unix +++ b/make/data/hotspot-symbols/symbols-unix @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -147,6 +147,7 @@ JVM_IsArrayClass JVM_IsCDSDumpingEnabled JVM_IsConstructorIx JVM_IsDumpingClassList +JVM_IsFinalizationEnabled JVM_IsHiddenClass JVM_IsInterface JVM_IsPrimitiveClass @@ -157,6 +158,7 @@ JVM_IsSupportedJNIVersion JVM_IsThreadAlive JVM_IsVMGeneratedMethodIx JVM_LatestUserDefinedLoader +JVM_LoadZipLibrary JVM_LoadLibrary JVM_LookupDefineClass JVM_LookupLambdaProxyClassFromArchive diff --git a/make/data/symbols/java.base-C.sym.txt b/make/data/symbols/java.base-C.sym.txt index 27896d9902f9ab2f9b99a45fc9e0f065d8bcf3a9..7a45fc1b49ed190a6f8fe14b9ba1138bbf8401e2 100644 --- a/make/data/symbols/java.base-C.sym.txt +++ b/make/data/symbols/java.base-C.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ # ########################################################## # module name java.base -header exports java/io,java/lang,java/lang/annotation,java/lang/constant,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/acl,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider target linux-amd64 flags 8000 +header exports java/io,java/lang,java/lang/annotation,java/lang/constant,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/acl,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert,jdk/internal/event[jdk.jfr] uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider target linux-amd64 flags 8000 class name java/io/FileInputStream -method name finalize descriptor ()V @@ -634,3 +634,13 @@ field name serialVersionUID descriptor J constantValue -1430015993304333921 flag class name javax/net/ssl/HttpsURLConnection method name getSSLSession descriptor ()Ljava/util/Optional; flags 1 signature ()Ljava/util/Optional; +class name jdk/internal/event/Event +header extends java/lang/Object flags 421 +method name descriptor ()V flags 4 +method name begin descriptor ()V flags 1 +method name end descriptor ()V flags 1 +method name commit descriptor ()V flags 1 +method name isEnabled descriptor ()Z flags 1 +method name shouldCommit descriptor ()Z flags 1 +method name set descriptor (ILjava/lang/Object;)V flags 1 + diff --git a/make/data/symbols/java.base-E.sym.txt b/make/data/symbols/java.base-E.sym.txt index 0aebcdd54d9e74e8177d879c0a2908a10dd7d66b..eaebf4b68f57c3e60f216b894691a36d6d1f4911 100644 --- a/make/data/symbols/java.base-E.sym.txt +++ b/make/data/symbols/java.base-E.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ # ########################################################## # module name java.base -header exports java/io,java/lang,java/lang/annotation,java/lang/constant,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider target linux-amd64 flags 8000 +header exports java/io,java/lang,java/lang/annotation,java/lang/constant,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert,jdk/internal/event[jdk.jfr] uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider target linux-amd64 flags 8000 class name java/io/PrintStream method name write descriptor ([B)V thrownTypes java/io/IOException flags 1 @@ -209,18 +209,18 @@ method name setCurrentBlocker descriptor (Ljava/lang/Object;)V flags 9 class name java/util/concurrent/locks/StampedLock header extends java/lang/Object implements java/io/Serializable flags 21 classAnnotations @Ljdk/Profile+Annotation;(value=I1) -method name tryWriteLock descriptor ()J flags 1 -method name writeLockInterruptibly descriptor ()J thrownTypes java/lang/InterruptedException flags 1 -method name tryReadLock descriptor ()J flags 1 -method name tryReadLock descriptor (JLjava/util/concurrent/TimeUnit;)J thrownTypes java/lang/InterruptedException flags 1 -method name readLockInterruptibly descriptor ()J thrownTypes java/lang/InterruptedException flags 1 -method name unlock descriptor (J)V flags 1 -method name tryWriteLock descriptor ()J -method name writeLockInterruptibly descriptor ()J -method name tryReadLock descriptor ()J -method name tryReadLock descriptor (JLjava/util/concurrent/TimeUnit;)J -method name readLockInterruptibly descriptor ()J -method name unlock descriptor (J)V +method name tryWriteLock descriptor ()J flags 1 +method name writeLockInterruptibly descriptor ()J thrownTypes java/lang/InterruptedException flags 1 +method name tryReadLock descriptor ()J flags 1 +method name tryReadLock descriptor (JLjava/util/concurrent/TimeUnit;)J thrownTypes java/lang/InterruptedException flags 1 +method name readLockInterruptibly descriptor ()J thrownTypes java/lang/InterruptedException flags 1 +method name unlock descriptor (J)V flags 1 -class name java/util/jar/Pack200 diff --git a/make/data/symbols/java.base-G.sym.txt b/make/data/symbols/java.base-G.sym.txt index 774c74459b4d6ea5cb74292161f98a904237306d..8196ef6be117ee881ef1031159b42677d8a23976 100644 --- a/make/data/symbols/java.base-G.sym.txt +++ b/make/data/symbols/java.base-G.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,9 @@ # ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### # ########################################################## # +module name java.base +header exports java/io,java/lang,java/lang/annotation,java/lang/constant,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert,jdk/internal/event[jdk.jfr],jdk/internal/vm/vector[jdk.incubator.vector] uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider target linux-amd64 flags 8000 + class name java/io/PrintStream header extends java/io/FilterOutputStream implements java/lang/Appendable,java/io/Closeable flags 21 innerclass innerClass java/util/Locale$Category outerClass java/util/Locale innerClassName Category flags 4019 @@ -677,8 +680,8 @@ method name toString descriptor ()Ljava/lang/String; flags 1 class name java/security/spec/PSSParameterSpec -field name TRAILER_FIELD_BC descriptor I -field name TRAILER_FIELD_BC descriptor I constantValue 1 flags 19 -method name toString descriptor ()Ljava/lang/String; +field name TRAILER_FIELD_BC descriptor I constantValue 1 flags 19 method name toString descriptor ()Ljava/lang/String; flags 1 class name java/security/spec/RSAKeyGenParameterSpec @@ -1169,3 +1172,113 @@ header extends java/lang/Object implements java/security/spec/AlgorithmParameter class name javax/crypto/spec/SecretKeySpec header extends java/lang/Object implements java/security/spec/KeySpec,javax/crypto/SecretKey flags 21 +class name jdk/internal/event/Event +header extends java/lang/Object flags 421 +-method name descriptor ()V +-method name begin descriptor ()V +-method name end descriptor ()V +-method name commit descriptor ()V +-method name isEnabled descriptor ()Z +-method name shouldCommit descriptor ()Z +-method name set descriptor (ILjava/lang/Object;)V +method name descriptor ()V flags 4 +method name begin descriptor ()V flags 1 +method name end descriptor ()V flags 1 +method name commit descriptor ()V flags 1 +method name isEnabled descriptor ()Z flags 1 +method name shouldCommit descriptor ()Z flags 1 +method name set descriptor (ILjava/lang/Object;)V flags 1 + +class name jdk/internal/vm/vector/VectorSupport +header extends java/lang/Object nestMembers jdk/internal/vm/vector/VectorSupport$VectorMask,jdk/internal/vm/vector/VectorSupport$VectorShuffle,jdk/internal/vm/vector/VectorSupport$Vector,jdk/internal/vm/vector/VectorSupport$VectorPayload,jdk/internal/vm/vector/VectorSupport$VectorSpecies flags 21 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +field name VECTOR_OP_ABS descriptor I constantValue 0 flags 19 +field name VECTOR_OP_NEG descriptor I constantValue 1 flags 19 +field name VECTOR_OP_SQRT descriptor I constantValue 2 flags 19 +field name VECTOR_OP_ADD descriptor I constantValue 4 flags 19 +field name VECTOR_OP_SUB descriptor I constantValue 5 flags 19 +field name VECTOR_OP_MUL descriptor I constantValue 6 flags 19 +field name VECTOR_OP_DIV descriptor I constantValue 7 flags 19 +field name VECTOR_OP_MIN descriptor I constantValue 8 flags 19 +field name VECTOR_OP_MAX descriptor I constantValue 9 flags 19 +field name VECTOR_OP_AND descriptor I constantValue 10 flags 19 +field name VECTOR_OP_OR descriptor I constantValue 11 flags 19 +field name VECTOR_OP_XOR descriptor I constantValue 12 flags 19 +field name VECTOR_OP_FMA descriptor I constantValue 13 flags 19 +field name VECTOR_OP_LSHIFT descriptor I constantValue 14 flags 19 +field name VECTOR_OP_RSHIFT descriptor I constantValue 15 flags 19 +field name VECTOR_OP_URSHIFT descriptor I constantValue 16 flags 19 +field name VECTOR_OP_CAST descriptor I constantValue 17 flags 19 +field name VECTOR_OP_REINTERPRET descriptor I constantValue 18 flags 19 +field name BT_eq descriptor I constantValue 0 flags 19 +field name BT_ne descriptor I constantValue 4 flags 19 +field name BT_le descriptor I constantValue 5 flags 19 +field name BT_ge descriptor I constantValue 7 flags 19 +field name BT_lt descriptor I constantValue 3 flags 19 +field name BT_gt descriptor I constantValue 1 flags 19 +field name BT_overflow descriptor I constantValue 2 flags 19 +field name BT_no_overflow descriptor I constantValue 6 flags 19 +field name T_FLOAT descriptor I constantValue 6 flags 19 +field name T_DOUBLE descriptor I constantValue 7 flags 19 +field name T_BYTE descriptor I constantValue 8 flags 19 +field name T_SHORT descriptor I constantValue 9 flags 19 +field name T_INT descriptor I constantValue 10 flags 19 +field name T_LONG descriptor I constantValue 11 flags 19 +method name descriptor ()V flags 1 +method name broadcastCoerced descriptor (Ljava/lang/Class;Ljava/lang/Class;IJLjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$BroadcastOperation;)Ljava/lang/Object; flags 9 signature ;>(Ljava/lang/Class<+TVM;>;Ljava/lang/Class;IJTS;Ljdk/internal/vm/vector/VectorSupport$BroadcastOperation;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name shuffleIota descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;IIIILjdk/internal/vm/vector/VectorSupport$ShuffleIotaOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorShuffle; flags 9 signature ;>(Ljava/lang/Class<*>;Ljava/lang/Class<*>;TS;IIIILjdk/internal/vm/vector/VectorSupport$ShuffleIotaOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorShuffle; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name shuffleToVector descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;ILjdk/internal/vm/vector/VectorSupport$ShuffleToVectorOperation;)Ljava/lang/Object; flags 9 signature ;E:Ljava/lang/Object;>(Ljava/lang/Class<*>;Ljava/lang/Class<*>;Ljava/lang/Class<*>;TSh;ILjdk/internal/vm/vector/VectorSupport$ShuffleToVectorOperation;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name indexVector descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$IndexOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;E:Ljava/lang/Object;S:Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;ITV;ITS;Ljdk/internal/vm/vector/VectorSupport$IndexOperation;)TV; +method name reductionCoerced descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljava/util/function/Function;)J flags 9 signature ;>(ILjava/lang/Class<*>;Ljava/lang/Class<*>;ITV;Ljava/util/function/Function;)J runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name extract descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VecExtractOp;)J flags 9 signature ;>(Ljava/lang/Class<*>;Ljava/lang/Class<*>;ITV;ILjdk/internal/vm/vector/VectorSupport$VecExtractOp;)J runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name insert descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;IJLjdk/internal/vm/vector/VectorSupport$VecInsertOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class<*>;ITV;IJLjdk/internal/vm/vector/VectorSupport$VecInsertOp;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name unaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object; flags 9 signature (ILjava/lang/Class<+TVM;>;Ljava/lang/Class<*>;ITVM;Ljava/util/function/Function;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name binaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object; flags 9 signature (ILjava/lang/Class<+TVM;>;Ljava/lang/Class<*>;ITVM;TVM;Ljava/util/function/BiFunction;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name ternaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljdk/internal/vm/vector/VectorSupport$TernaryOperation;)Ljava/lang/Object; flags 9 signature (ILjava/lang/Class<+TVM;>;Ljava/lang/Class<*>;ITVM;TVM;TVM;Ljdk/internal/vm/vector/VectorSupport$TernaryOperation;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name load descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JLjava/lang/Object;ILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$LoadOperation;)Ljava/lang/Object; flags 9 signature ;>(Ljava/lang/Class<+TVM;>;Ljava/lang/Class;ILjava/lang/Object;JTC;ITS;Ljdk/internal/vm/vector/VectorSupport$LoadOperation;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name loadWithMap descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljava/lang/Object;I[IILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$LoadVectorOperationWithMap;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;W:Ljdk/internal/vm/vector/VectorSupport$Vector;E:Ljava/lang/Object;S:Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;>(Ljava/lang/Class<*>;Ljava/lang/Class;ILjava/lang/Class<*>;Ljava/lang/Object;JTW;TC;I[IITS;Ljdk/internal/vm/vector/VectorSupport$LoadVectorOperationWithMap;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name store descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljava/lang/Object;ILjdk/internal/vm/vector/VectorSupport$StoreVectorOperation;)V flags 9 signature ;>(Ljava/lang/Class<*>;Ljava/lang/Class<*>;ILjava/lang/Object;JTV;TC;ILjdk/internal/vm/vector/VectorSupport$StoreVectorOperation;)V runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name storeWithMap descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljava/lang/Object;I[IILjdk/internal/vm/vector/VectorSupport$StoreVectorOperationWithMap;)V flags 9 signature ;W:Ljdk/internal/vm/vector/VectorSupport$Vector;>(Ljava/lang/Class<*>;Ljava/lang/Class<*>;ILjava/lang/Class<*>;Ljava/lang/Object;JTW;TV;TC;I[IILjdk/internal/vm/vector/VectorSupport$StoreVectorOperationWithMap;)V runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name test descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Z flags 9 signature (ILjava/lang/Class<*>;Ljava/lang/Class<*>;ITVM;TVM;Ljava/util/function/BiFunction;)Z runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name compare descriptor (ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorCompareOp;)Ljdk/internal/vm/vector/VectorSupport$VectorMask; flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(ILjava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class<*>;ITV;TV;Ljdk/internal/vm/vector/VectorSupport$VectorCompareOp;)TM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name rearrangeOp descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;Ljdk/internal/vm/vector/VectorSupport$VectorRearrangeOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;Sh:Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class<*>;ITV;TSh;Ljdk/internal/vm/vector/VectorSupport$VectorRearrangeOp;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name blend descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$VectorBlendOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class<*>;ITV;TV;TM;Ljdk/internal/vm/vector/VectorSupport$VectorBlendOp;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name broadcastInt descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VectorBroadcastIntOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;>(ILjava/lang/Class<+TV;>;Ljava/lang/Class<*>;ITV;ILjdk/internal/vm/vector/VectorSupport$VectorBroadcastIntOp;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name convert descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$VectorPayload;Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$VectorConvertOp;)Ljdk/internal/vm/vector/VectorSupport$VectorPayload; flags 9 signature ;>(ILjava/lang/Class<*>;Ljava/lang/Class<*>;ILjava/lang/Class<*>;Ljava/lang/Class<*>;ITVIN;TS;Ljdk/internal/vm/vector/VectorSupport$VectorConvertOp;)TVOUT; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name maybeRebox descriptor (Ljava/lang/Object;)Ljava/lang/Object; flags 9 signature (TV;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name getMaxLaneCount descriptor (Ljava/lang/Class;)I flags 109 signature (Ljava/lang/Class<*>;)I +method name isNonCapturingLambda descriptor (Ljava/lang/Object;)Z flags 9 + +class name jdk/internal/vm/vector/VectorSupport$Vector +header extends jdk/internal/vm/vector/VectorSupport$VectorPayload nestHost jdk/internal/vm/vector/VectorSupport flags 21 signature Ljdk/internal/vm/vector/VectorSupport$VectorPayload; +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +method name descriptor (Ljava/lang/Object;)V flags 1 + +class name jdk/internal/vm/vector/VectorSupport$VectorMask +header extends jdk/internal/vm/vector/VectorSupport$VectorPayload nestHost jdk/internal/vm/vector/VectorSupport flags 21 signature Ljdk/internal/vm/vector/VectorSupport$VectorPayload; +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +method name descriptor (Ljava/lang/Object;)V flags 1 + +class name jdk/internal/vm/vector/VectorSupport$VectorPayload +header extends java/lang/Object nestHost jdk/internal/vm/vector/VectorSupport flags 21 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +method name descriptor (Ljava/lang/Object;)V flags 1 +method name getPayload descriptor ()Ljava/lang/Object; flags 14 + +class name jdk/internal/vm/vector/VectorSupport$VectorShuffle +header extends jdk/internal/vm/vector/VectorSupport$VectorPayload nestHost jdk/internal/vm/vector/VectorSupport flags 21 signature Ljdk/internal/vm/vector/VectorSupport$VectorPayload; +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +method name descriptor (Ljava/lang/Object;)V flags 1 + +class name jdk/internal/vm/vector/VectorSupport$VectorSpecies +header extends java/lang/Object nestHost jdk/internal/vm/vector/VectorSupport flags 21 signature Ljava/lang/Object; +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +method name descriptor ()V flags 1 + diff --git a/make/data/symbols/java.base-H.sym.txt b/make/data/symbols/java.base-H.sym.txt index 585d05063b31cc9d6102b42e7b45ca6fda279123..c6ef0d70aeb710f8fdd7a30c8cf1891715114844 100644 --- a/make/data/symbols/java.base-H.sym.txt +++ b/make/data/symbols/java.base-H.sym.txt @@ -27,7 +27,7 @@ # ########################################################## # module name java.base -header exports java/io,java/lang,java/lang/annotation,java/lang/constant,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/random,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/random/RandomGenerator,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider,interface\u0020;java/util/random/RandomGenerator\u0020;impls\u0020;java/security/SecureRandom\u005C;u002C;java/util/Random\u005C;u002C;java/util/SplittableRandom target linux-amd64 flags 8000 +header exports java/io,java/lang,java/lang/annotation,java/lang/constant,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/random,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert,jdk/internal/event[jdk.jfr],jdk/internal/vm/vector[jdk.incubator.vector] uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/random/RandomGenerator,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider,interface\u0020;java/util/random/RandomGenerator\u0020;impls\u0020;java/security/SecureRandom\u005C;u002C;java/util/Random\u005C;u002C;java/util/SplittableRandom target linux-amd64 flags 8000 class name java/io/CharArrayReader method name read descriptor (Ljava/nio/CharBuffer;)I thrownTypes java/io/IOException flags 1 @@ -114,8 +114,8 @@ header extends java/lang/Object implements java/lang/annotation/Annotation flags class name java/lang/System -method name setSecurityManager descriptor (Ljava/lang/SecurityManager;)V -method name getSecurityManager descriptor ()Ljava/lang/SecurityManager; -method name getSecurityManager descriptor ()Ljava/lang/SecurityManager; flags 9 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="17") method name setSecurityManager descriptor (Ljava/lang/SecurityManager;)V flags 9 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="17")@Ljdk/internal/reflect/CallerSensitive; +method name getSecurityManager descriptor ()Ljava/lang/SecurityManager; flags 9 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="17") class name java/lang/Thread -method name checkAccess descriptor ()V @@ -313,8 +313,8 @@ field name SHA512_256 descriptor Ljava/security/spec/MGF1ParameterSpec; flags 19 class name java/security/spec/PSSParameterSpec -field name TRAILER_FIELD_BC descriptor I -field name TRAILER_FIELD_BC descriptor I constantValue 1 flags 19 -method name toString descriptor ()Ljava/lang/String; +field name TRAILER_FIELD_BC descriptor I constantValue 1 flags 19 method name toString descriptor ()Ljava/lang/String; flags 1 class name java/security/spec/RSAKeyGenParameterSpec @@ -470,8 +470,8 @@ method name splits descriptor ()Ljava/util/stream/Stream; flags 1 signature ()Lj method name splits descriptor (J)Ljava/util/stream/Stream; flags 1 signature (J)Ljava/util/stream/Stream; method name splits descriptor (Ljava/util/random/RandomGenerator$SplittableGenerator;)Ljava/util/stream/Stream; flags 1 signature (Ljava/util/random/RandomGenerator$SplittableGenerator;)Ljava/util/stream/Stream; method name splits descriptor (JLjava/util/random/RandomGenerator$SplittableGenerator;)Ljava/util/stream/Stream; flags 1 signature (JLjava/util/random/RandomGenerator$SplittableGenerator;)Ljava/util/stream/Stream; -method name split descriptor ()Ljava/util/random/RandomGenerator$SplittableGenerator; flags 1041 method name split descriptor (Ljava/util/random/RandomGenerator$SplittableGenerator;)Ljava/util/random/RandomGenerator$SplittableGenerator; flags 1041 +method name split descriptor ()Ljava/util/random/RandomGenerator$SplittableGenerator; flags 1041 class name java/util/TimeZone header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 421 @@ -928,3 +928,32 @@ method name doAsPrivileged descriptor (Ljavax/security/auth/Subject;Ljava/securi class name javax/security/auth/SubjectDomainCombiner header extends java/lang/Object implements java/security/DomainCombiner flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="17") +class name jdk/internal/vm/vector/VectorSupport +field name VECTOR_OP_MASK_TRUECOUNT descriptor I constantValue 19 flags 19 +field name VECTOR_OP_MASK_FIRSTTRUE descriptor I constantValue 20 flags 19 +field name VECTOR_OP_MASK_LASTTRUE descriptor I constantValue 21 flags 19 +field name VECTOR_OP_TAN descriptor I constantValue 101 flags 19 +field name VECTOR_OP_TANH descriptor I constantValue 102 flags 19 +field name VECTOR_OP_SIN descriptor I constantValue 103 flags 19 +field name VECTOR_OP_SINH descriptor I constantValue 104 flags 19 +field name VECTOR_OP_COS descriptor I constantValue 105 flags 19 +field name VECTOR_OP_COSH descriptor I constantValue 106 flags 19 +field name VECTOR_OP_ASIN descriptor I constantValue 107 flags 19 +field name VECTOR_OP_ACOS descriptor I constantValue 108 flags 19 +field name VECTOR_OP_ATAN descriptor I constantValue 109 flags 19 +field name VECTOR_OP_ATAN2 descriptor I constantValue 110 flags 19 +field name VECTOR_OP_CBRT descriptor I constantValue 111 flags 19 +field name VECTOR_OP_LOG descriptor I constantValue 112 flags 19 +field name VECTOR_OP_LOG10 descriptor I constantValue 113 flags 19 +field name VECTOR_OP_LOG1P descriptor I constantValue 114 flags 19 +field name VECTOR_OP_POW descriptor I constantValue 115 flags 19 +field name VECTOR_OP_EXP descriptor I constantValue 116 flags 19 +field name VECTOR_OP_EXPM1 descriptor I constantValue 117 flags 19 +field name VECTOR_OP_HYPOT descriptor I constantValue 118 flags 19 +field name BT_unsigned_compare descriptor I constantValue 16 flags 19 +field name BT_ule descriptor I constantValue 21 flags 19 +field name BT_uge descriptor I constantValue 23 flags 19 +field name BT_ult descriptor I constantValue 19 flags 19 +field name BT_ugt descriptor I constantValue 17 flags 19 +method name maskReductionCoerced descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljdk/internal/vm/vector/VectorSupport$VectorMaskOp;)I flags 9 signature (ILjava/lang/Class<+TM;>;Ljava/lang/Class<*>;ITM;Ljdk/internal/vm/vector/VectorSupport$VectorMaskOp;)I runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; + diff --git a/make/data/symbols/java.base-I.sym.txt b/make/data/symbols/java.base-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..bb60a7a3070701327458c42ee66c6f60b2e2c0b5 --- /dev/null +++ b/make/data/symbols/java.base-I.sym.txt @@ -0,0 +1,756 @@ +# +# Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +module name java.base +header exports java/io,java/lang,java/lang/annotation,java/lang/constant,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/random,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert,jdk/internal/event[jdk.jfr],jdk/internal/vm/vector[jdk.incubator.vector] uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/InetAddressResolverProvider,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/random/RandomGenerator,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider,interface\u0020;java/util/random/RandomGenerator\u0020;impls\u0020;java/security/SecureRandom\u005C;u002C;java/util/Random\u005C;u002C;java/util/SplittableRandom target linux-amd64 flags 8000 + +class name java/io/FileInputStream +method name transferTo descriptor (Ljava/io/OutputStream;)J thrownTypes java/io/IOException flags 1 + +class name java/io/ObjectInputStream$GetField +-method name get descriptor (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; +method name get descriptor (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; thrownTypes java/io/IOException,java/lang/ClassNotFoundException flags 401 + +class name java/io/PrintStream +header extends java/io/FilterOutputStream implements java/lang/Appendable,java/io/Closeable flags 21 +innerclass innerClass java/util/Locale$Category outerClass java/util/Locale innerClassName Category flags 4019 +method name charset descriptor ()Ljava/nio/charset/Charset; flags 1 + +class name java/lang/AbstractStringBuilder +header extends java/lang/Object implements java/lang/Appendable,java/lang/CharSequence flags 420 +innerclass innerClass java/util/Spliterator$OfInt outerClass java/util/Spliterator innerClassName OfInt flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/Compiler +header extends java/lang/Object flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name java/lang/Deprecated +header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 runtimeAnnotations @Ljava/lang/annotation/Documented;@Ljava/lang/annotation/Retention;(value=eLjava/lang/annotation/RetentionPolicy;RUNTIME;)@Ljava/lang/annotation/Target;(value={eLjava/lang/annotation/ElementType;CONSTRUCTOR;eLjava/lang/annotation/ElementType;FIELD;eLjava/lang/annotation/ElementType;LOCAL_VARIABLE;eLjava/lang/annotation/ElementType;METHOD;eLjava/lang/annotation/ElementType;PACKAGE;eLjava/lang/annotation/ElementType;MODULE;eLjava/lang/annotation/ElementType;PARAMETER;eLjava/lang/annotation/ElementType;TYPE;}) + +class name java/lang/Enum +-method name finalize descriptor ()V +method name finalize descriptor ()V flags 14 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="18") + +class name java/lang/IllegalCallerException +header extends java/lang/RuntimeException flags 21 + +class name java/lang/LayerInstantiationException +header extends java/lang/RuntimeException flags 21 + +class name java/lang/Math +method name divideExact descriptor (II)I flags 9 +method name divideExact descriptor (JJ)J flags 9 +method name floorDivExact descriptor (II)I flags 9 +method name floorDivExact descriptor (JJ)J flags 9 +method name ceilDivExact descriptor (II)I flags 9 +method name ceilDivExact descriptor (JJ)J flags 9 +method name unsignedMultiplyHigh descriptor (JJ)J flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name ceilDiv descriptor (II)I flags 9 +method name ceilDiv descriptor (JI)J flags 9 +method name ceilDiv descriptor (JJ)J flags 9 +method name ceilMod descriptor (II)I flags 9 +method name ceilMod descriptor (JI)I flags 9 +method name ceilMod descriptor (JJ)J flags 9 + +class name java/lang/NamedPackage +header extends java/lang/Object flags 20 + +class name java/lang/Object +-method name finalize descriptor ()V +method name finalize descriptor ()V thrownTypes java/lang/Throwable flags 4 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name java/lang/Runtime +-method name exec descriptor (Ljava/lang/String;)Ljava/lang/Process; +-method name exec descriptor (Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/Process; +-method name exec descriptor (Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process; +-method name runFinalization descriptor ()V +method name exec descriptor (Ljava/lang/String;)Ljava/lang/Process; thrownTypes java/io/IOException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="18") +method name exec descriptor (Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/Process; thrownTypes java/io/IOException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="18") +method name exec descriptor (Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process; thrownTypes java/io/IOException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="18") +method name runFinalization descriptor ()V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="18") + +class name java/lang/StrictMath +method name divideExact descriptor (II)I flags 9 +method name divideExact descriptor (JJ)J flags 9 +method name floorDivExact descriptor (II)I flags 9 +method name floorDivExact descriptor (JJ)J flags 9 +method name ceilDivExact descriptor (II)I flags 9 +method name ceilDivExact descriptor (JJ)J flags 9 +method name unsignedMultiplyHigh descriptor (JJ)J flags 9 +method name ceilDiv descriptor (II)I flags 9 +method name ceilDiv descriptor (JI)J flags 9 +method name ceilDiv descriptor (JJ)J flags 9 +method name ceilMod descriptor (II)I flags 9 +method name ceilMod descriptor (JI)I flags 9 +method name ceilMod descriptor (JJ)J flags 9 + +class name java/lang/SuppressWarnings +header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 runtimeAnnotations @Ljava/lang/annotation/Target;(value={eLjava/lang/annotation/ElementType;TYPE;eLjava/lang/annotation/ElementType;FIELD;eLjava/lang/annotation/ElementType;METHOD;eLjava/lang/annotation/ElementType;PARAMETER;eLjava/lang/annotation/ElementType;CONSTRUCTOR;eLjava/lang/annotation/ElementType;LOCAL_VARIABLE;eLjava/lang/annotation/ElementType;MODULE;})@Ljava/lang/annotation/Retention;(value=eLjava/lang/annotation/RetentionPolicy;SOURCE;) + +class name java/lang/System +-method name runFinalization descriptor ()V +method name runFinalization descriptor ()V flags 9 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="18") + +class name java/lang/Thread +-method name stop descriptor ()V +method name stop descriptor ()V flags 11 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="1.2") + +class name java/lang/constant/ClassDesc +header extends java/lang/Object implements java/lang/constant/ConstantDesc,java/lang/invoke/TypeDescriptor$OfField sealed true flags 601 signature Ljava/lang/Object;Ljava/lang/constant/ConstantDesc;Ljava/lang/invoke/TypeDescriptor$OfField; +innerclass innerClass java/lang/invoke/TypeDescriptor$OfField outerClass java/lang/invoke/TypeDescriptor innerClassName OfField flags 609 + +class name java/lang/constant/ConstantDesc +header extends java/lang/Object sealed true flags 601 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/constant/DirectMethodHandleDesc +header extends java/lang/Object implements java/lang/constant/MethodHandleDesc nestMembers java/lang/constant/DirectMethodHandleDesc$Kind sealed true flags 601 +innerclass innerClass java/lang/constant/DirectMethodHandleDesc$Kind outerClass java/lang/constant/DirectMethodHandleDesc innerClassName Kind flags 4019 + +class name java/lang/constant/MethodHandleDesc +header extends java/lang/Object implements java/lang/constant/ConstantDesc sealed true flags 601 +innerclass innerClass java/lang/constant/DirectMethodHandleDesc$Kind outerClass java/lang/constant/DirectMethodHandleDesc innerClassName Kind flags 4019 + +class name java/lang/constant/MethodTypeDesc +header extends java/lang/Object implements java/lang/constant/ConstantDesc,java/lang/invoke/TypeDescriptor$OfMethod sealed true flags 601 signature Ljava/lang/Object;Ljava/lang/constant/ConstantDesc;Ljava/lang/invoke/TypeDescriptor$OfMethod; +innerclass innerClass java/lang/invoke/TypeDescriptor$OfMethod outerClass java/lang/invoke/TypeDescriptor innerClassName OfMethod flags 609 +innerclass innerClass java/lang/invoke/TypeDescriptor$OfField outerClass java/lang/invoke/TypeDescriptor innerClassName OfField flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/invoke/CallSite +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/invoke/LambdaMetafactory +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/invoke/MethodHandle +-method name asType descriptor (Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle; +method name asType descriptor (Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle; flags 11 + +class name java/lang/invoke/StringConcatException +header extends java/lang/Exception flags 21 + +class name java/lang/module/Configuration +header extends java/lang/Object flags 31 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/module/FindException +header extends java/lang/RuntimeException flags 21 + +class name java/lang/module/InvalidModuleDescriptorException +header extends java/lang/RuntimeException flags 21 + +class name java/lang/module/ModuleReader +header extends java/lang/Object implements java/io/Closeable flags 601 + +class name java/lang/module/ModuleReference +header extends java/lang/Object flags 421 + +class name java/lang/module/ResolutionException +header extends java/lang/RuntimeException flags 21 + +class name java/lang/module/ResolvedModule +header extends java/lang/Object flags 31 + +class name java/lang/reflect/AccessibleObject +header extends java/lang/Object implements java/lang/reflect/AnnotatedElement flags 21 classAnnotations @Ljdk/Profile+Annotation;(value=I1) + +class name java/lang/reflect/AnnotatedElement +header extends java/lang/Object flags 601 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/reflect/Executable +header extends java/lang/reflect/AccessibleObject implements java/lang/reflect/Member,java/lang/reflect/GenericDeclaration sealed true flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/reflect/InaccessibleObjectException +header extends java/lang/RuntimeException flags 21 + +class name java/lang/reflect/Method +-method name invoke descriptor (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; +method name invoke descriptor (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; thrownTypes java/lang/IllegalAccessException,java/lang/reflect/InvocationTargetException flags 81 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive;@Ljdk/internal/vm/annotation/ForceInline;@Ljdk/internal/vm/annotation/IntrinsicCandidate; + +class name java/net/DatagramSocket +header extends java/lang/Object implements java/io/Closeable flags 21 classAnnotations @Ljdk/Profile+Annotation;(value=I1) + +class name java/net/InetAddress +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/net/spi/InetAddressResolver$LookupPolicy outerClass java/net/spi/InetAddressResolver innerClassName LookupPolicy flags 19 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/net/spi/InetAddressResolverProvider$Configuration outerClass java/net/spi/InetAddressResolverProvider innerClassName Configuration flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/net/ServerSocket +-method name setSoTimeout descriptor (I)V +-method name getSoTimeout descriptor ()I +-method name setReceiveBufferSize descriptor (I)V +-method name getReceiveBufferSize descriptor ()I +method name setSoTimeout descriptor (I)V thrownTypes java/net/SocketException flags 1 +method name getSoTimeout descriptor ()I thrownTypes java/io/IOException flags 1 +method name setReceiveBufferSize descriptor (I)V thrownTypes java/net/SocketException flags 1 +method name getReceiveBufferSize descriptor ()I thrownTypes java/net/SocketException flags 1 + +class name java/net/SocketImpl +header extends java/lang/Object implements java/net/SocketOptions flags 421 + +class name java/net/spi/InetAddressResolver +header extends java/lang/Object nestMembers java/net/spi/InetAddressResolver$LookupPolicy flags 601 +innerclass innerClass java/net/spi/InetAddressResolver$LookupPolicy outerClass java/net/spi/InetAddressResolver innerClassName LookupPolicy flags 19 +method name lookupByName descriptor (Ljava/lang/String;Ljava/net/spi/InetAddressResolver$LookupPolicy;)Ljava/util/stream/Stream; thrownTypes java/net/UnknownHostException flags 401 signature (Ljava/lang/String;Ljava/net/spi/InetAddressResolver$LookupPolicy;)Ljava/util/stream/Stream; +method name lookupByAddress descriptor ([B)Ljava/lang/String; thrownTypes java/net/UnknownHostException flags 401 + +class name java/net/spi/InetAddressResolver$LookupPolicy +header extends java/lang/Object nestHost java/net/spi/InetAddressResolver flags 31 +innerclass innerClass java/net/spi/InetAddressResolver$LookupPolicy outerClass java/net/spi/InetAddressResolver innerClassName LookupPolicy flags 19 +field name IPV4 descriptor I constantValue 1 flags 19 +field name IPV6 descriptor I constantValue 2 flags 19 +field name IPV4_FIRST descriptor I constantValue 4 flags 19 +field name IPV6_FIRST descriptor I constantValue 8 flags 19 +method name of descriptor (I)Ljava/net/spi/InetAddressResolver$LookupPolicy; flags 9 +method name characteristics descriptor ()I flags 1 + +class name java/net/spi/InetAddressResolverProvider +header extends java/lang/Object nestMembers java/net/spi/InetAddressResolverProvider$Configuration flags 421 +innerclass innerClass java/net/spi/InetAddressResolverProvider$Configuration outerClass java/net/spi/InetAddressResolverProvider innerClassName Configuration flags 609 +method name get descriptor (Ljava/net/spi/InetAddressResolverProvider$Configuration;)Ljava/net/spi/InetAddressResolver; flags 401 +method name name descriptor ()Ljava/lang/String; flags 401 +method name descriptor ()V flags 4 + +class name java/net/spi/InetAddressResolverProvider$Configuration +header extends java/lang/Object nestHost java/net/spi/InetAddressResolverProvider sealed true flags 601 +innerclass innerClass java/net/spi/InetAddressResolverProvider$Configuration outerClass java/net/spi/InetAddressResolverProvider innerClassName Configuration flags 609 +method name builtinResolver descriptor ()Ljava/net/spi/InetAddressResolver; flags 401 +method name lookupLocalHostName descriptor ()Ljava/lang/String; flags 401 + +class name java/net/spi/URLStreamHandlerProvider +header extends java/lang/Object implements java/net/URLStreamHandlerFactory flags 421 + +class name java/nio/CharBuffer +header extends java/nio/Buffer implements java/lang/Comparable,java/lang/Appendable,java/lang/CharSequence,java/lang/Readable flags 421 signature Ljava/nio/Buffer;Ljava/lang/Comparable;Ljava/lang/Appendable;Ljava/lang/CharSequence;Ljava/lang/Readable; +innerclass innerClass java/util/Spliterator$OfInt outerClass java/util/Spliterator innerClassName OfInt flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/nio/charset/Charset +method name forName descriptor (Ljava/lang/String;Ljava/nio/charset/Charset;)Ljava/nio/charset/Charset; flags 9 + +class name java/security/Certificate +header extends java/lang/Object flags 601 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="1.2") + +class name java/security/Identity +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 421 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="1.2") + +class name java/security/KeyStore +method name getAttributes descriptor (Ljava/lang/String;)Ljava/util/Set; thrownTypes java/security/KeyStoreException flags 11 signature (Ljava/lang/String;)Ljava/util/Set; + +class name java/security/KeyStoreSpi +header extends java/lang/Object flags 421 +innerclass innerClass java/security/KeyStore$LoadStoreParameter outerClass java/security/KeyStore innerClassName LoadStoreParameter flags 609 +innerclass innerClass java/security/KeyStore$ProtectionParameter outerClass java/security/KeyStore innerClassName ProtectionParameter flags 609 +innerclass innerClass java/security/KeyStore$PasswordProtection outerClass java/security/KeyStore innerClassName PasswordProtection flags 9 +innerclass innerClass java/security/KeyStore$CallbackHandlerProtection outerClass java/security/KeyStore innerClassName CallbackHandlerProtection flags 9 +innerclass innerClass java/security/KeyStore$TrustedCertificateEntry outerClass java/security/KeyStore innerClassName TrustedCertificateEntry flags 19 +innerclass innerClass java/security/KeyStore$PrivateKeyEntry outerClass java/security/KeyStore innerClassName PrivateKeyEntry flags 19 +innerclass innerClass java/security/KeyStore$SecretKeyEntry outerClass java/security/KeyStore innerClassName SecretKeyEntry flags 19 +innerclass innerClass java/security/KeyStore$Entry outerClass java/security/KeyStore innerClassName Entry flags 609 +innerclass innerClass java/security/KeyStore$Entry$Attribute outerClass java/security/KeyStore$Entry innerClassName Attribute flags 609 +method name engineGetAttributes descriptor (Ljava/lang/String;)Ljava/util/Set; flags 1 signature (Ljava/lang/String;)Ljava/util/Set; + +class name java/security/Provider +-method name getServices descriptor ()Ljava/util/Set; +method name getServices descriptor ()Ljava/util/Set; flags 1 signature ()Ljava/util/Set; + +class name java/security/SecureRandomParameters +header extends java/lang/Object flags 601 + +class name java/security/SignedObject +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name java/security/cert/CertificateRevokedException +header extends java/security/cert/CertificateException flags 21 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 + +class name java/security/cert/URICertStoreParameters +header extends java/lang/Object implements java/security/cert/CertStoreParameters flags 31 + +class name java/security/interfaces/RSAKey +-method name getParams descriptor ()Ljava/security/spec/AlgorithmParameterSpec; +method name getParams descriptor ()Ljava/security/spec/AlgorithmParameterSpec; flags 1 + +class name java/security/spec/MGF1ParameterSpec +-field name SHA512_224 descriptor Ljava/security/spec/MGF1ParameterSpec; +-field name SHA512_256 descriptor Ljava/security/spec/MGF1ParameterSpec; +field name SHA512_224 descriptor Ljava/security/spec/MGF1ParameterSpec; flags 19 +field name SHA512_256 descriptor Ljava/security/spec/MGF1ParameterSpec; flags 19 + +class name java/security/spec/PSSParameterSpec +-field name TRAILER_FIELD_BC descriptor I +-method name toString descriptor ()Ljava/lang/String; +field name TRAILER_FIELD_BC descriptor I constantValue 1 flags 19 +method name toString descriptor ()Ljava/lang/String; flags 1 + +class name java/security/spec/RSAKeyGenParameterSpec +-method name descriptor (ILjava/math/BigInteger;Ljava/security/spec/AlgorithmParameterSpec;)V +-method name getKeyParams descriptor ()Ljava/security/spec/AlgorithmParameterSpec; +method name descriptor (ILjava/math/BigInteger;Ljava/security/spec/AlgorithmParameterSpec;)V flags 1 +method name getKeyParams descriptor ()Ljava/security/spec/AlgorithmParameterSpec; flags 1 + +class name java/security/spec/RSAMultiPrimePrivateCrtKeySpec +-method name descriptor (Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;[Ljava/security/spec/RSAOtherPrimeInfo;Ljava/security/spec/AlgorithmParameterSpec;)V +method name descriptor (Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;[Ljava/security/spec/RSAOtherPrimeInfo;Ljava/security/spec/AlgorithmParameterSpec;)V flags 1 + +class name java/security/spec/RSAPrivateCrtKeySpec +-method name descriptor (Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/security/spec/AlgorithmParameterSpec;)V +method name descriptor (Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/security/spec/AlgorithmParameterSpec;)V flags 1 + +class name java/security/spec/RSAPrivateKeySpec +-method name descriptor (Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/security/spec/AlgorithmParameterSpec;)V +-method name getParams descriptor ()Ljava/security/spec/AlgorithmParameterSpec; +method name descriptor (Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/security/spec/AlgorithmParameterSpec;)V flags 1 +method name getParams descriptor ()Ljava/security/spec/AlgorithmParameterSpec; flags 1 + +class name java/security/spec/RSAPublicKeySpec +-method name descriptor (Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/security/spec/AlgorithmParameterSpec;)V +-method name getParams descriptor ()Ljava/security/spec/AlgorithmParameterSpec; +method name descriptor (Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/security/spec/AlgorithmParameterSpec;)V flags 1 +method name getParams descriptor ()Ljava/security/spec/AlgorithmParameterSpec; flags 1 + +class name java/text/DateFormatSymbols +header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 21 +innerclass innerClass java/util/Locale$Category outerClass java/util/Locale innerClassName Category flags 4019 + +class name java/text/RuleBasedCollator +header extends java/text/Collator flags 21 +innerclass innerClass java/text/Normalizer$Form outerClass java/text/Normalizer innerClassName Form flags 4019 + +class name java/time/Duration +method name isPositive descriptor ()Z flags 1 + +class name java/time/chrono/ChronoLocalDate +header extends java/lang/Object implements java/time/temporal/Temporal,java/time/temporal/TemporalAdjuster,java/lang/Comparable flags 601 signature Ljava/lang/Object;Ljava/time/temporal/Temporal;Ljava/time/temporal/TemporalAdjuster;Ljava/lang/Comparable; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/time/chrono/ChronoLocalDateTime +header extends java/lang/Object implements java/time/temporal/Temporal,java/time/temporal/TemporalAdjuster,java/lang/Comparable flags 601 signature Ljava/lang/Object;Ljava/time/temporal/Temporal;Ljava/time/temporal/TemporalAdjuster;Ljava/lang/Comparable;>; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/time/format/DecimalStyle +header extends java/lang/Object flags 31 +innerclass innerClass java/util/Locale$Category outerClass java/util/Locale innerClassName Category flags 4019 + +class name java/time/temporal/TemporalAdjusters +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/Comparator +header extends java/lang/Object flags 601 signature Ljava/lang/Object; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/DoubleSummaryStatistics +header extends java/lang/Object implements java/util/function/DoubleConsumer flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/GregorianCalendar +header extends java/util/Calendar flags 21 +innerclass innerClass java/util/Locale$Category outerClass java/util/Locale innerClassName Category flags 4019 + +class name java/util/HashMap +header extends java/util/AbstractMap implements java/util/Map,java/lang/Cloneable,java/io/Serializable flags 21 signature Ljava/util/AbstractMap;Ljava/util/Map;Ljava/lang/Cloneable;Ljava/io/Serializable; +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name java/util/HashSet +header extends java/util/AbstractSet implements java/util/Set,java/lang/Cloneable,java/io/Serializable flags 21 signature Ljava/util/AbstractSet;Ljava/util/Set;Ljava/lang/Cloneable;Ljava/io/Serializable; +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 + +class name java/util/Hashtable +header extends java/util/Dictionary implements java/util/Map,java/lang/Cloneable,java/io/Serializable flags 21 signature Ljava/util/Dictionary;Ljava/util/Map;Ljava/lang/Cloneable;Ljava/io/Serializable; +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name java/util/IdentityHashMap +header extends java/util/AbstractMap implements java/util/Map,java/io/Serializable,java/lang/Cloneable flags 21 signature Ljava/util/AbstractMap;Ljava/util/Map;Ljava/io/Serializable;Ljava/lang/Cloneable; +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name java/util/Locale$IsoCountryCode +header extends java/lang/Enum nestHost java/util/Locale sealed true flags 4421 signature Ljava/lang/Enum; +innerclass innerClass java/util/Locale$IsoCountryCode outerClass java/util/Locale innerClassName IsoCountryCode flags 4409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/Observable +header extends java/lang/Object flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/util/Observer +header extends java/lang/Object flags 601 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/util/TimeZone +header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 421 +innerclass innerClass java/util/Locale$Category outerClass java/util/Locale innerClassName Category flags 4019 + +class name java/util/TreeSet +header extends java/util/AbstractSet implements java/util/NavigableSet,java/lang/Cloneable,java/io/Serializable flags 21 signature Ljava/util/AbstractSet;Ljava/util/NavigableSet;Ljava/lang/Cloneable;Ljava/io/Serializable; +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 + +class name java/util/concurrent/ConcurrentMap +header extends java/lang/Object implements java/util/Map flags 601 signature Ljava/lang/Object;Ljava/util/Map; +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/concurrent/ConcurrentSkipListSet +header extends java/util/AbstractSet implements java/util/NavigableSet,java/lang/Cloneable,java/io/Serializable flags 21 signature Ljava/util/AbstractSet;Ljava/util/NavigableSet;Ljava/lang/Cloneable;Ljava/io/Serializable; +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/concurrent/CountedCompleter +header extends java/util/concurrent/ForkJoinTask flags 421 signature Ljava/util/concurrent/ForkJoinTask; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/concurrent/ThreadPoolExecutor +-method name finalize descriptor ()V +method name finalize descriptor ()V flags 4 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name java/util/concurrent/atomic/AtomicBoolean +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/concurrent/atomic/AtomicReference +header extends java/lang/Object implements java/io/Serializable flags 21 signature Ljava/lang/Object;Ljava/io/Serializable; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/concurrent/atomic/AtomicReferenceArray +header extends java/lang/Object implements java/io/Serializable flags 21 signature Ljava/lang/Object;Ljava/io/Serializable; +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/concurrent/locks/StampedLock +header extends java/lang/Object implements java/io/Serializable flags 21 classAnnotations @Ljdk/Profile+Annotation;(value=I1) +-method name tryWriteLock descriptor ()J +-method name writeLockInterruptibly descriptor ()J +-method name tryReadLock descriptor ()J +-method name tryReadLock descriptor (JLjava/util/concurrent/TimeUnit;)J +-method name readLockInterruptibly descriptor ()J +-method name unlock descriptor (J)V +method name tryWriteLock descriptor ()J flags 1 +method name writeLockInterruptibly descriptor ()J thrownTypes java/lang/InterruptedException flags 1 +method name tryReadLock descriptor ()J flags 1 +method name tryReadLock descriptor (JLjava/util/concurrent/TimeUnit;)J thrownTypes java/lang/InterruptedException flags 1 +method name readLockInterruptibly descriptor ()J thrownTypes java/lang/InterruptedException flags 1 +method name unlock descriptor (J)V flags 1 + +class name java/util/function/BiConsumer +header extends java/lang/Object flags 601 signature Ljava/lang/Object; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/BiFunction +header extends java/lang/Object flags 601 signature Ljava/lang/Object; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/BiPredicate +header extends java/lang/Object flags 601 signature Ljava/lang/Object; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/BinaryOperator +header extends java/lang/Object implements java/util/function/BiFunction flags 601 signature Ljava/lang/Object;Ljava/util/function/BiFunction; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/Consumer +header extends java/lang/Object flags 601 signature Ljava/lang/Object; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/DoubleConsumer +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/DoublePredicate +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/DoubleUnaryOperator +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/Function +header extends java/lang/Object flags 601 signature Ljava/lang/Object; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/IntConsumer +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/IntPredicate +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/IntUnaryOperator +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/LongConsumer +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/LongPredicate +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/LongUnaryOperator +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/Predicate +header extends java/lang/Object flags 601 signature Ljava/lang/Object; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/function/UnaryOperator +header extends java/lang/Object implements java/util/function/Function flags 601 signature Ljava/lang/Object;Ljava/util/function/Function; runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/spi/AbstractResourceBundleProvider +header extends java/lang/Object implements java/util/spi/ResourceBundleProvider flags 421 +innerclass innerClass java/util/ResourceBundle$Control outerClass java/util/ResourceBundle innerClassName Control flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/spi/CurrencyNameProvider +header extends java/util/spi/LocaleServiceProvider flags 421 +innerclass innerClass java/util/ResourceBundle$Control outerClass java/util/ResourceBundle innerClassName Control flags 9 + +class name java/util/spi/ResourceBundleProvider +header extends java/lang/Object flags 601 + +class name java/util/spi/ToolProvider +header extends java/lang/Object flags 601 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/zip/CRC32C +header extends java/lang/Object implements java/util/zip/Checksum flags 31 + +class name javax/crypto/AEADBadTagException +header extends javax/crypto/BadPaddingException flags 21 + +class name javax/crypto/BadPaddingException +header extends java/security/GeneralSecurityException flags 21 + +class name javax/crypto/CipherInputStream +header extends java/io/FilterInputStream flags 21 + +class name javax/crypto/CipherOutputStream +header extends java/io/FilterOutputStream flags 21 + +class name javax/crypto/CipherSpi +header extends java/lang/Object flags 421 + +class name javax/crypto/EncryptedPrivateKeyInfo +header extends java/lang/Object flags 21 + +class name javax/crypto/ExemptionMechanism +header extends java/lang/Object flags 21 + +class name javax/crypto/ExemptionMechanismException +header extends java/security/GeneralSecurityException flags 21 + +class name javax/crypto/ExemptionMechanismSpi +header extends java/lang/Object flags 421 + +class name javax/crypto/IllegalBlockSizeException +header extends java/security/GeneralSecurityException flags 21 + +class name javax/crypto/KeyAgreement +header extends java/lang/Object flags 21 +innerclass innerClass java/security/Provider$Service outerClass java/security/Provider innerClassName Service flags 9 + +class name javax/crypto/KeyAgreementSpi +header extends java/lang/Object flags 421 + +class name javax/crypto/KeyGenerator +header extends java/lang/Object flags 21 +innerclass innerClass java/security/Provider$Service outerClass java/security/Provider innerClassName Service flags 9 + +class name javax/crypto/KeyGeneratorSpi +header extends java/lang/Object flags 421 + +class name javax/crypto/Mac +header extends java/lang/Object implements java/lang/Cloneable flags 21 +innerclass innerClass java/security/Provider$Service outerClass java/security/Provider innerClassName Service flags 9 + +class name javax/crypto/MacSpi +header extends java/lang/Object flags 421 + +class name javax/crypto/NoSuchPaddingException +header extends java/security/GeneralSecurityException flags 21 + +class name javax/crypto/NullCipher +header extends javax/crypto/Cipher flags 21 + +class name javax/crypto/SealedObject +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/crypto/SecretKey +header extends java/lang/Object implements java/security/Key,javax/security/auth/Destroyable flags 601 + +class name javax/crypto/SecretKeyFactory +header extends java/lang/Object flags 21 +innerclass innerClass java/security/Provider$Service outerClass java/security/Provider innerClassName Service flags 9 + +class name javax/crypto/SecretKeyFactorySpi +header extends java/lang/Object flags 421 + +class name javax/crypto/ShortBufferException +header extends java/security/GeneralSecurityException flags 21 + +class name javax/crypto/interfaces/DHKey +header extends java/lang/Object flags 601 + +class name javax/crypto/interfaces/DHPrivateKey +header extends java/lang/Object implements javax/crypto/interfaces/DHKey,java/security/PrivateKey flags 601 + +class name javax/crypto/interfaces/DHPublicKey +header extends java/lang/Object implements javax/crypto/interfaces/DHKey,java/security/PublicKey flags 601 + +class name javax/crypto/interfaces/PBEKey +header extends java/lang/Object implements javax/crypto/SecretKey flags 601 + +class name javax/crypto/spec/DESKeySpec +header extends java/lang/Object implements java/security/spec/KeySpec flags 21 + +class name javax/crypto/spec/DESedeKeySpec +header extends java/lang/Object implements java/security/spec/KeySpec flags 21 + +class name javax/crypto/spec/DHGenParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec flags 21 + +class name javax/crypto/spec/DHParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec flags 21 + +class name javax/crypto/spec/DHPrivateKeySpec +header extends java/lang/Object implements java/security/spec/KeySpec flags 21 + +class name javax/crypto/spec/DHPublicKeySpec +header extends java/lang/Object implements java/security/spec/KeySpec flags 21 + +class name javax/crypto/spec/GCMParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec flags 21 + +class name javax/crypto/spec/IvParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec flags 21 + +class name javax/crypto/spec/OAEPParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec flags 21 +innerclass innerClass javax/crypto/spec/PSource$PSpecified outerClass javax/crypto/spec/PSource innerClassName PSpecified flags 19 + +class name javax/crypto/spec/PBEKeySpec +header extends java/lang/Object implements java/security/spec/KeySpec flags 21 + +class name javax/crypto/spec/PBEParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec flags 21 + +class name javax/crypto/spec/RC2ParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec flags 21 + +class name javax/crypto/spec/RC5ParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec flags 21 + +class name javax/crypto/spec/SecretKeySpec +header extends java/lang/Object implements java/security/spec/KeySpec,javax/crypto/SecretKey flags 21 + +class name javax/security/auth/Subject +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name doAs descriptor (Ljavax/security/auth/Subject;Ljava/security/PrivilegedAction;)Ljava/lang/Object; +-method name doAs descriptor (Ljavax/security/auth/Subject;Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object; +method name current descriptor ()Ljavax/security/auth/Subject; flags 9 +method name callAs descriptor (Ljavax/security/auth/Subject;Ljava/util/concurrent/Callable;)Ljava/lang/Object; thrownTypes java/util/concurrent/CompletionException flags 9 signature (Ljavax/security/auth/Subject;Ljava/util/concurrent/Callable;)TT; +method name doAs descriptor (Ljavax/security/auth/Subject;Ljava/security/PrivilegedAction;)Ljava/lang/Object; flags 9 deprecated true signature (Ljavax/security/auth/Subject;Ljava/security/PrivilegedAction;)TT; runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="18") +method name doAs descriptor (Ljavax/security/auth/Subject;Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object; thrownTypes java/security/PrivilegedActionException flags 9 deprecated true signature (Ljavax/security/auth/Subject;Ljava/security/PrivilegedExceptionAction;)TT; runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="18") + +class name javax/security/auth/login/LoginContext +header extends java/lang/Object flags 21 +innerclass innerClass javax/security/auth/login/AppConfigurationEntry$LoginModuleControlFlag outerClass javax/security/auth/login/AppConfigurationEntry innerClassName LoginModuleControlFlag flags 9 +innerclass innerClass java/util/ServiceLoader$Provider outerClass java/util/ServiceLoader innerClassName Provider flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/internal/vm/vector/VectorSupport +header extends java/lang/Object nestMembers jdk/internal/vm/vector/VectorSupport$VectorMask,jdk/internal/vm/vector/VectorSupport$VectorShuffle,jdk/internal/vm/vector/VectorSupport$Vector,jdk/internal/vm/vector/VectorSupport$VectorPayload,jdk/internal/vm/vector/VectorSupport$VectorSpecies flags 21 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +-method name broadcastCoerced descriptor (Ljava/lang/Class;Ljava/lang/Class;IJLjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$BroadcastOperation;)Ljava/lang/Object; +-method name shuffleIota descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;IIIILjdk/internal/vm/vector/VectorSupport$ShuffleIotaOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorShuffle; +-method name shuffleToVector descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;ILjdk/internal/vm/vector/VectorSupport$ShuffleToVectorOperation;)Ljava/lang/Object; +-method name indexVector descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$IndexOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; +-method name reductionCoerced descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljava/util/function/Function;)J +-method name extract descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VecExtractOp;)J +-method name insert descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;IJLjdk/internal/vm/vector/VectorSupport$VecInsertOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; +-method name unaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object; +-method name binaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object; +-method name ternaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljdk/internal/vm/vector/VectorSupport$TernaryOperation;)Ljava/lang/Object; +-method name load descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JLjava/lang/Object;ILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$LoadOperation;)Ljava/lang/Object; +-method name loadWithMap descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljava/lang/Object;I[IILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$LoadVectorOperationWithMap;)Ljdk/internal/vm/vector/VectorSupport$Vector; +-method name storeWithMap descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljava/lang/Object;I[IILjdk/internal/vm/vector/VectorSupport$StoreVectorOperationWithMap;)V +-method name test descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Z +-method name compare descriptor (ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorCompareOp;)Ljdk/internal/vm/vector/VectorSupport$VectorMask; +-method name rearrangeOp descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;Ljdk/internal/vm/vector/VectorSupport$VectorRearrangeOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; +-method name blend descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$VectorBlendOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; +-method name broadcastInt descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VectorBroadcastIntOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; +-method name maybeRebox descriptor (Ljava/lang/Object;)Ljava/lang/Object; +-method name maskReductionCoerced descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;Ljdk/internal/vm/vector/VectorSupport$VectorMaskOp;)I +field name VECTOR_OP_MASK_TOLONG descriptor I constantValue 22 flags 19 +field name VECTOR_OP_LROTATE descriptor I constantValue 23 flags 19 +field name VECTOR_OP_RROTATE descriptor I constantValue 24 flags 19 +method name broadcastCoerced descriptor (Ljava/lang/Class;Ljava/lang/Class;IJLjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$BroadcastOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorPayload; flags 9 signature ;E:Ljava/lang/Object;>(Ljava/lang/Class<+TVM;>;Ljava/lang/Class;IJTS;Ljdk/internal/vm/vector/VectorSupport$BroadcastOperation;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name shuffleIota descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;IIIILjdk/internal/vm/vector/VectorSupport$ShuffleIotaOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorShuffle; flags 9 signature ;SH:Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;>(Ljava/lang/Class;Ljava/lang/Class<+TSH;>;TS;IIIILjdk/internal/vm/vector/VectorSupport$ShuffleIotaOperation;)TSH; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name shuffleToVector descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;ILjdk/internal/vm/vector/VectorSupport$ShuffleToVectorOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;SH:Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;E:Ljava/lang/Object;>(Ljava/lang/Class<+Ljdk/internal/vm/vector/VectorSupport$Vector;>;Ljava/lang/Class;Ljava/lang/Class<+TSH;>;TSH;ILjdk/internal/vm/vector/VectorSupport$ShuffleToVectorOperation;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name indexVector descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$IndexOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;E:Ljava/lang/Object;S:Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;ITV;ITS;Ljdk/internal/vm/vector/VectorSupport$IndexOperation;)TV; +method name reductionCoerced descriptor (ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$ReductionOperation;)J flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(ILjava/lang/Class<+TV;>;Ljava/lang/Class<+TM;>;Ljava/lang/Class;ITV;TM;Ljdk/internal/vm/vector/VectorSupport$ReductionOperation;)J runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name extract descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VecExtractOp;)J flags 9 signature ;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;ITV;ILjdk/internal/vm/vector/VectorSupport$VecExtractOp;)J runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name insert descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;IJLjdk/internal/vm/vector/VectorSupport$VecInsertOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;ITV;IJLjdk/internal/vm/vector/VectorSupport$VecInsertOp;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name unaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$UnaryOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(ILjava/lang/Class<+TV;>;Ljava/lang/Class<+TM;>;Ljava/lang/Class;ITV;TM;Ljdk/internal/vm/vector/VectorSupport$UnaryOperation;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name binaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$VectorPayload;Ljdk/internal/vm/vector/VectorSupport$VectorPayload;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$BinaryOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorPayload; flags 9 signature ;E:Ljava/lang/Object;>(ILjava/lang/Class<+TVM;>;Ljava/lang/Class<+TM;>;Ljava/lang/Class;ITVM;TVM;TM;Ljdk/internal/vm/vector/VectorSupport$BinaryOperation;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name ternaryOp descriptor (ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$TernaryOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(ILjava/lang/Class<+TV;>;Ljava/lang/Class<+TM;>;Ljava/lang/Class;ITV;TV;TV;TM;Ljdk/internal/vm/vector/VectorSupport$TernaryOperation;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name load descriptor (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JLjava/lang/Object;ILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$LoadOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorPayload; flags 9 signature ;>(Ljava/lang/Class<+TVM;>;Ljava/lang/Class;ILjava/lang/Object;JTC;ITS;Ljdk/internal/vm/vector/VectorSupport$LoadOperation;)TVM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name loadMasked descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$VectorMask;Ljava/lang/Object;ILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$LoadVectorMaskedOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;E:Ljava/lang/Object;S:Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JTM;TC;ITS;Ljdk/internal/vm/vector/VectorSupport$LoadVectorMaskedOperation;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name loadWithMap descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljava/lang/Object;I[IILjdk/internal/vm/vector/VectorSupport$VectorSpecies;Ljdk/internal/vm/vector/VectorSupport$LoadVectorOperationWithMap;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;W:Ljdk/internal/vm/vector/VectorSupport$Vector;S:Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class<+Ljdk/internal/vm/vector/VectorSupport$Vector;>;Ljava/lang/Object;JTW;TM;TC;I[IITS;Ljdk/internal/vm/vector/VectorSupport$LoadVectorOperationWithMap;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name storeMasked descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljava/lang/Object;ILjdk/internal/vm/vector/VectorSupport$StoreVectorMaskedOperation;)V flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JTV;TM;TC;ILjdk/internal/vm/vector/VectorSupport$StoreVectorMaskedOperation;)V runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name storeWithMap descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljava/lang/Object;I[IILjdk/internal/vm/vector/VectorSupport$StoreVectorOperationWithMap;)V flags 9 signature ;W:Ljdk/internal/vm/vector/VectorSupport$Vector;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class<+Ljdk/internal/vm/vector/VectorSupport$Vector;>;Ljava/lang/Object;JTW;TV;TM;TC;I[IILjdk/internal/vm/vector/VectorSupport$StoreVectorOperationWithMap;)V runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name test descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljava/util/function/BiFunction;)Z flags 9 signature ;E:Ljava/lang/Object;>(ILjava/lang/Class<*>;Ljava/lang/Class<*>;ITM;TM;Ljava/util/function/BiFunction;)Z runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name compare descriptor (ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$VectorCompareOp;)Ljdk/internal/vm/vector/VectorSupport$VectorMask; flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(ILjava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class;ITV;TV;TM;Ljdk/internal/vm/vector/VectorSupport$VectorCompareOp;)TM; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name rearrangeOp descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$VectorRearrangeOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;SH:Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ITV;TSH;TM;Ljdk/internal/vm/vector/VectorSupport$VectorRearrangeOp;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name blend descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$VectorBlendOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(Ljava/lang/Class<+TV;>;Ljava/lang/Class;Ljava/lang/Class;ITV;TV;TM;Ljdk/internal/vm/vector/VectorSupport$VectorBlendOp;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name broadcastInt descriptor (ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$VectorBroadcastIntOp;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;M:Ljdk/internal/vm/vector/VectorSupport$VectorMask;E:Ljava/lang/Object;>(ILjava/lang/Class<+TV;>;Ljava/lang/Class<+TM;>;Ljava/lang/Class;ITV;ITM;Ljdk/internal/vm/vector/VectorSupport$VectorBroadcastIntOp;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name maybeRebox descriptor (Ljdk/internal/vm/vector/VectorSupport$VectorPayload;)Ljdk/internal/vm/vector/VectorSupport$VectorPayload; flags 9 signature (TVP;)TVP; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name maskReductionCoerced descriptor (ILjava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$VectorMaskOp;)J flags 9 signature ;E:Ljava/lang/Object;>(ILjava/lang/Class<+TM;>;Ljava/lang/Class<*>;ITM;Ljdk/internal/vm/vector/VectorSupport$VectorMaskOp;)J runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; + diff --git a/make/data/symbols/java.compiler-I.sym.txt b/make/data/symbols/java.compiler-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f3cdb0623ee5a6369fce63891d7c7989c08abbf --- /dev/null +++ b/make/data/symbols/java.compiler-I.sym.txt @@ -0,0 +1,140 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/annotation/processing/AbstractProcessor +header extends java/lang/Object implements javax/annotation/processing/Processor flags 421 +innerclass innerClass javax/tools/Diagnostic$Kind outerClass javax/tools/Diagnostic innerClassName Kind flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/annotation/processing/Generated +header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 runtimeAnnotations @Ljava/lang/annotation/Documented;@Ljava/lang/annotation/Retention;(value=eLjava/lang/annotation/RetentionPolicy;SOURCE;)@Ljava/lang/annotation/Target;(value={eLjava/lang/annotation/ElementType;PACKAGE;eLjava/lang/annotation/ElementType;TYPE;eLjava/lang/annotation/ElementType;METHOD;eLjava/lang/annotation/ElementType;CONSTRUCTOR;eLjava/lang/annotation/ElementType;FIELD;eLjava/lang/annotation/ElementType;LOCAL_VARIABLE;eLjava/lang/annotation/ElementType;PARAMETER;}) + +class name javax/annotation/processing/Messager +method name printError descriptor (Ljava/lang/CharSequence;)V flags 1 +method name printError descriptor (Ljava/lang/CharSequence;Ljavax/lang/model/element/Element;)V flags 1 +method name printWarning descriptor (Ljava/lang/CharSequence;)V flags 1 +method name printWarning descriptor (Ljava/lang/CharSequence;Ljavax/lang/model/element/Element;)V flags 1 +method name printNote descriptor (Ljava/lang/CharSequence;)V flags 1 +method name printNote descriptor (Ljava/lang/CharSequence;Ljavax/lang/model/element/Element;)V flags 1 + +class name javax/lang/model/SourceVersion +field name RELEASE_18 descriptor Ljavax/lang/model/SourceVersion; flags 4019 +method name valueOf descriptor (Ljava/lang/Runtime$Version;)Ljavax/lang/model/SourceVersion; flags 9 +method name runtimeVersion descriptor ()Ljava/lang/Runtime$Version; flags 1 + +class name javax/lang/model/element/ExecutableElement +method name getEnclosingElement descriptor ()Ljavax/lang/model/element/Element; flags 401 + +class name javax/lang/model/element/Modifier +header extends java/lang/Enum sealed true flags 4021 signature Ljava/lang/Enum; + +class name javax/lang/model/element/UnknownAnnotationValueException +header extends javax/lang/model/UnknownEntityException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/lang/model/element/UnknownDirectiveException +header extends javax/lang/model/UnknownEntityException flags 21 +innerclass innerClass javax/lang/model/element/ModuleElement$Directive outerClass javax/lang/model/element/ModuleElement innerClassName Directive flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/lang/model/element/UnknownElementException +header extends javax/lang/model/UnknownEntityException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/lang/model/type/MirroredTypeException +header extends javax/lang/model/type/MirroredTypesException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/lang/model/type/MirroredTypesException +header extends java/lang/RuntimeException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/lang/model/type/UnknownTypeException +header extends javax/lang/model/UnknownEntityException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/lang/model/util/AbstractAnnotationValueVisitor14 +header extends javax/lang/model/util/AbstractAnnotationValueVisitor9 flags 421 signature Ljavax/lang/model/util/AbstractAnnotationValueVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/lang/model/util/AbstractElementVisitor14 +header extends javax/lang/model/util/AbstractElementVisitor9 flags 421 signature Ljavax/lang/model/util/AbstractElementVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/lang/model/util/AbstractTypeVisitor14 +header extends javax/lang/model/util/AbstractTypeVisitor9 flags 421 signature Ljavax/lang/model/util/AbstractTypeVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/lang/model/util/AbstractTypeVisitor6 +header extends java/lang/Object implements javax/lang/model/type/TypeVisitor flags 421 signature Ljava/lang/Object;Ljavax/lang/model/type/TypeVisitor; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_6;) + +class name javax/lang/model/util/AbstractTypeVisitor7 +header extends javax/lang/model/util/AbstractTypeVisitor6 flags 421 signature Ljavax/lang/model/util/AbstractTypeVisitor6; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_7;) + +class name javax/lang/model/util/AbstractTypeVisitor8 +header extends javax/lang/model/util/AbstractTypeVisitor7 flags 421 signature Ljavax/lang/model/util/AbstractTypeVisitor7; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_8;) + +class name javax/lang/model/util/ElementKindVisitor14 +header extends javax/lang/model/util/ElementKindVisitor9 flags 21 signature Ljavax/lang/model/util/ElementKindVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/lang/model/util/ElementScanner14 +header extends javax/lang/model/util/ElementScanner9 flags 21 signature Ljavax/lang/model/util/ElementScanner9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/lang/model/util/Elements +method name getOutermostTypeElement descriptor (Ljavax/lang/model/element/Element;)Ljavax/lang/model/element/TypeElement; flags 1 +method name getFileObjectOf descriptor (Ljavax/lang/model/element/Element;)Ljavax/tools/JavaFileObject; flags 1 + +class name javax/lang/model/util/SimpleAnnotationValueVisitor14 +header extends javax/lang/model/util/SimpleAnnotationValueVisitor9 flags 21 signature Ljavax/lang/model/util/SimpleAnnotationValueVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/lang/model/util/SimpleElementVisitor14 +header extends javax/lang/model/util/SimpleElementVisitor9 flags 21 signature Ljavax/lang/model/util/SimpleElementVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/lang/model/util/SimpleTypeVisitor14 +header extends javax/lang/model/util/SimpleTypeVisitor9 flags 21 signature Ljavax/lang/model/util/SimpleTypeVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/lang/model/util/TypeKindVisitor14 +header extends javax/lang/model/util/TypeKindVisitor9 flags 21 signature Ljavax/lang/model/util/TypeKindVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_18;) + +class name javax/tools/DocumentationTool$Location +field name SNIPPET_PATH descriptor Ljavax/tools/DocumentationTool$Location; flags 4019 + +class name javax/tools/ForwardingJavaFileManager +method name getJavaFileForOutputForOriginatingFiles descriptor (Ljavax/tools/JavaFileManager$Location;Ljava/lang/String;Ljavax/tools/JavaFileObject$Kind;[Ljavax/tools/FileObject;)Ljavax/tools/JavaFileObject; thrownTypes java/io/IOException flags 81 +method name getFileForOutputForOriginatingFiles descriptor (Ljavax/tools/JavaFileManager$Location;Ljava/lang/String;Ljava/lang/String;[Ljavax/tools/FileObject;)Ljavax/tools/FileObject; thrownTypes java/io/IOException flags 81 + +class name javax/tools/JavaFileManager +method name getJavaFileForOutputForOriginatingFiles descriptor (Ljavax/tools/JavaFileManager$Location;Ljava/lang/String;Ljavax/tools/JavaFileObject$Kind;[Ljavax/tools/FileObject;)Ljavax/tools/JavaFileObject; thrownTypes java/io/IOException flags 81 +method name getFileForOutputForOriginatingFiles descriptor (Ljavax/tools/JavaFileManager$Location;Ljava/lang/String;Ljava/lang/String;[Ljavax/tools/FileObject;)Ljavax/tools/FileObject; thrownTypes java/io/IOException flags 81 + +class name javax/tools/SimpleJavaFileObject +header extends java/lang/Object implements javax/tools/JavaFileObject flags 21 +innerclass innerClass javax/tools/JavaFileObject$Kind outerClass javax/tools/JavaFileObject innerClassName Kind flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/tools/ToolProvider +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.datatransfer-I.sym.txt b/make/data/symbols/java.datatransfer-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..748b21f2ef81b739b3160fd099c7a49240c61a79 --- /dev/null +++ b/make/data/symbols/java.datatransfer-I.sym.txt @@ -0,0 +1,36 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/awt/datatransfer/Clipboard +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/datatransfer/DataFlavor +header extends java/lang/Object implements java/io/Externalizable,java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.desktop-I.sym.txt b/make/data/symbols/java.desktop-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..348d9fd110ebbf775a09e5f8e067c1be4a6b9110 --- /dev/null +++ b/make/data/symbols/java.desktop-I.sym.txt @@ -0,0 +1,922 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/awt/AWTKeyStroke +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/AttributeValue +header extends java/lang/Object flags 420 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/BorderLayout +header extends java/lang/Object implements java/awt/LayoutManager2,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/CheckboxGroup +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/Color +header extends java/lang/Object implements java/awt/Paint,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/ContainerOrderFocusTraversalPolicy +header extends java/awt/FocusTraversalPolicy implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/Dimension +header extends java/awt/geom/Dimension2D implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/DisplayMode +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/Event +header extends java/lang/Object implements java/io/Serializable flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/FlowLayout +header extends java/lang/Object implements java/awt/LayoutManager,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/FontMetrics +header extends java/lang/Object implements java/io/Serializable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/Graphics +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name finalize descriptor ()V +method name finalize descriptor ()V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name java/awt/GridBagLayoutInfo +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/awt/Component$BaselineResizeBehavior outerClass java/awt/Component innerClassName BaselineResizeBehavior flags 4019 + +class name java/awt/GridLayout +header extends java/lang/Object implements java/awt/LayoutManager,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/HeadlessException +header extends java/lang/UnsupportedOperationException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/Insets +header extends java/lang/Object implements java/lang/Cloneable,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/MenuShortcut +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/Point +header extends java/awt/geom/Point2D implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/PrintJob +-method name finalize descriptor ()V +method name finalize descriptor ()V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name java/awt/Rectangle +header extends java/awt/geom/Rectangle2D implements java/awt/Shape,java/io/Serializable flags 21 +innerclass innerClass java/awt/geom/Rectangle2D$Double outerClass java/awt/geom/Rectangle2D innerClassName Double flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/SystemColor +header extends java/awt/Color implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/TexturePaint +header extends java/lang/Object implements java/awt/Paint flags 21 +innerclass innerClass java/awt/geom/Rectangle2D$Double outerClass java/awt/geom/Rectangle2D innerClassName Double flags 9 + +class name java/awt/color/ColorSpace +header extends java/lang/Object implements java/io/Serializable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/color/ICC_ColorSpace +header extends java/awt/color/ColorSpace flags 21 classAnnotations @Ljdk/Profile+Annotation;(value=I4) + +class name java/awt/color/ICC_Profile +-method name finalize descriptor ()V + +class name java/awt/desktop/AboutEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/AboutHandler +header extends java/lang/Object flags 601 + +class name java/awt/desktop/AppEvent +header extends java/util/EventObject flags 21 + +class name java/awt/desktop/AppForegroundEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/AppForegroundListener +header extends java/lang/Object implements java/awt/desktop/SystemEventListener flags 601 + +class name java/awt/desktop/AppHiddenEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/AppHiddenListener +header extends java/lang/Object implements java/awt/desktop/SystemEventListener flags 601 + +class name java/awt/desktop/AppReopenedEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/AppReopenedListener +header extends java/lang/Object implements java/awt/desktop/SystemEventListener flags 601 + +class name java/awt/desktop/FilesEvent +header extends java/awt/desktop/AppEvent flags 21 + +class name java/awt/desktop/OpenFilesEvent +header extends java/awt/desktop/FilesEvent flags 31 + +class name java/awt/desktop/OpenFilesHandler +header extends java/lang/Object flags 601 + +class name java/awt/desktop/OpenURIEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/OpenURIHandler +header extends java/lang/Object flags 601 + +class name java/awt/desktop/PreferencesEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/PreferencesHandler +header extends java/lang/Object flags 601 + +class name java/awt/desktop/PrintFilesEvent +header extends java/awt/desktop/FilesEvent flags 31 + +class name java/awt/desktop/PrintFilesHandler +header extends java/lang/Object flags 601 + +class name java/awt/desktop/QuitEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/QuitHandler +header extends java/lang/Object flags 601 + +class name java/awt/desktop/QuitResponse +header extends java/lang/Object flags 601 + +class name java/awt/desktop/QuitStrategy +header extends java/lang/Enum flags 4031 signature Ljava/lang/Enum; + +class name java/awt/desktop/ScreenSleepEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/ScreenSleepListener +header extends java/lang/Object implements java/awt/desktop/SystemEventListener flags 601 + +class name java/awt/desktop/SystemEventListener +header extends java/lang/Object implements java/util/EventListener flags 601 + +class name java/awt/desktop/SystemSleepEvent +header extends java/awt/desktop/AppEvent flags 31 + +class name java/awt/desktop/SystemSleepListener +header extends java/lang/Object implements java/awt/desktop/SystemEventListener flags 601 + +class name java/awt/desktop/UserSessionListener +header extends java/lang/Object implements java/awt/desktop/SystemEventListener flags 601 + +class name java/awt/dnd/DragGestureEvent +header extends java/util/EventObject flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name java/awt/dnd/DragGestureRecognizer +header extends java/lang/Object implements java/io/Serializable flags 421 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name java/awt/dnd/DragSource +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/dnd/DropTargetDragEvent +header extends java/awt/dnd/DropTargetEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/dnd/DropTargetDropEvent +header extends java/awt/dnd/DropTargetEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/ActionEvent +header extends java/awt/AWTEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/AdjustmentEvent +header extends java/awt/AWTEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/ComponentEvent +header extends java/awt/AWTEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/ContainerEvent +header extends java/awt/event/ComponentEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/HierarchyEvent +header extends java/awt/AWTEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/InputMethodEvent +header extends java/awt/AWTEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/ItemEvent +header extends java/awt/AWTEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/MouseWheelEvent +header extends java/awt/event/MouseEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/PaintEvent +header extends java/awt/event/ComponentEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/event/WindowEvent +header extends java/awt/event/ComponentEvent flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/font/FontRenderContext +header extends java/lang/Object flags 21 +innerclass innerClass java/awt/RenderingHints$Key outerClass java/awt/RenderingHints innerClassName Key flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/font/GraphicAttribute +header extends java/lang/Object flags 421 +innerclass innerClass java/awt/geom/Rectangle2D$Float outerClass java/awt/geom/Rectangle2D innerClassName Float flags 9 + +class name java/awt/font/ImageGraphicAttribute +header extends java/awt/font/GraphicAttribute flags 31 +innerclass innerClass java/awt/geom/Rectangle2D$Float outerClass java/awt/geom/Rectangle2D innerClassName Float flags 9 + +class name java/awt/font/NumericShaper$Range +header extends java/lang/Enum nestHost java/awt/font/NumericShaper sealed true flags 4021 signature Ljava/lang/Enum; +innerclass innerClass java/awt/font/NumericShaper$Range outerClass java/awt/font/NumericShaper innerClassName Range flags 4009 + +class name java/awt/font/ShapeGraphicAttribute +header extends java/awt/font/GraphicAttribute flags 31 +innerclass innerClass java/awt/geom/Rectangle2D$Float outerClass java/awt/geom/Rectangle2D innerClassName Float flags 9 + +class name java/awt/font/TextHitInfo +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/font/TextMeasurer +header extends java/lang/Object implements java/lang/Cloneable flags 31 +innerclass innerClass java/text/AttributedCharacterIterator$Attribute outerClass java/text/AttributedCharacterIterator innerClassName Attribute flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/geom/AffineTransform +header extends java/lang/Object implements java/lang/Cloneable,java/io/Serializable flags 21 +innerclass innerClass java/awt/geom/Point2D$Double outerClass java/awt/geom/Point2D innerClassName Double flags 9 +innerclass innerClass java/awt/geom/Point2D$Float outerClass java/awt/geom/Point2D innerClassName Float flags 9 +innerclass innerClass java/awt/geom/Path2D$Double outerClass java/awt/geom/Path2D innerClassName Double flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/geom/Area +header extends java/lang/Object implements java/awt/Shape,java/lang/Cloneable flags 21 +innerclass innerClass java/awt/geom/Rectangle2D$Double outerClass java/awt/geom/Rectangle2D innerClassName Double flags 9 + +class name java/awt/geom/RectangularShape +header extends java/lang/Object implements java/awt/Shape,java/lang/Cloneable flags 421 +innerclass innerClass java/awt/geom/Rectangle2D$Double outerClass java/awt/geom/Rectangle2D innerClassName Double flags 9 + +class name java/awt/image/AbstractMultiResolutionImage +header extends java/awt/Image implements java/awt/image/MultiResolutionImage flags 421 + +class name java/awt/image/BandCombineOp +header extends java/lang/Object implements java/awt/image/RasterOp flags 21 +innerclass innerClass java/awt/geom/Point2D$Float outerClass java/awt/geom/Point2D innerClassName Float flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/BandedSampleModel +header extends java/awt/image/ComponentSampleModel flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/BaseMultiResolutionImage +header extends java/awt/image/AbstractMultiResolutionImage flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/BufferedImageFilter +header extends java/awt/image/ImageFilter implements java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/ByteLookupTable +header extends java/awt/image/LookupTable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/ColorConvertOp +header extends java/lang/Object implements java/awt/image/BufferedImageOp,java/awt/image/RasterOp flags 21 +innerclass innerClass java/awt/geom/Point2D$Float outerClass java/awt/geom/Point2D innerClassName Float flags 9 + +class name java/awt/image/ColorModel +-method name finalize descriptor ()V + +class name java/awt/image/ComponentColorModel +header extends java/awt/image/ColorModel flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/ComponentSampleModel +header extends java/awt/image/SampleModel flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/ConvolveOp +header extends java/lang/Object implements java/awt/image/BufferedImageOp,java/awt/image/RasterOp flags 21 +innerclass innerClass java/awt/geom/Point2D$Float outerClass java/awt/geom/Point2D innerClassName Float flags 9 + +class name java/awt/image/DataBufferUShort +header extends java/awt/image/DataBuffer flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/DirectColorModel +header extends java/awt/image/PackedColorModel flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/ImageFilter +header extends java/lang/Object implements java/awt/image/ImageConsumer,java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/IndexColorModel +header extends java/awt/image/ColorModel flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name finalize descriptor ()V + +class name java/awt/image/Kernel +header extends java/lang/Object implements java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/LookupOp +header extends java/lang/Object implements java/awt/image/BufferedImageOp,java/awt/image/RasterOp flags 21 +innerclass innerClass java/awt/geom/Point2D$Float outerClass java/awt/geom/Point2D innerClassName Float flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/MultiPixelPackedSampleModel +header extends java/awt/image/SampleModel flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/MultiResolutionImage +header extends java/lang/Object flags 601 + +class name java/awt/image/PackedColorModel +header extends java/awt/image/ColorModel flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/Raster +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/ReplicateScaleFilter +header extends java/awt/image/ImageFilter flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/RescaleOp +header extends java/lang/Object implements java/awt/image/BufferedImageOp,java/awt/image/RasterOp flags 21 +innerclass innerClass java/awt/geom/Point2D$Float outerClass java/awt/geom/Point2D innerClassName Float flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/SampleModel +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/ShortLookupTable +header extends java/awt/image/LookupTable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/image/SinglePixelPackedSampleModel +header extends java/awt/image/SampleModel flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/awt/print/Paper +header extends java/lang/Object implements java/lang/Cloneable flags 21 +innerclass innerClass java/awt/geom/Rectangle2D$Double outerClass java/awt/geom/Rectangle2D innerClassName Double flags 9 + +class name java/beans/BeanProperty +header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 runtimeAnnotations @Ljava/lang/annotation/Documented;@Ljava/lang/annotation/Target;(value={eLjava/lang/annotation/ElementType;METHOD;})@Ljava/lang/annotation/Retention;(value=eLjava/lang/annotation/RetentionPolicy;RUNTIME;) + +class name java/beans/Beans +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/beans/DefaultPersistenceDelegate +header extends java/beans/PersistenceDelegate flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/beans/Encoder +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/beans/EventSetDescriptor +header extends java/beans/FeatureDescriptor flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/beans/Expression +header extends java/beans/Statement flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/beans/FeatureDescriptor +header extends java/lang/Object flags 21 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 + +class name java/beans/IndexedPropertyDescriptor +header extends java/beans/PropertyDescriptor flags 21 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/beans/JavaBean +header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 runtimeAnnotations @Ljava/lang/annotation/Documented;@Ljava/lang/annotation/Target;(value={eLjava/lang/annotation/ElementType;TYPE;})@Ljava/lang/annotation/Retention;(value=eLjava/lang/annotation/RetentionPolicy;RUNTIME;) + +class name java/beans/PropertyDescriptor +header extends java/beans/FeatureDescriptor flags 21 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/beans/SimpleBeanInfo +header extends java/lang/Object implements java/beans/BeanInfo flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/accessibility/AccessibilityProvider +header extends java/lang/Object flags 421 + +class name javax/accessibility/AccessibleBundle +header extends java/lang/Object flags 421 classAnnotations @Ljdk/Profile+Annotation;(value=I4) + +class name javax/accessibility/AccessibleRelationSet +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/accessibility/AccessibleStateSet +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/imageio/metadata/IIOMetadata +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/imageio/plugins/jpeg/JPEGHuffmanTable +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/imageio/plugins/jpeg/JPEGQTable +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/imageio/plugins/tiff/TIFFDirectory +header extends java/lang/Object implements java/lang/Cloneable flags 21 + +class name javax/imageio/plugins/tiff/TIFFField +header extends java/lang/Object implements java/lang/Cloneable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/imageio/plugins/tiff/TIFFImageReadParam +header extends javax/imageio/ImageReadParam flags 31 + +class name javax/imageio/plugins/tiff/TIFFTag +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/imageio/plugins/tiff/TIFFTagSet +header extends java/lang/Object flags 21 + +class name javax/imageio/spi/ImageReaderWriterSpi +header extends javax/imageio/spi/IIOServiceProvider flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/imageio/spi/ServiceRegistry +-method name finalize descriptor ()V +method name finalize descriptor ()V thrownTypes java/lang/Throwable flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name javax/imageio/stream/FileCacheImageInputStream +-method name finalize descriptor ()V +method name finalize descriptor ()V thrownTypes java/lang/Throwable flags 4 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name javax/imageio/stream/FileImageInputStream +-method name finalize descriptor ()V +method name finalize descriptor ()V thrownTypes java/lang/Throwable flags 4 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name javax/imageio/stream/FileImageOutputStream +-method name finalize descriptor ()V +method name finalize descriptor ()V thrownTypes java/lang/Throwable flags 4 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name javax/imageio/stream/ImageInputStreamImpl +-method name finalize descriptor ()V +method name finalize descriptor ()V thrownTypes java/lang/Throwable flags 4 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name javax/imageio/stream/MemoryCacheImageInputStream +-method name finalize descriptor ()V +method name finalize descriptor ()V thrownTypes java/lang/Throwable flags 4 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="9") + +class name javax/print/attribute/DateTimeSyntax +header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/print/attribute/EnumSyntax +header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/print/attribute/IntegerSyntax +header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/print/attribute/standard/MediaPrintableArea +header extends java/lang/Object implements javax/print/attribute/DocAttribute,javax/print/attribute/PrintRequestAttribute,javax/print/attribute/PrintJobAttribute flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/print/event/PrintEvent +header extends java/util/EventObject flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sound/midi/MetaMessage +header extends javax/sound/midi/MidiMessage flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sound/midi/MidiMessage +header extends java/lang/Object implements java/lang/Cloneable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sound/midi/Sequence +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sound/midi/ShortMessage +header extends javax/sound/midi/MidiMessage flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sound/midi/SysexMessage +header extends javax/sound/midi/MidiMessage flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sound/sampled/ReverbType +header extends java/lang/Object flags 21 classAnnotations @Ljdk/Profile+Annotation;(value=I4) + +class name javax/sound/sampled/spi/FormatConversionProvider +header extends java/lang/Object flags 421 +innerclass innerClass javax/sound/sampled/AudioFormat$Encoding outerClass javax/sound/sampled/AudioFormat innerClassName Encoding flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/BoxLayout +header extends java/lang/Object implements java/awt/LayoutManager2,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/DebugGraphics +header extends java/awt/Graphics flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/DefaultBoundedRangeModel +header extends java/lang/Object implements javax/swing/BoundedRangeModel,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/DefaultListSelectionModel +header extends java/lang/Object implements javax/swing/ListSelectionModel,java/lang/Cloneable,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/GrayFilter +header extends java/awt/image/RGBImageFilter flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/GroupLayout +header extends java/lang/Object implements java/awt/LayoutManager2 nestMembers javax/swing/GroupLayout$ParallelGroup,javax/swing/GroupLayout$SequentialGroup,javax/swing/GroupLayout$Group,javax/swing/GroupLayout$Spring,javax/swing/GroupLayout$Alignment flags 21 +innerclass innerClass javax/swing/GroupLayout$Alignment outerClass javax/swing/GroupLayout innerClassName Alignment flags 4019 +innerclass innerClass javax/swing/GroupLayout$ParallelGroup outerClass javax/swing/GroupLayout innerClassName ParallelGroup flags 1 +innerclass innerClass javax/swing/GroupLayout$Group outerClass javax/swing/GroupLayout innerClassName Group flags 401 +innerclass innerClass javax/swing/GroupLayout$SequentialGroup outerClass javax/swing/GroupLayout innerClassName SequentialGroup flags 1 +innerclass innerClass javax/swing/GroupLayout$Spring outerClass javax/swing/GroupLayout innerClassName Spring flags 40a +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/GroupLayout$Group +header extends javax/swing/GroupLayout$Spring nestHost javax/swing/GroupLayout flags 421 +innerclass innerClass javax/swing/GroupLayout$Group outerClass javax/swing/GroupLayout innerClassName Group flags 401 +innerclass innerClass javax/swing/GroupLayout$Spring outerClass javax/swing/GroupLayout innerClassName Spring flags 40a + +class name javax/swing/GroupLayout$ParallelGroup +header extends javax/swing/GroupLayout$Group nestHost javax/swing/GroupLayout flags 21 +innerclass innerClass javax/swing/GroupLayout$ParallelGroup outerClass javax/swing/GroupLayout innerClassName ParallelGroup flags 1 +innerclass innerClass javax/swing/GroupLayout$Group outerClass javax/swing/GroupLayout innerClassName Group flags 401 +innerclass innerClass javax/swing/GroupLayout$Alignment outerClass javax/swing/GroupLayout innerClassName Alignment flags 4019 +innerclass innerClass javax/swing/GroupLayout$Spring outerClass javax/swing/GroupLayout innerClassName Spring flags 40a + +class name javax/swing/GroupLayout$SequentialGroup +header extends javax/swing/GroupLayout$Group nestHost javax/swing/GroupLayout flags 21 +innerclass innerClass javax/swing/GroupLayout$SequentialGroup outerClass javax/swing/GroupLayout innerClassName SequentialGroup flags 1 +innerclass innerClass javax/swing/GroupLayout$Group outerClass javax/swing/GroupLayout innerClassName Group flags 401 +innerclass innerClass javax/swing/GroupLayout$Spring outerClass javax/swing/GroupLayout innerClassName Spring flags 40a +innerclass innerClass javax/swing/LayoutStyle$ComponentPlacement outerClass javax/swing/LayoutStyle innerClassName ComponentPlacement flags 4019 +innerclass innerClass java/awt/Component$BaselineResizeBehavior outerClass java/awt/Component innerClassName BaselineResizeBehavior flags 4019 + +class name javax/swing/GroupLayout$Spring +header extends java/lang/Object nestHost javax/swing/GroupLayout flags 420 +innerclass innerClass javax/swing/GroupLayout$Spring outerClass javax/swing/GroupLayout innerClassName Spring flags 40a +innerclass innerClass javax/swing/GroupLayout$Alignment outerClass javax/swing/GroupLayout innerClassName Alignment flags 4019 +innerclass innerClass java/awt/Component$BaselineResizeBehavior outerClass java/awt/Component innerClassName BaselineResizeBehavior flags 4019 + +class name javax/swing/JList$AccessibleJList$AccessibleJListChild +-method name getAccessibleAction descriptor ()Ljavax/accessibility/AccessibleAction; +method name getAccessibleAction descriptor ()Ljavax/accessibility/AccessibleAction; flags 1 + +class name javax/swing/JTextPane +header extends javax/swing/JEditorPane flags 21 runtimeAnnotations @Ljava/beans/JavaBean;(description="A\u005C;u0020;text\u005C;u0020;component\u005C;u0020;that\u005C;u0020;can\u005C;u0020;be\u005C;u0020;marked\u005C;u0020;up\u005C;u0020;with\u005C;u0020;attributes\u005C;u0020;that\u005C;u0020;are\u005C;u0020;graphically\u005C;u0020;represented.")@Ljavax/swing/SwingContainer; + +class name javax/swing/LookAndFeel +header extends java/lang/Object flags 421 +innerclass innerClass javax/swing/text/JTextComponent$KeyBinding outerClass javax/swing/text/JTextComponent innerClassName KeyBinding flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/MenuSelectionManager +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/SizeRequirements +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/SortingFocusTraversalPolicy +header extends javax/swing/InternalFrameFocusTraversalPolicy flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/SwingContainer +header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 runtimeAnnotations @Ljava/lang/annotation/Target;(value={eLjava/lang/annotation/ElementType;TYPE;})@Ljava/lang/annotation/Retention;(value=eLjava/lang/annotation/RetentionPolicy;RUNTIME;) + +class name javax/swing/UIClientPropertyKey +header extends java/lang/Object flags 601 + +class name javax/swing/border/LineBorder +header extends javax/swing/border/AbstractBorder flags 21 +innerclass innerClass java/awt/geom/RoundRectangle2D$Float outerClass java/awt/geom/RoundRectangle2D innerClassName Float flags 9 +innerclass innerClass java/awt/geom/Rectangle2D$Float outerClass java/awt/geom/Rectangle2D innerClassName Float flags 9 +innerclass innerClass java/awt/geom/Path2D$Float outerClass java/awt/geom/Path2D innerClassName Float flags 9 + +class name javax/swing/event/EventListenerList +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/event/ListDataEvent +header extends java/util/EventObject flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/event/ListSelectionEvent +header extends java/util/EventObject flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/event/TreeModelEvent +header extends java/util/EventObject flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/filechooser/FileNameExtensionFilter +header extends javax/swing/filechooser/FileFilter flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/basic/BasicArrowButton +header extends javax/swing/JButton implements javax/swing/SwingConstants flags 21 +innerclass innerClass java/awt/geom/Path2D$Double outerClass java/awt/geom/Path2D innerClassName Double flags 9 + +class name javax/swing/plaf/basic/BasicButtonUI +header extends javax/swing/plaf/ButtonUI flags 21 +innerclass innerClass java/awt/Component$BaselineResizeBehavior outerClass java/awt/Component innerClassName BaselineResizeBehavior flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/basic/BasicPasswordFieldUI +header extends javax/swing/plaf/basic/BasicTextFieldUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/basic/BasicSplitPaneUI$BasicVerticalLayoutManager +header extends javax/swing/plaf/basic/BasicSplitPaneUI$BasicHorizontalLayoutManager nestHost javax/swing/plaf/basic/BasicSplitPaneUI flags 21 +innerclass innerClass javax/swing/plaf/basic/BasicSplitPaneUI$BasicHorizontalLayoutManager outerClass javax/swing/plaf/basic/BasicSplitPaneUI innerClassName BasicHorizontalLayoutManager flags 1 +innerclass innerClass javax/swing/plaf/basic/BasicSplitPaneUI$BasicVerticalLayoutManager outerClass javax/swing/plaf/basic/BasicSplitPaneUI innerClassName BasicVerticalLayoutManager flags 1 + +class name javax/swing/plaf/basic/BasicToolBarSeparatorUI +header extends javax/swing/plaf/basic/BasicSeparatorUI flags 21 +innerclass innerClass javax/swing/JToolBar$Separator outerClass javax/swing/JToolBar innerClassName Separator flags 9 + +class name javax/swing/plaf/metal/MetalButtonUI +header extends javax/swing/plaf/basic/BasicButtonUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/metal/MetalCheckBoxUI +header extends javax/swing/plaf/metal/MetalRadioButtonUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/metal/MetalRadioButtonUI +header extends javax/swing/plaf/basic/BasicRadioButtonUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/metal/MetalTabbedPaneUI$TabbedPaneLayout +header extends javax/swing/plaf/basic/BasicTabbedPaneUI$TabbedPaneLayout nestHost javax/swing/plaf/metal/MetalTabbedPaneUI flags 21 +innerclass innerClass javax/swing/plaf/basic/BasicTabbedPaneUI$TabbedPaneLayout outerClass javax/swing/plaf/basic/BasicTabbedPaneUI innerClassName TabbedPaneLayout flags 1 +innerclass innerClass javax/swing/plaf/metal/MetalTabbedPaneUI$TabbedPaneLayout outerClass javax/swing/plaf/metal/MetalTabbedPaneUI innerClassName TabbedPaneLayout flags 1 + +class name javax/swing/plaf/metal/MetalToggleButtonUI +header extends javax/swing/plaf/basic/BasicToggleButtonUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/metal/MetalToolBarUI$MetalContainerListener +header extends javax/swing/plaf/basic/BasicToolBarUI$ToolBarContListener nestHost javax/swing/plaf/metal/MetalToolBarUI flags 21 +innerclass innerClass javax/swing/plaf/basic/BasicToolBarUI$ToolBarContListener outerClass javax/swing/plaf/basic/BasicToolBarUI innerClassName ToolBarContListener flags 4 +innerclass innerClass javax/swing/plaf/metal/MetalToolBarUI$MetalContainerListener outerClass javax/swing/plaf/metal/MetalToolBarUI innerClassName MetalContainerListener flags 4 + +class name javax/swing/plaf/metal/MetalToolBarUI$MetalRolloverListener +header extends javax/swing/plaf/basic/BasicToolBarUI$PropertyListener nestHost javax/swing/plaf/metal/MetalToolBarUI flags 21 +innerclass innerClass javax/swing/plaf/basic/BasicToolBarUI$PropertyListener outerClass javax/swing/plaf/basic/BasicToolBarUI innerClassName PropertyListener flags 4 +innerclass innerClass javax/swing/plaf/metal/MetalToolBarUI$MetalRolloverListener outerClass javax/swing/plaf/metal/MetalToolBarUI innerClassName MetalRolloverListener flags 4 + +class name javax/swing/plaf/metal/MetalToolTipUI +header extends javax/swing/plaf/basic/BasicToolTipUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/multi/MultiLookAndFeel +header extends javax/swing/LookAndFeel flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/synth/SynthButtonUI +header extends javax/swing/plaf/basic/BasicButtonUI implements java/beans/PropertyChangeListener,javax/swing/plaf/synth/SynthUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/synth/SynthIcon +header extends java/lang/Object implements javax/swing/Icon flags 601 + +class name javax/swing/plaf/synth/SynthMenuItemUI +header extends javax/swing/plaf/basic/BasicMenuItemUI implements java/beans/PropertyChangeListener,javax/swing/plaf/synth/SynthUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/synth/SynthMenuUI +header extends javax/swing/plaf/basic/BasicMenuUI implements java/beans/PropertyChangeListener,javax/swing/plaf/synth/SynthUI flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/plaf/synth/SynthSeparatorUI +header extends javax/swing/plaf/SeparatorUI implements java/beans/PropertyChangeListener,javax/swing/plaf/synth/SynthUI flags 21 +innerclass innerClass javax/swing/JToolBar$Separator outerClass javax/swing/JToolBar innerClassName Separator flags 9 + +class name javax/swing/plaf/synth/SynthStyle +header extends java/lang/Object flags 421 +innerclass innerClass javax/swing/UIDefaults$LazyInputMap outerClass javax/swing/UIDefaults innerClassName LazyInputMap flags 9 +innerclass innerClass javax/swing/UIDefaults$LazyValue outerClass javax/swing/UIDefaults innerClassName LazyValue flags 609 + +class name javax/swing/table/AbstractTableModel +header extends java/lang/Object implements javax/swing/table/TableModel,java/io/Serializable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/AbstractWriter +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/BoxView +header extends javax/swing/text/CompositeView flags 21 +innerclass innerClass javax/swing/event/DocumentEvent$ElementChange outerClass javax/swing/event/DocumentEvent innerClassName ElementChange flags 609 +innerclass innerClass javax/swing/text/Position$Bias outerClass javax/swing/text/Position innerClassName Bias flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/CompositeView +header extends javax/swing/text/View flags 421 +innerclass innerClass javax/swing/text/Position$Bias outerClass javax/swing/text/Position innerClassName Bias flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/DateFormatter +header extends javax/swing/text/InternationalFormatter flags 21 +innerclass innerClass java/text/DateFormat$Field outerClass java/text/DateFormat innerClassName Field flags 9 + +class name javax/swing/text/IconView +header extends javax/swing/text/View flags 21 +innerclass innerClass javax/swing/text/Position$Bias outerClass javax/swing/text/Position innerClassName Bias flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/LayoutQueue +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/NumberFormatter +header extends javax/swing/text/InternationalFormatter flags 21 +innerclass innerClass java/text/NumberFormat$Field outerClass java/text/NumberFormat innerClassName Field flags 9 +innerclass innerClass javax/swing/text/DocumentFilter$FilterBypass outerClass javax/swing/text/DocumentFilter innerClassName FilterBypass flags 409 +innerclass innerClass java/text/AttributedCharacterIterator$Attribute outerClass java/text/AttributedCharacterIterator innerClassName Attribute flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/Segment +header extends java/lang/Object implements java/lang/Cloneable,java/text/CharacterIterator,java/lang/CharSequence flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/TabSet +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/TabStop +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/View +header extends java/lang/Object implements javax/swing/SwingConstants flags 421 +innerclass innerClass javax/swing/text/Position$Bias outerClass javax/swing/text/Position innerClassName Bias flags 19 +innerclass innerClass javax/swing/event/DocumentEvent$ElementChange outerClass javax/swing/event/DocumentEvent innerClassName ElementChange flags 609 +innerclass innerClass javax/swing/event/DocumentEvent$EventType outerClass javax/swing/event/DocumentEvent innerClassName EventType flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/html/InlineView +header extends javax/swing/text/LabelView flags 21 +innerclass innerClass javax/swing/text/html/CSS$Attribute outerClass javax/swing/text/html/CSS innerClassName Attribute flags 19 + +class name javax/swing/text/html/ListView +header extends javax/swing/text/html/BlockView flags 21 +innerclass innerClass javax/swing/text/html/StyleSheet$ListPainter outerClass javax/swing/text/html/StyleSheet innerClassName ListPainter flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/html/MinimalHTMLWriter +header extends javax/swing/text/AbstractWriter flags 21 +innerclass innerClass javax/swing/text/StyleConstants$ParagraphConstants outerClass javax/swing/text/StyleConstants innerClassName ParagraphConstants flags 9 +innerclass innerClass javax/swing/text/StyleConstants$CharacterConstants outerClass javax/swing/text/StyleConstants innerClassName CharacterConstants flags 9 +innerclass innerClass javax/swing/text/StyleConstants$FontConstants outerClass javax/swing/text/StyleConstants innerClassName FontConstants flags 9 +innerclass innerClass javax/swing/text/StyleConstants$ColorConstants outerClass javax/swing/text/StyleConstants innerClassName ColorConstants flags 9 +innerclass innerClass javax/swing/text/AbstractDocument$BranchElement outerClass javax/swing/text/AbstractDocument innerClassName BranchElement flags 1 +innerclass innerClass javax/swing/text/StyleContext$NamedStyle outerClass javax/swing/text/StyleContext innerClassName NamedStyle flags 1 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/html/ObjectView +header extends javax/swing/text/ComponentView flags 21 +innerclass innerClass javax/swing/text/html/HTML$Attribute outerClass javax/swing/text/html/HTML innerClassName Attribute flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/html/Option +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass javax/swing/text/html/HTML$Attribute outerClass javax/swing/text/html/HTML innerClassName Attribute flags 19 + +class name javax/swing/text/html/ParagraphView +header extends javax/swing/text/ParagraphView flags 21 +innerclass innerClass javax/swing/text/html/StyleSheet$BoxPainter outerClass javax/swing/text/html/StyleSheet innerClassName BoxPainter flags 9 +innerclass innerClass javax/swing/text/html/CSS$Attribute outerClass javax/swing/text/html/CSS innerClassName Attribute flags 19 + +class name javax/swing/text/html/parser/ContentModel +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/html/parser/DocumentParser +header extends javax/swing/text/html/parser/Parser flags 21 +innerclass innerClass javax/swing/text/html/HTMLEditorKit$ParserCallback outerClass javax/swing/text/html/HTMLEditorKit innerClassName ParserCallback flags 9 +innerclass innerClass javax/swing/text/html/HTML$Tag outerClass javax/swing/text/html/HTML innerClassName Tag flags 9 +innerclass innerClass javax/swing/text/html/HTML$Attribute outerClass javax/swing/text/html/HTML innerClassName Attribute flags 19 + +class name javax/swing/text/html/parser/Parser +header extends java/lang/Object implements javax/swing/text/html/parser/DTDConstants flags 21 +innerclass innerClass javax/swing/text/html/HTML$Attribute outerClass javax/swing/text/html/HTML innerClassName Attribute flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/text/html/parser/TagElement +header extends java/lang/Object flags 21 +innerclass innerClass javax/swing/text/html/HTML$Tag outerClass javax/swing/text/html/HTML innerClassName Tag flags 9 +innerclass innerClass javax/swing/text/html/HTML$UnknownTag outerClass javax/swing/text/html/HTML innerClassName UnknownTag flags 9 + +class name javax/swing/tree/DefaultTreeModel +header extends java/lang/Object implements java/io/Serializable,javax/swing/tree/TreeModel flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name javax/swing/tree/DefaultTreeSelectionModel +header extends java/lang/Object implements java/lang/Cloneable,java/io/Serializable,javax/swing/tree/TreeSelectionModel flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/tree/TreePath +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/undo/AbstractUndoableEdit +header extends java/lang/Object implements javax/swing/undo/UndoableEdit,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/undo/CompoundEdit +header extends javax/swing/undo/AbstractUndoableEdit flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/swing/undo/UndoableEditSupport +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.instrument-I.sym.txt b/make/data/symbols/java.instrument-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..9f7539e822613fcf2d4f82865bfa24fdbd5add3f --- /dev/null +++ b/make/data/symbols/java.instrument-I.sym.txt @@ -0,0 +1,31 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/lang/instrument/UnmodifiableModuleException +header extends java/lang/RuntimeException flags 21 + diff --git a/make/data/symbols/java.logging-I.sym.txt b/make/data/symbols/java.logging-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..0c5aabcc4bb913e7a9243924fb88f58bebf52876 --- /dev/null +++ b/make/data/symbols/java.logging-I.sym.txt @@ -0,0 +1,55 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/util/logging/ErrorManager +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/logging/LoggingMXBean +header extends java/lang/Object flags 601 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/util/logging/LoggingPermission +header extends java/security/BasicPermission flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/logging/MemoryHandler +header extends java/util/logging/Handler flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/logging/SimpleFormatter +header extends java/util/logging/Formatter flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/logging/SocketHandler +header extends java/util/logging/StreamHandler flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/logging/XMLFormatter +header extends java/util/logging/Formatter flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.management-I.sym.txt b/make/data/symbols/java.management-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..ae261e32e0c9f49286e1f3aff065ff916b0bc286 --- /dev/null +++ b/make/data/symbols/java.management-I.sym.txt @@ -0,0 +1,269 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/lang/management/LockInfo +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/management/ManagementPermission +header extends java/security/BasicPermission flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/management/MemoryMXBean +-method name getObjectPendingFinalizationCount descriptor ()I +method name getObjectPendingFinalizationCount descriptor ()I flags 401 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="18") + +class name java/lang/management/MemoryUsage +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/management/MonitorInfo +header extends java/lang/management/LockInfo flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/management/RuntimeMXBean +header extends java/lang/Object implements java/lang/management/PlatformManagedObject flags 601 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/Attribute +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/AttributeList +header extends java/util/ArrayList flags 21 signature Ljava/util/ArrayList; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/BadAttributeValueExpException +header extends java/lang/Exception flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/BadBinaryOpValueExpException +header extends java/lang/Exception flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/BadStringOperationException +header extends java/lang/Exception flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/ConstructorParameters +header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 runtimeAnnotations @Ljava/lang/annotation/Documented;@Ljava/lang/annotation/Target;(value={eLjava/lang/annotation/ElementType;CONSTRUCTOR;})@Ljava/lang/annotation/Retention;(value=eLjava/lang/annotation/RetentionPolicy;RUNTIME;) + +class name javax/management/ImmutableDescriptor +header extends java/lang/Object implements javax/management/Descriptor flags 21 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanAttributeInfo +header extends javax/management/MBeanFeatureInfo implements java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanConstructorInfo +header extends javax/management/MBeanFeatureInfo implements java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanNotificationInfo +header extends javax/management/MBeanFeatureInfo implements java/lang/Cloneable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanOperationInfo +header extends javax/management/MBeanFeatureInfo implements java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanParameterInfo +header extends javax/management/MBeanFeatureInfo implements java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanPermission +header extends java/security/Permission flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanServerDelegate +header extends java/lang/Object implements javax/management/MBeanServerDelegateMBean,javax/management/NotificationEmitter flags 21 +innerclass innerClass java/lang/System$Logger outerClass java/lang/System innerClassName Logger flags 609 +innerclass innerClass java/lang/System$Logger$Level outerClass java/lang/System$Logger innerClassName Level flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanServerFactory +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/System$Logger outerClass java/lang/System innerClassName Logger flags 609 +innerclass innerClass java/lang/System$Logger$Level outerClass java/lang/System$Logger innerClassName Level flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanServerInvocationHandler +header extends java/lang/Object implements java/lang/reflect/InvocationHandler flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanServerNotification +header extends javax/management/Notification flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanServerPermission +header extends java/security/BasicPermission flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanTrustPermission +header extends java/security/BasicPermission flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/Notification +header extends java/util/EventObject flags 21 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/ObjectInstance +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/Query +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/StandardEmitterMBean +header extends javax/management/StandardMBean implements javax/management/NotificationEmitter flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/StringValueExp +header extends java/lang/Object implements javax/management/ValueExp flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/loading/DefaultLoaderRepository +header extends java/lang/Object flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated; +innerclass innerClass java/lang/System$Logger outerClass java/lang/System innerClassName Logger flags 609 +innerclass innerClass java/lang/System$Logger$Level outerClass java/lang/System$Logger innerClassName Level flags 4019 + +class name javax/management/loading/MLetContent +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/modelmbean/InvalidTargetObjectTypeException +header extends java/lang/Exception flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/modelmbean/XMLParseException +header extends java/lang/Exception flags 21 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/ArrayType +header extends javax/management/openmbean/OpenType flags 21 signature Ljavax/management/openmbean/OpenType; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/CompositeDataInvocationHandler +header extends java/lang/Object implements java/lang/reflect/InvocationHandler flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/CompositeDataSupport +header extends java/lang/Object implements javax/management/openmbean/CompositeData,java/io/Serializable flags 21 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/CompositeType +header extends javax/management/openmbean/OpenType flags 21 signature Ljavax/management/openmbean/OpenType; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/OpenMBeanAttributeInfoSupport +header extends javax/management/MBeanAttributeInfo implements javax/management/openmbean/OpenMBeanAttributeInfo flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/OpenMBeanOperationInfoSupport +header extends javax/management/MBeanOperationInfo implements javax/management/openmbean/OpenMBeanOperationInfo flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/SimpleType +header extends javax/management/openmbean/OpenType flags 31 signature Ljavax/management/openmbean/OpenType; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/TabularDataSupport +header extends java/lang/Object implements javax/management/openmbean/TabularData,java/util/Map,java/lang/Cloneable,java/io/Serializable flags 21 signature Ljava/lang/Object;Ljavax/management/openmbean/TabularData;Ljava/util/Map;Ljava/lang/Cloneable;Ljava/io/Serializable; +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/openmbean/TabularType +header extends javax/management/openmbean/OpenType flags 21 signature Ljavax/management/openmbean/OpenType; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/relation/RelationNotification +header extends javax/management/Notification flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 + +class name javax/management/relation/RelationSupport +header extends java/lang/Object implements javax/management/relation/RelationSupportMBean,javax/management/MBeanRegistration flags 21 +innerclass innerClass java/lang/System$Logger outerClass java/lang/System innerClassName Logger flags 609 +innerclass innerClass java/lang/System$Logger$Level outerClass java/lang/System$Logger innerClassName Level flags 4019 + +class name javax/management/relation/Role +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/relation/RoleInfo +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/relation/RoleResult +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 + +class name javax/management/relation/RoleUnresolved +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/remote/JMXConnectorServerFactory +header extends java/lang/Object flags 21 +innerclass innerClass java/util/ServiceLoader$Provider outerClass java/util/ServiceLoader innerClassName Provider flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/remote/JMXPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/remote/JMXServiceURL +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/remote/NotificationResult +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/remote/TargetedNotification +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.management.rmi-I.sym.txt b/make/data/symbols/java.management.rmi-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..18477d6862fb9b090aa665edc321161a80ec44a0 --- /dev/null +++ b/make/data/symbols/java.management.rmi-I.sym.txt @@ -0,0 +1,39 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/management/remote/rmi/RMIConnectorServer +header extends javax/management/remote/JMXConnectorServer flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/remote/rmi/RMIIIOPServerImpl +header extends javax/management/remote/rmi/RMIServerImpl flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated; + +class name javax/management/remote/rmi/RMIServerImpl +header extends java/lang/Object implements java/io/Closeable,javax/management/remote/rmi/RMIServer flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.naming-I.sym.txt b/make/data/symbols/java.naming-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..f913ec6f184bff2d13a5184d6b1f445ca38c21f9 --- /dev/null +++ b/make/data/symbols/java.naming-I.sym.txt @@ -0,0 +1,76 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/naming/BinaryRefAddr +header extends javax/naming/RefAddr flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/Binding +header extends javax/naming/NameClassPair flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/CompositeName +header extends java/lang/Object implements javax/naming/Name flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/CompoundName +header extends java/lang/Object implements javax/naming/Name flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/LinkException +header extends javax/naming/NamingException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/NameClassPair +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/NamingException +header extends java/lang/Exception flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/RefAddr +header extends java/lang/Object implements java/io/Serializable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/Reference +header extends java/lang/Object implements java/lang/Cloneable,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/directory/AttributeModificationException +header extends javax/naming/NamingException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/directory/ModificationItem +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/naming/directory/SearchResult +header extends javax/naming/Binding flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.net.http-I.sym.txt b/make/data/symbols/java.net.http-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..718ae0a2c6f76482ce71f02b3c3edaff5b9f3985 --- /dev/null +++ b/make/data/symbols/java.net.http-I.sym.txt @@ -0,0 +1,36 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/net/http/HttpRequest$Builder +header extends java/lang/Object nestHost java/net/http/HttpRequest flags 601 +innerclass innerClass java/net/http/HttpRequest$BodyPublishers outerClass java/net/http/HttpRequest innerClassName BodyPublishers flags 9 +innerclass innerClass java/net/http/HttpRequest$BodyPublisher outerClass java/net/http/HttpRequest innerClassName BodyPublisher flags 609 +innerclass innerClass java/net/http/HttpRequest$Builder outerClass java/net/http/HttpRequest innerClassName Builder flags 609 +innerclass innerClass java/net/http/HttpClient$Version outerClass java/net/http/HttpClient innerClassName Version flags 4019 +method name HEAD descriptor ()Ljava/net/http/HttpRequest$Builder; flags 1 + diff --git a/make/data/symbols/java.rmi-I.sym.txt b/make/data/symbols/java.rmi-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..9e577bb975ca0af4c80ecef1dfe574adc436a551 --- /dev/null +++ b/make/data/symbols/java.rmi-I.sym.txt @@ -0,0 +1,52 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/rmi/RemoteException +header extends java/io/IOException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/rmi/dgc/VMID +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/rmi/server/ObjID +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/rmi/server/RemoteObject +header extends java/lang/Object implements java/rmi/Remote,java/io/Serializable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/rmi/server/ServerCloneException +header extends java/lang/CloneNotSupportedException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/rmi/server/UID +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.scripting-I.sym.txt b/make/data/symbols/java.scripting-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..661fc972e825f36a278c3e0187ba52bb7081d418 --- /dev/null +++ b/make/data/symbols/java.scripting-I.sym.txt @@ -0,0 +1,32 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/script/ScriptException +header extends java/lang/Exception flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.security.jgss-I.sym.txt b/make/data/symbols/java.security.jgss-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..6af48bfea4aeade47ff8c10898c1e6fa0e175929 --- /dev/null +++ b/make/data/symbols/java.security.jgss-I.sym.txt @@ -0,0 +1,69 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/security/auth/kerberos/DelegationPermission +header extends java/security/BasicPermission implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/security/auth/kerberos/EncryptionKey +header extends java/lang/Object implements javax/crypto/SecretKey flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/security/auth/kerberos/KerberosCredMessage +header extends java/lang/Object implements javax/security/auth/Destroyable flags 31 +innerclass innerClass java/util/Base64$Encoder outerClass java/util/Base64 innerClassName Encoder flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/security/auth/kerberos/KerberosKey +header extends java/lang/Object implements javax/crypto/SecretKey flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/security/auth/kerberos/KerberosPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/security/auth/kerberos/KerberosTicket +header extends java/lang/Object implements javax/security/auth/Destroyable,javax/security/auth/Refreshable,java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/security/auth/kerberos/KeyTab +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/security/auth/kerberos/ServicePermission +header extends java/security/Permission implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name org/ietf/jgss/GSSException +header extends java/lang/Exception flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name org/ietf/jgss/Oid +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.security.sasl-I.sym.txt b/make/data/symbols/java.security.sasl-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..37bab20606abb562b3f564e30882c5359b873e18 --- /dev/null +++ b/make/data/symbols/java.security.sasl-I.sym.txt @@ -0,0 +1,32 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/security/sasl/SaslException +header extends java/io/IOException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.smartcardio-I.sym.txt b/make/data/symbols/java.smartcardio-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..63ca75a641ec247e8ab443d4c1d5faf1d5467e72 --- /dev/null +++ b/make/data/symbols/java.smartcardio-I.sym.txt @@ -0,0 +1,62 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/smartcardio/ATR +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/smartcardio/Card +header extends java/lang/Object flags 421 + +class name javax/smartcardio/CardChannel +header extends java/lang/Object flags 421 + +class name javax/smartcardio/CardException +header extends java/lang/Exception flags 21 + +class name javax/smartcardio/CardNotPresentException +header extends javax/smartcardio/CardException flags 21 + +class name javax/smartcardio/CardPermission +header extends java/security/Permission flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/smartcardio/CardTerminal +header extends java/lang/Object flags 421 + +class name javax/smartcardio/CommandAPDU +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/smartcardio/ResponseAPDU +header extends java/lang/Object implements java/io/Serializable flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/smartcardio/TerminalFactorySpi +header extends java/lang/Object flags 421 + diff --git a/make/data/symbols/java.sql-I.sym.txt b/make/data/symbols/java.sql-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..16586cf28ca2f5c4ffe01573f07f48fe1e7c19c4 --- /dev/null +++ b/make/data/symbols/java.sql-I.sym.txt @@ -0,0 +1,60 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/sql/BatchUpdateException +header extends java/sql/SQLException flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 + +class name java/sql/ConnectionBuilder +header extends java/lang/Object flags 601 + +class name java/sql/JDBCType +header extends java/lang/Enum implements java/sql/SQLType flags 4031 signature Ljava/lang/Enum;Ljava/sql/SQLType; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/sql/SQLWarning +header extends java/sql/SQLException flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/sql/ShardingKey +header extends java/lang/Object flags 601 + +class name java/sql/ShardingKeyBuilder +header extends java/lang/Object flags 601 + +class name java/sql/Statement +header extends java/lang/Object implements java/sql/Wrapper,java/lang/AutoCloseable flags 601 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sql/PooledConnectionBuilder +header extends java/lang/Object flags 601 + +class name javax/sql/XAConnectionBuilder +header extends java/lang/Object flags 601 + diff --git a/make/data/symbols/java.sql.rowset-I.sym.txt b/make/data/symbols/java.sql.rowset-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..ea90b56bbc7363c76ad0b788b4b91bc1c0f69b41 --- /dev/null +++ b/make/data/symbols/java.sql.rowset-I.sym.txt @@ -0,0 +1,69 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/sql/rowset/BaseRowSet +header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sql/rowset/serial/SerialArray +header extends java/lang/Object implements java/sql/Array,java/io/Serializable,java/lang/Cloneable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 + +class name javax/sql/rowset/serial/SerialBlob +header extends java/lang/Object implements java/sql/Blob,java/io/Serializable,java/lang/Cloneable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 + +class name javax/sql/rowset/serial/SerialClob +header extends java/lang/Object implements java/sql/Clob,java/io/Serializable,java/lang/Cloneable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sql/rowset/serial/SerialDatalink +header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sql/rowset/serial/SerialJavaObject +header extends java/lang/Object implements java/io/Serializable,java/lang/Cloneable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 + +class name javax/sql/rowset/serial/SerialRef +header extends java/lang/Object implements java/sql/Ref,java/io/Serializable,java/lang/Cloneable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/sql/rowset/serial/SerialStruct +header extends java/lang/Object implements java/sql/Struct,java/io/Serializable,java/lang/Cloneable flags 21 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.xml-B.sym.txt b/make/data/symbols/java.xml-B.sym.txt index 08675c9bf03cb30bef1c36be40ba5b50f4292aa6..3f256899258cebb963072b57e0a4f0504639035b 100644 --- a/make/data/symbols/java.xml-B.sym.txt +++ b/make/data/symbols/java.xml-B.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -136,8 +136,8 @@ header extends java/lang/Object implements javax/xml/stream/util/XMLEventConsume class name javax/xml/stream/XMLInputFactory header extends java/lang/Object flags 421 -method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 -method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; +method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 class name javax/xml/stream/XMLOutputFactory header extends java/lang/Object flags 421 diff --git a/make/data/symbols/java.xml-C.sym.txt b/make/data/symbols/java.xml-C.sym.txt index 6023e7f147c9da0ff7d89269ce57a628e93012ad..56f91aac3dcb316ac47a9225de2e0bf6b1b806b0 100644 --- a/make/data/symbols/java.xml-C.sym.txt +++ b/make/data/symbols/java.xml-C.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,6 @@ # ########################################################## # class name javax/xml/stream/XMLInputFactory -method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 -method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; +method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 diff --git a/make/data/symbols/java.xml-D.sym.txt b/make/data/symbols/java.xml-D.sym.txt index 29a4adb0d58dc4d268b49416e61ffc5f9755ddd6..a91b0cd8dd12ff3f0a4627609dfc9cb6a5322ef5 100644 --- a/make/data/symbols/java.xml-D.sym.txt +++ b/make/data/symbols/java.xml-D.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,6 @@ method name newNSInstance descriptor ()Ljavax/xml/parsers/SAXParserFactory; flag method name newNSInstance descriptor (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljavax/xml/parsers/SAXParserFactory; flags 9 class name javax/xml/stream/XMLInputFactory -method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 -method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; +method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 diff --git a/make/data/symbols/java.xml-E.sym.txt b/make/data/symbols/java.xml-E.sym.txt index 3c5d6da6fc3df7bac5816bad97c1eb0789cfac7d..9c4ac9945e8b55e00620b5f22a6c676fb9e0f873 100644 --- a/make/data/symbols/java.xml-E.sym.txt +++ b/make/data/symbols/java.xml-E.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ # ########################################################## # class name javax/xml/stream/XMLInputFactory -method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 -method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; +method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 class name org/xml/sax/ContentHandler method name declaration descriptor (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V thrownTypes org/xml/sax/SAXException flags 1 diff --git a/make/data/symbols/java.xml-I.sym.txt b/make/data/symbols/java.xml-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..ccadde9ba21875fc4d507911737bfeab3864f9aa --- /dev/null +++ b/make/data/symbols/java.xml-I.sym.txt @@ -0,0 +1,158 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/xml/catalog/Catalog +header extends java/lang/Object flags 601 + +class name javax/xml/catalog/CatalogException +header extends java/lang/RuntimeException flags 21 + +class name javax/xml/catalog/CatalogFeatures +header extends java/lang/Object nestMembers javax/xml/catalog/CatalogFeatures$Builder,javax/xml/catalog/CatalogFeatures$Feature flags 21 +innerclass innerClass javax/xml/catalog/CatalogFeatures$Builder outerClass javax/xml/catalog/CatalogFeatures innerClassName Builder flags 9 +innerclass innerClass javax/xml/catalog/CatalogFeatures$Feature outerClass javax/xml/catalog/CatalogFeatures innerClassName Feature flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/catalog/CatalogManager +header extends java/lang/Object flags 31 + +class name javax/xml/catalog/CatalogResolver +header extends java/lang/Object implements org/xml/sax/EntityResolver,javax/xml/stream/XMLResolver,javax/xml/transform/URIResolver,org/w3c/dom/ls/LSResourceResolver flags 601 + +class name javax/xml/datatype/DatatypeFactory +header extends java/lang/Object flags 421 +innerclass innerClass javax/xml/datatype/DatatypeConstants$Field outerClass javax/xml/datatype/DatatypeConstants innerClassName Field flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/datatype/Duration +header extends java/lang/Object flags 421 +innerclass innerClass javax/xml/datatype/DatatypeConstants$Field outerClass javax/xml/datatype/DatatypeConstants innerClassName Field flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/namespace/QName +header extends java/lang/Object implements java/io/Serializable flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/parsers/DocumentBuilder +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/parsers/DocumentBuilderFactory +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/parsers/SAXParser +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/parsers/SAXParserFactory +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/stream/XMLEventReader +header extends java/lang/Object implements java/util/Iterator flags 601 signature Ljava/lang/Object;Ljava/util/Iterator; + +class name javax/xml/stream/XMLInputFactory +-method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; +method name newFactory descriptor ()Ljavax/xml/stream/XMLInputFactory; thrownTypes javax/xml/stream/FactoryConfigurationError flags 9 + +class name javax/xml/stream/XMLStreamException +header extends java/lang/Exception flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/transform/Transformer +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/transform/TransformerException +header extends java/lang/Exception flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/validation/SchemaFactory +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/xpath/XPath +header extends java/lang/Object flags 601 +innerclass innerClass javax/xml/xpath/XPathEvaluationResult$XPathResultType outerClass javax/xml/xpath/XPathEvaluationResult innerClassName XPathResultType flags 4019 + +class name javax/xml/xpath/XPathException +header extends java/lang/Exception flags 21 +innerclass innerClass java/io/ObjectOutputStream$PutField outerClass java/io/ObjectOutputStream innerClassName PutField flags 409 +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name javax/xml/xpath/XPathExpression +header extends java/lang/Object flags 601 +innerclass innerClass javax/xml/xpath/XPathEvaluationResult$XPathResultType outerClass javax/xml/xpath/XPathEvaluationResult innerClassName XPathResultType flags 4019 + +class name javax/xml/xpath/XPathFactory +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +method name setProperty descriptor (Ljava/lang/String;Ljava/lang/String;)V flags 1 +method name getProperty descriptor (Ljava/lang/String;)Ljava/lang/String; flags 1 + +class name javax/xml/xpath/XPathNodes +header extends java/lang/Object implements java/lang/Iterable flags 601 signature Ljava/lang/Object;Ljava/lang/Iterable; + +class name org/w3c/dom/ElementTraversal +header extends java/lang/Object flags 601 + +class name org/xml/sax/AttributeList +header extends java/lang/Object flags 601 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="1.5") + +class name org/xml/sax/DocumentHandler +header extends java/lang/Object flags 601 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="1.5") + +class name org/xml/sax/HandlerBase +header extends java/lang/Object implements org/xml/sax/EntityResolver,org/xml/sax/DTDHandler,org/xml/sax/DocumentHandler,org/xml/sax/ErrorHandler flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="1.5") + +class name org/xml/sax/Parser +header extends java/lang/Object flags 601 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="1.5") + +class name org/xml/sax/ext/Attributes2Impl +header extends org/xml/sax/helpers/AttributesImpl implements org/xml/sax/ext/Attributes2 flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name org/xml/sax/helpers/AttributeListImpl +header extends java/lang/Object implements org/xml/sax/AttributeList flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="1.5") + +class name org/xml/sax/helpers/AttributesImpl +header extends java/lang/Object implements org/xml/sax/Attributes flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name org/xml/sax/helpers/ParserFactory +header extends java/lang/Object flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="1.5") + +class name org/xml/sax/helpers/XMLFilterImpl +header extends java/lang/Object implements org/xml/sax/XMLFilter,org/xml/sax/EntityResolver,org/xml/sax/DTDHandler,org/xml/sax/ContentHandler,org/xml/sax/ErrorHandler flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name org/xml/sax/helpers/XMLReaderFactory +header extends java/lang/Object flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/java.xml.crypto-I.sym.txt b/make/data/symbols/java.xml.crypto-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..257909a317c7b7111508eebc2f150e8223c5a91a --- /dev/null +++ b/make/data/symbols/java.xml.crypto-I.sym.txt @@ -0,0 +1,46 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/xml/crypto/NodeSetData +header extends java/lang/Object implements javax/xml/crypto/Data,java/lang/Iterable flags 601 signature Ljava/lang/Object;Ljavax/xml/crypto/Data;Ljava/lang/Iterable; + +class name javax/xml/crypto/dom/DOMCryptoContext +header extends java/lang/Object implements javax/xml/crypto/XMLCryptoContext flags 21 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/crypto/dsig/XMLSignatureFactory +header extends java/lang/Object flags 421 +innerclass innerClass java/security/Provider$Service outerClass java/security/Provider innerClassName Service flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/xml/crypto/dsig/keyinfo/KeyInfoFactory +header extends java/lang/Object flags 421 +innerclass innerClass java/security/Provider$Service outerClass java/security/Provider innerClassName Service flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/jdk.accessibility-I.sym.txt b/make/data/symbols/jdk.accessibility-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..eee9c4105f30260169246c6ca5f22e2e62dca6a9 --- /dev/null +++ b/make/data/symbols/jdk.accessibility-I.sym.txt @@ -0,0 +1,58 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/java/accessibility/util/AWTEventMonitor +-field name componentWithFocus descriptor Ljava/awt/Component; +-field name componentListener descriptor Ljava/awt/event/ComponentListener; +-field name containerListener descriptor Ljava/awt/event/ContainerListener; +-field name focusListener descriptor Ljava/awt/event/FocusListener; +-field name keyListener descriptor Ljava/awt/event/KeyListener; +-field name mouseListener descriptor Ljava/awt/event/MouseListener; +-field name mouseMotionListener descriptor Ljava/awt/event/MouseMotionListener; +-field name windowListener descriptor Ljava/awt/event/WindowListener; +-field name actionListener descriptor Ljava/awt/event/ActionListener; +-field name adjustmentListener descriptor Ljava/awt/event/AdjustmentListener; +-field name itemListener descriptor Ljava/awt/event/ItemListener; +-field name textListener descriptor Ljava/awt/event/TextListener; + +class name com/sun/java/accessibility/util/AccessibilityListenerList +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/java/accessibility/util/EventID +header extends java/lang/Object flags 21 + +class name com/sun/java/accessibility/util/GUIInitializedListener +header extends java/lang/Object implements java/util/EventListener flags 601 + +class name com/sun/java/accessibility/util/TopLevelWindowListener +header extends java/lang/Object implements java/util/EventListener flags 601 + +class name com/sun/java/accessibility/util/Translator +header extends javax/accessibility/AccessibleContext implements javax/accessibility/Accessible,javax/accessibility/AccessibleComponent flags 21 + diff --git a/make/data/symbols/jdk.attach-I.sym.txt b/make/data/symbols/jdk.attach-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..bbe7de3e07f9363b49f7686cfea8cf05049b2c58 --- /dev/null +++ b/make/data/symbols/jdk.attach-I.sym.txt @@ -0,0 +1,55 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/tools/attach/AgentInitializationException +header extends java/lang/Exception flags 21 + +class name com/sun/tools/attach/AgentLoadException +header extends java/lang/Exception flags 21 + +class name com/sun/tools/attach/AttachNotSupportedException +header extends java/lang/Exception flags 21 + +class name com/sun/tools/attach/AttachOperationFailedException +header extends java/io/IOException flags 21 + +class name com/sun/tools/attach/AttachPermission +header extends java/security/BasicPermission flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/tools/attach/VirtualMachine +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/tools/attach/VirtualMachineDescriptor +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/tools/attach/spi/AttachProvider +header extends java/lang/Object flags 421 + diff --git a/make/data/symbols/jdk.compiler-I.sym.txt b/make/data/symbols/jdk.compiler-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..7546b9fea27467f220f4480013a4d9939d84e350 --- /dev/null +++ b/make/data/symbols/jdk.compiler-I.sym.txt @@ -0,0 +1,373 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/source/doctree/AuthorTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/BlockTagTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/CommentTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/DeprecatedTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/DocCommentTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/DocRootTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 + +class name com/sun/source/doctree/DocTree$Kind +field name SNIPPET descriptor Lcom/sun/source/doctree/DocTree$Kind; flags 4019 + +class name com/sun/source/doctree/DocTreeVisitor +header extends java/lang/Object flags 601 signature Ljava/lang/Object; +method name visitSnippet descriptor (Lcom/sun/source/doctree/SnippetTree;Ljava/lang/Object;)Ljava/lang/Object; flags 1 signature (Lcom/sun/source/doctree/SnippetTree;TP;)TR; + +class name com/sun/source/doctree/DocTypeTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/EndElementTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/EntityTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/ErroneousTree +header extends java/lang/Object implements com/sun/source/doctree/TextTree flags 601 + +class name com/sun/source/doctree/HiddenTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/IdentifierTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/IndexTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 + +class name com/sun/source/doctree/InheritDocTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 + +class name com/sun/source/doctree/InlineTagTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/LinkTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 + +class name com/sun/source/doctree/LiteralTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 + +class name com/sun/source/doctree/ParamTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/ProvidesTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/ReferenceTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/SeeTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/SerialDataTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/SerialFieldTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/SerialTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/SinceTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/SnippetTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 +method name getAttributes descriptor ()Ljava/util/List; flags 401 signature ()Ljava/util/List<+Lcom/sun/source/doctree/DocTree;>; +method name getBody descriptor ()Lcom/sun/source/doctree/TextTree; flags 401 + +class name com/sun/source/doctree/StartElementTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/SummaryTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 + +class name com/sun/source/doctree/TextTree +header extends java/lang/Object implements com/sun/source/doctree/DocTree flags 601 + +class name com/sun/source/doctree/ThrowsTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/UnknownBlockTagTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/UnknownInlineTagTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 + +class name com/sun/source/doctree/UsesTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/doctree/ValueTree +header extends java/lang/Object implements com/sun/source/doctree/InlineTagTree flags 601 + +class name com/sun/source/doctree/VersionTree +header extends java/lang/Object implements com/sun/source/doctree/BlockTagTree flags 601 + +class name com/sun/source/tree/AnnotatedTypeTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/AnnotationTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/ArrayAccessTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/ArrayTypeTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/AssertTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/AssignmentTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/BinaryTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/BlockTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/BreakTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/CatchTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/ClassTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/CompilationUnitTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/CompoundAssignmentTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/ConditionalExpressionTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/ContinueTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/DirectiveTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/DoWhileLoopTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/EmptyStatementTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/EnhancedForLoopTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/ErroneousTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/ExportsTree +header extends java/lang/Object implements com/sun/source/tree/DirectiveTree flags 601 + +class name com/sun/source/tree/ExpressionStatementTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/ForLoopTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/IdentifierTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/IfTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/ImportTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/InstanceOfTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/IntersectionTypeTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/LabeledStatementTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/LineMap +header extends java/lang/Object flags 601 + +class name com/sun/source/tree/LiteralTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/MemberSelectTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/MethodInvocationTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/MethodTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/ModifiersTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/NewArrayTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/NewClassTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/OpensTree +header extends java/lang/Object implements com/sun/source/tree/DirectiveTree flags 601 + +class name com/sun/source/tree/PackageTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/ParameterizedTypeTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/ParenthesizedTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/PrimitiveTypeTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/ProvidesTree +header extends java/lang/Object implements com/sun/source/tree/DirectiveTree flags 601 + +class name com/sun/source/tree/RequiresTree +header extends java/lang/Object implements com/sun/source/tree/DirectiveTree flags 601 + +class name com/sun/source/tree/ReturnTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/Scope +header extends java/lang/Object flags 601 + +class name com/sun/source/tree/StatementTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/SwitchTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/SynchronizedTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/ThrowTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/TreeVisitor +header extends java/lang/Object flags 601 signature Ljava/lang/Object; + +class name com/sun/source/tree/TryTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/TypeCastTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/TypeParameterTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/UnaryTree +header extends java/lang/Object implements com/sun/source/tree/ExpressionTree flags 601 + +class name com/sun/source/tree/UnionTypeTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/tree/UsesTree +header extends java/lang/Object implements com/sun/source/tree/DirectiveTree flags 601 + +class name com/sun/source/tree/VariableTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/WhileLoopTree +header extends java/lang/Object implements com/sun/source/tree/StatementTree flags 601 + +class name com/sun/source/tree/WildcardTree +header extends java/lang/Object implements com/sun/source/tree/Tree flags 601 + +class name com/sun/source/util/DocSourcePositions +header extends java/lang/Object implements com/sun/source/util/SourcePositions flags 601 + +class name com/sun/source/util/DocTreeFactory +header extends java/lang/Object flags 601 +innerclass innerClass com/sun/source/doctree/AttributeTree$ValueKind outerClass com/sun/source/doctree/AttributeTree innerClassName ValueKind flags 4019 +method name newSnippetTree descriptor (Ljava/util/List;Lcom/sun/source/doctree/TextTree;)Lcom/sun/source/doctree/SnippetTree; flags 401 signature (Ljava/util/List<+Lcom/sun/source/doctree/DocTree;>;Lcom/sun/source/doctree/TextTree;)Lcom/sun/source/doctree/SnippetTree; + +class name com/sun/source/util/DocTreePathScanner +header extends com/sun/source/util/DocTreeScanner flags 21 signature Lcom/sun/source/util/DocTreeScanner; + +class name com/sun/source/util/DocTreeScanner +header extends java/lang/Object implements com/sun/source/doctree/DocTreeVisitor flags 21 signature Ljava/lang/Object;Lcom/sun/source/doctree/DocTreeVisitor; +method name visitSnippet descriptor (Lcom/sun/source/doctree/SnippetTree;Ljava/lang/Object;)Ljava/lang/Object; flags 1 signature (Lcom/sun/source/doctree/SnippetTree;TP;)TR; + +class name com/sun/source/util/DocTrees +header extends com/sun/source/util/Trees flags 421 +innerclass innerClass javax/tools/JavaCompiler$CompilationTask outerClass javax/tools/JavaCompiler innerClassName CompilationTask flags 609 +innerclass innerClass javax/tools/Diagnostic$Kind outerClass javax/tools/Diagnostic innerClassName Kind flags 4019 + +class name com/sun/source/util/JavacTask +header extends java/lang/Object implements javax/tools/JavaCompiler$CompilationTask flags 421 +innerclass innerClass javax/tools/JavaCompiler$CompilationTask outerClass javax/tools/JavaCompiler innerClassName CompilationTask flags 609 + +class name com/sun/source/util/Plugin +header extends java/lang/Object flags 601 + +class name com/sun/source/util/SimpleDocTreeVisitor +header extends java/lang/Object implements com/sun/source/doctree/DocTreeVisitor flags 21 signature Ljava/lang/Object;Lcom/sun/source/doctree/DocTreeVisitor; +method name visitSnippet descriptor (Lcom/sun/source/doctree/SnippetTree;Ljava/lang/Object;)Ljava/lang/Object; flags 1 signature (Lcom/sun/source/doctree/SnippetTree;TP;)TR; + +class name com/sun/source/util/SimpleTreeVisitor +header extends java/lang/Object implements com/sun/source/tree/TreeVisitor flags 21 signature Ljava/lang/Object;Lcom/sun/source/tree/TreeVisitor; + +class name com/sun/source/util/SourcePositions +header extends java/lang/Object flags 601 + +class name com/sun/source/util/TaskListener +header extends java/lang/Object flags 601 + +class name com/sun/source/util/TreePathScanner +header extends com/sun/source/util/TreeScanner flags 21 signature Lcom/sun/source/util/TreeScanner; + +class name com/sun/source/util/Trees +header extends java/lang/Object flags 421 +innerclass innerClass javax/tools/JavaCompiler$CompilationTask outerClass javax/tools/JavaCompiler innerClassName CompilationTask flags 609 +innerclass innerClass javax/tools/Diagnostic$Kind outerClass javax/tools/Diagnostic innerClassName Kind flags 4019 + +class name com/sun/tools/javac/Main +header extends java/lang/Object flags 21 + diff --git a/make/data/symbols/jdk.dynalink-I.sym.txt b/make/data/symbols/jdk.dynalink-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..854dbd70888eb8241862fc6affba6420a06351dc --- /dev/null +++ b/make/data/symbols/jdk.dynalink-I.sym.txt @@ -0,0 +1,136 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/dynalink/CallSiteDescriptor +header extends jdk/dynalink/SecureLookupSupplier flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/DynamicLinker +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/StackWalker$StackFrame outerClass java/lang/StackWalker innerClassName StackFrame flags 609 +innerclass innerClass java/lang/StackWalker$Option outerClass java/lang/StackWalker innerClassName Option flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/NamedOperation +header extends java/lang/Object implements jdk/dynalink/Operation flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/Namespace +header extends java/lang/Object flags 601 + +class name jdk/dynalink/NamespaceOperation +header extends java/lang/Object implements jdk/dynalink/Operation flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/NoSuchDynamicMethodException +header extends java/lang/RuntimeException flags 21 + +class name jdk/dynalink/Operation +header extends java/lang/Object flags 601 + +class name jdk/dynalink/RelinkableCallSite +header extends java/lang/Object flags 601 + +class name jdk/dynalink/SecureLookupSupplier +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/StandardNamespace +header extends java/lang/Enum implements jdk/dynalink/Namespace flags 4031 signature Ljava/lang/Enum;Ljdk/dynalink/Namespace; + +class name jdk/dynalink/StandardOperation +header extends java/lang/Enum implements jdk/dynalink/Operation flags 4031 signature Ljava/lang/Enum;Ljdk/dynalink/Operation; + +class name jdk/dynalink/beans/MissingMemberHandlerFactory +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; + +class name jdk/dynalink/linker/GuardedInvocation +header extends java/lang/Object flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/linker/GuardedInvocationTransformer +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; + +class name jdk/dynalink/linker/GuardingDynamicLinker +header extends java/lang/Object flags 601 + +class name jdk/dynalink/linker/GuardingDynamicLinkerExporter +header extends java/lang/Object implements java/util/function/Supplier flags 421 signature Ljava/lang/Object;Ljava/util/function/Supplier;>; + +class name jdk/dynalink/linker/GuardingTypeConverterFactory +header extends java/lang/Object flags 601 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/linker/LinkRequest +header extends java/lang/Object flags 601 + +class name jdk/dynalink/linker/LinkerServices +header extends java/lang/Object flags 601 +innerclass innerClass jdk/dynalink/linker/ConversionComparator$Comparison outerClass jdk/dynalink/linker/ConversionComparator innerClassName Comparison flags 4019 + +class name jdk/dynalink/linker/MethodHandleTransformer +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; + +class name jdk/dynalink/linker/MethodTypeConversionStrategy +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; + +class name jdk/dynalink/linker/TypeBasedGuardingDynamicLinker +header extends java/lang/Object implements jdk/dynalink/linker/GuardingDynamicLinker flags 601 + +class name jdk/dynalink/linker/support/CompositeGuardingDynamicLinker +header extends java/lang/Object implements jdk/dynalink/linker/GuardingDynamicLinker flags 21 + +class name jdk/dynalink/linker/support/DefaultInternalObjectFilter +header extends java/lang/Object implements jdk/dynalink/linker/MethodHandleTransformer flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/linker/support/Guards +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/linker/support/Lookup +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/linker/support/SimpleLinkRequest +header extends java/lang/Object implements jdk/dynalink/linker/LinkRequest flags 21 + +class name jdk/dynalink/linker/support/TypeUtilities +header extends java/lang/Object flags 31 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 + +class name jdk/dynalink/support/AbstractRelinkableCallSite +header extends java/lang/invoke/MutableCallSite implements jdk/dynalink/RelinkableCallSite flags 421 + +class name jdk/dynalink/support/ChainedCallSite +header extends jdk/dynalink/support/AbstractRelinkableCallSite flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/dynalink/support/SimpleRelinkableCallSite +header extends jdk/dynalink/support/AbstractRelinkableCallSite flags 21 + diff --git a/make/data/symbols/jdk.httpserver-I.sym.txt b/make/data/symbols/jdk.httpserver-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..5803e61c4ba94a11b799870501ee0f9bda09e023 --- /dev/null +++ b/make/data/symbols/jdk.httpserver-I.sym.txt @@ -0,0 +1,110 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +module name jdk.httpserver +header exports com/sun/net/httpserver,com/sun/net/httpserver/spi requires name\u0020;java.base\u0020;flags\u0020;8000 uses com/sun/net/httpserver/spi/HttpServerProvider target linux-amd64 moduleMainClass sun/net/httpserver/simpleserver/Main flags 8000 + +class name com/sun/net/httpserver/Filter +method name adaptRequest descriptor (Ljava/lang/String;Ljava/util/function/UnaryOperator;)Lcom/sun/net/httpserver/Filter; flags 9 signature (Ljava/lang/String;Ljava/util/function/UnaryOperator;)Lcom/sun/net/httpserver/Filter; + +class name com/sun/net/httpserver/Headers +header extends java/lang/Object implements java/util/Map flags 21 signature Ljava/lang/Object;Ljava/util/Map;>; +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +method name descriptor (Ljava/util/Map;)V flags 1 signature (Ljava/util/Map;>;)V +method name replaceAll descriptor (Ljava/util/function/BiFunction;)V flags 1 signature (Ljava/util/function/BiFunction<-Ljava/lang/String;-Ljava/util/List;+Ljava/util/List;>;)V +method name toString descriptor ()Ljava/lang/String; flags 1 +method name of descriptor ([Ljava/lang/String;)Lcom/sun/net/httpserver/Headers; flags 89 +method name of descriptor (Ljava/util/Map;)Lcom/sun/net/httpserver/Headers; flags 9 signature (Ljava/util/Map;>;)Lcom/sun/net/httpserver/Headers; + +class name com/sun/net/httpserver/HttpContext +header extends java/lang/Object flags 421 + +class name com/sun/net/httpserver/HttpExchange +header extends java/lang/Object implements java/lang/AutoCloseable,com/sun/net/httpserver/Request flags 421 + +class name com/sun/net/httpserver/HttpHandler +header extends java/lang/Object flags 601 + +class name com/sun/net/httpserver/HttpHandlers +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +method name handleOrElse descriptor (Ljava/util/function/Predicate;Lcom/sun/net/httpserver/HttpHandler;Lcom/sun/net/httpserver/HttpHandler;)Lcom/sun/net/httpserver/HttpHandler; flags 9 signature (Ljava/util/function/Predicate;Lcom/sun/net/httpserver/HttpHandler;Lcom/sun/net/httpserver/HttpHandler;)Lcom/sun/net/httpserver/HttpHandler; +method name of descriptor (ILcom/sun/net/httpserver/Headers;Ljava/lang/String;)Lcom/sun/net/httpserver/HttpHandler; flags 9 + +class name com/sun/net/httpserver/HttpPrincipal +header extends java/lang/Object implements java/security/Principal flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/net/httpserver/HttpServer +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +method name create descriptor (Ljava/net/InetSocketAddress;ILjava/lang/String;Lcom/sun/net/httpserver/HttpHandler;[Lcom/sun/net/httpserver/Filter;)Lcom/sun/net/httpserver/HttpServer; thrownTypes java/io/IOException flags 89 + +class name com/sun/net/httpserver/HttpsConfigurator +header extends java/lang/Object flags 21 + +class name com/sun/net/httpserver/HttpsExchange +header extends com/sun/net/httpserver/HttpExchange flags 421 + +class name com/sun/net/httpserver/HttpsParameters +header extends java/lang/Object flags 421 + +class name com/sun/net/httpserver/HttpsServer +header extends com/sun/net/httpserver/HttpServer flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +method name create descriptor (Ljava/net/InetSocketAddress;ILjava/lang/String;Lcom/sun/net/httpserver/HttpHandler;[Lcom/sun/net/httpserver/Filter;)Lcom/sun/net/httpserver/HttpsServer; thrownTypes java/io/IOException flags 89 + +class name com/sun/net/httpserver/Request +header extends java/lang/Object flags 601 +method name getRequestURI descriptor ()Ljava/net/URI; flags 401 +method name getRequestMethod descriptor ()Ljava/lang/String; flags 401 +method name getRequestHeaders descriptor ()Lcom/sun/net/httpserver/Headers; flags 401 +method name with descriptor (Ljava/lang/String;Ljava/util/List;)Lcom/sun/net/httpserver/Request; flags 1 signature (Ljava/lang/String;Ljava/util/List;)Lcom/sun/net/httpserver/Request; + +class name com/sun/net/httpserver/SimpleFileServer +header extends java/lang/Object nestMembers com/sun/net/httpserver/SimpleFileServer$OutputLevel flags 31 +innerclass innerClass com/sun/net/httpserver/SimpleFileServer$OutputLevel outerClass com/sun/net/httpserver/SimpleFileServer innerClassName OutputLevel flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +method name createFileServer descriptor (Ljava/net/InetSocketAddress;Ljava/nio/file/Path;Lcom/sun/net/httpserver/SimpleFileServer$OutputLevel;)Lcom/sun/net/httpserver/HttpServer; flags 9 +method name createFileHandler descriptor (Ljava/nio/file/Path;)Lcom/sun/net/httpserver/HttpHandler; flags 9 +method name createOutputFilter descriptor (Ljava/io/OutputStream;Lcom/sun/net/httpserver/SimpleFileServer$OutputLevel;)Lcom/sun/net/httpserver/Filter; flags 9 + +class name com/sun/net/httpserver/SimpleFileServer$OutputLevel +header extends java/lang/Enum nestHost com/sun/net/httpserver/SimpleFileServer flags 4031 signature Ljava/lang/Enum; +innerclass innerClass com/sun/net/httpserver/SimpleFileServer$OutputLevel outerClass com/sun/net/httpserver/SimpleFileServer innerClassName OutputLevel flags 4019 +field name NONE descriptor Lcom/sun/net/httpserver/SimpleFileServer$OutputLevel; flags 4019 +field name INFO descriptor Lcom/sun/net/httpserver/SimpleFileServer$OutputLevel; flags 4019 +field name VERBOSE descriptor Lcom/sun/net/httpserver/SimpleFileServer$OutputLevel; flags 4019 +method name values descriptor ()[Lcom/sun/net/httpserver/SimpleFileServer$OutputLevel; flags 9 +method name valueOf descriptor (Ljava/lang/String;)Lcom/sun/net/httpserver/SimpleFileServer$OutputLevel; flags 9 + +class name com/sun/net/httpserver/spi/HttpServerProvider +header extends java/lang/Object flags 421 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/jdk.incubator.foreign-F.sym.txt b/make/data/symbols/jdk.incubator.foreign-F.sym.txt index 4a37cfad9b5cf0488ed26c56faf41f9dded05ccc..efb2d71b3344c2b5b3ce1effafa9b4f6d7421e07 100644 --- a/make/data/symbols/jdk.incubator.foreign-F.sym.txt +++ b/make/data/symbols/jdk.incubator.foreign-F.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -59,9 +59,9 @@ method name asSlice descriptor (JJ)Ljdk/incubator/foreign/MemorySegment; flags 1 method name withAccessModes descriptor (I)Ljdk/incubator/foreign/MemorySegment; flags 1041 class name jdk/incubator/foreign/MemoryAddress -field name NULL descriptor Ljdk/incubator/foreign/MemoryAddress; flags 19 -method name offset descriptor ()J -method name copy descriptor (Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;J)V +field name NULL descriptor Ljdk/incubator/foreign/MemoryAddress; flags 19 method name segmentOffset descriptor ()J flags 401 method name toRawLongValue descriptor ()J flags 401 method name rebase descriptor (Ljdk/incubator/foreign/MemorySegment;)Ljdk/incubator/foreign/MemoryAddress; flags 401 @@ -78,8 +78,8 @@ method name collectCoordinates descriptor (Ljava/lang/invoke/VarHandle;ILjava/la method name dropCoordinates descriptor (Ljava/lang/invoke/VarHandle;I[Ljava/lang/Class;)Ljava/lang/invoke/VarHandle; flags 89 signature (Ljava/lang/invoke/VarHandle;I[Ljava/lang/Class<*>;)Ljava/lang/invoke/VarHandle; class name jdk/incubator/foreign/MemoryLayout -field name LAYOUT_NAME descriptor Ljava/lang/String; constantValue layout/name flags 19 -method name offset descriptor ([Ljdk/incubator/foreign/MemoryLayout$PathElement;)J +field name LAYOUT_NAME descriptor Ljava/lang/String; constantValue layout/name flags 19 method name attribute descriptor (Ljava/lang/String;)Ljava/util/Optional; flags 401 signature (Ljava/lang/String;)Ljava/util/Optional; method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/MemoryLayout; flags 401 method name attributes descriptor ()Ljava/util/stream/Stream; flags 401 signature ()Ljava/util/stream/Stream; @@ -88,16 +88,16 @@ method name byteOffset descriptor ([Ljdk/incubator/foreign/MemoryLayout$PathElem method name isPadding descriptor ()Z flags 401 class name jdk/incubator/foreign/MemorySegment +-method name acquire descriptor ()Ljdk/incubator/foreign/MemorySegment; +-method name asReadOnly descriptor ()Ljdk/incubator/foreign/MemorySegment; +-method name isReadOnly descriptor ()Z +-method name mapFromPath descriptor (Ljava/nio/file/Path;JLjava/nio/channels/FileChannel$MapMode;)Ljdk/incubator/foreign/MemorySegment; field name READ descriptor I constantValue 1 flags 19 field name WRITE descriptor I constantValue 2 flags 19 field name CLOSE descriptor I constantValue 4 flags 19 field name ACQUIRE descriptor I constantValue 8 flags 19 field name HANDOFF descriptor I constantValue 16 flags 19 field name ALL_ACCESS descriptor I constantValue 31 flags 19 --method name acquire descriptor ()Ljdk/incubator/foreign/MemorySegment; --method name asReadOnly descriptor ()Ljdk/incubator/foreign/MemorySegment; --method name isReadOnly descriptor ()Z --method name mapFromPath descriptor (Ljava/nio/file/Path;JLjava/nio/channels/FileChannel$MapMode;)Ljdk/incubator/foreign/MemorySegment; method name spliterator descriptor (Ljdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/SequenceLayout;)Ljava/util/Spliterator; flags 9 signature (TS;Ljdk/incubator/foreign/SequenceLayout;)Ljava/util/Spliterator; method name withOwnerThread descriptor (Ljava/lang/Thread;)Ljdk/incubator/foreign/MemorySegment; flags 401 method name withAccessModes descriptor (I)Ljdk/incubator/foreign/MemorySegment; flags 401 diff --git a/make/data/symbols/jdk.incubator.foreign-G.sym.txt b/make/data/symbols/jdk.incubator.foreign-G.sym.txt index 5bb38702f4fa1a496f86e3ed98f3f38e10888f8f..3ea0960ea1e1761c471640498a3e72f598ccab23 100644 --- a/make/data/symbols/jdk.incubator.foreign-G.sym.txt +++ b/make/data/symbols/jdk.incubator.foreign-G.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -264,12 +264,12 @@ header extends java/lang/Object implements jdk/incubator/foreign/Addressable,jav innerclass innerClass java/nio/channels/FileChannel$MapMode outerClass java/nio/channels/FileChannel innerClassName MapMode flags 9 innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 -field name ACQUIRE descriptor I -field name SHARE descriptor I constantValue 8 flags 19 -method name baseAddress descriptor ()Ljdk/incubator/foreign/MemoryAddress; -method name spliterator descriptor (Ljdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/SequenceLayout;)Ljava/util/Spliterator; -method name withOwnerThread descriptor (Ljava/lang/Thread;)Ljdk/incubator/foreign/MemorySegment; -method name mapFromPath descriptor (Ljava/nio/file/Path;JJLjava/nio/channels/FileChannel$MapMode;)Ljdk/incubator/foreign/MappedMemorySegment; -method name ofNativeRestricted descriptor (Ljdk/incubator/foreign/MemoryAddress;JLjava/lang/Thread;Ljava/lang/Runnable;Ljava/lang/Object;)Ljdk/incubator/foreign/MemorySegment; +field name SHARE descriptor I constantValue 8 flags 19 method name address descriptor ()Ljdk/incubator/foreign/MemoryAddress; flags 401 method name spliterator descriptor (Ljdk/incubator/foreign/SequenceLayout;)Ljava/util/Spliterator; flags 401 signature (Ljdk/incubator/foreign/SequenceLayout;)Ljava/util/Spliterator; method name asSlice descriptor (Ljdk/incubator/foreign/MemoryAddress;J)Ljdk/incubator/foreign/MemorySegment; flags 1 diff --git a/make/data/symbols/jdk.incubator.foreign-H.sym.txt b/make/data/symbols/jdk.incubator.foreign-H.sym.txt index 376ba519f57b5fd270bb534406f45aa1feb316e7..d5349d378bfd7ddcbc57ccadefa20344e4f063fd 100644 --- a/make/data/symbols/jdk.incubator.foreign-H.sym.txt +++ b/make/data/symbols/jdk.incubator.foreign-H.sym.txt @@ -43,6 +43,7 @@ innerclass innerClass jdk/incubator/foreign/CLinker$VaList$Builder outerClass jd -method name allocateMemoryRestricted descriptor (J)Ljdk/incubator/foreign/MemoryAddress; -method name freeMemoryRestricted descriptor (Ljdk/incubator/foreign/MemoryAddress;)V method name getInstance descriptor ()Ljdk/incubator/foreign/CLinker; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name systemLookup descriptor ()Ljdk/incubator/foreign/SymbolLookup; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; method name downcallHandle descriptor (Ljdk/incubator/foreign/Addressable;Ljdk/incubator/foreign/SegmentAllocator;Ljava/lang/invoke/MethodType;Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodHandle; flags 401 method name downcallHandle descriptor (Ljava/lang/invoke/MethodType;Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodHandle; flags 401 method name upcallStub descriptor (Ljava/lang/invoke/MethodHandle;Ljdk/incubator/foreign/FunctionDescriptor;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/MemoryAddress; flags 401 @@ -51,7 +52,6 @@ method name toCString descriptor (Ljava/lang/String;Ljdk/incubator/foreign/Resou method name toJavaString descriptor (Ljdk/incubator/foreign/MemoryAddress;)Ljava/lang/String; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; method name allocateMemory descriptor (J)Ljdk/incubator/foreign/MemoryAddress; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; method name freeMemory descriptor (Ljdk/incubator/foreign/MemoryAddress;)V flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; -method name systemLookup descriptor ()Ljdk/incubator/foreign/SymbolLookup; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; class name jdk/incubator/foreign/CLinker$VaList header extends java/lang/Object implements jdk/incubator/foreign/Addressable nestHost jdk/incubator/foreign/CLinker sealed true flags 601 diff --git a/make/data/symbols/jdk.incubator.foreign-I.sym.txt b/make/data/symbols/jdk.incubator.foreign-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..c8b457ba73374df773576d71cb98958841cceb0f --- /dev/null +++ b/make/data/symbols/jdk.incubator.foreign-I.sym.txt @@ -0,0 +1,582 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/incubator/foreign/AbstractLayout +header extends java/lang/Object implements jdk/incubator/foreign/MemoryLayout flags 420 +innerclass innerClass java/lang/constant/DirectMethodHandleDesc$Kind outerClass java/lang/constant/DirectMethodHandleDesc innerClassName Kind flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name descriptor (Ljava/util/OptionalLong;JLjava/util/Map;)V +-method name attribute descriptor (Ljava/lang/String;)Ljava/util/Optional; +-method name attributes descriptor ()Ljava/util/stream/Stream; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/AbstractLayout; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/MemoryLayout; +method name descriptor (Ljava/util/OptionalLong;JLjava/util/Optional;)V flags 1 signature (Ljava/util/OptionalLong;JLjava/util/Optional;)V +method name byteSize descriptor ()J flags 1 + +class name jdk/incubator/foreign/Addressable +header extends java/lang/Object sealed true flags 601 + +class name jdk/incubator/foreign/CLinker +header extends java/lang/Object implements jdk/incubator/foreign/SymbolLookup sealed true flags 601 +-field name C_CHAR descriptor Ljdk/incubator/foreign/ValueLayout; +-field name C_SHORT descriptor Ljdk/incubator/foreign/ValueLayout; +-field name C_INT descriptor Ljdk/incubator/foreign/ValueLayout; +-field name C_LONG descriptor Ljdk/incubator/foreign/ValueLayout; +-field name C_LONG_LONG descriptor Ljdk/incubator/foreign/ValueLayout; +-field name C_FLOAT descriptor Ljdk/incubator/foreign/ValueLayout; +-field name C_DOUBLE descriptor Ljdk/incubator/foreign/ValueLayout; +-field name C_POINTER descriptor Ljdk/incubator/foreign/ValueLayout; +-field name C_VA_LIST descriptor Ljdk/incubator/foreign/MemoryLayout; +-method name downcallHandle descriptor (Ljdk/incubator/foreign/Addressable;Ljava/lang/invoke/MethodType;Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodHandle; +-method name asVarArg descriptor (Ljdk/incubator/foreign/MemoryLayout;)Ljdk/incubator/foreign/MemoryLayout; +-method name toJavaString descriptor (Ljdk/incubator/foreign/MemorySegment;)Ljava/lang/String; +-method name getInstance descriptor ()Ljdk/incubator/foreign/CLinker; +-method name systemLookup descriptor ()Ljdk/incubator/foreign/SymbolLookup; +-method name downcallHandle descriptor (Ljdk/incubator/foreign/Addressable;Ljdk/incubator/foreign/SegmentAllocator;Ljava/lang/invoke/MethodType;Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodHandle; +-method name downcallHandle descriptor (Ljava/lang/invoke/MethodType;Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodHandle; +-method name upcallStub descriptor (Ljava/lang/invoke/MethodHandle;Ljdk/incubator/foreign/FunctionDescriptor;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/MemoryAddress; +-method name toCString descriptor (Ljava/lang/String;Ljdk/incubator/foreign/SegmentAllocator;)Ljdk/incubator/foreign/MemorySegment; +-method name toCString descriptor (Ljava/lang/String;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/MemorySegment; +-method name toJavaString descriptor (Ljdk/incubator/foreign/MemoryAddress;)Ljava/lang/String; +-method name allocateMemory descriptor (J)Ljdk/incubator/foreign/MemoryAddress; +-method name freeMemory descriptor (Ljdk/incubator/foreign/MemoryAddress;)V +method name systemCLinker descriptor ()Ljdk/incubator/foreign/CLinker; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name lookup descriptor (Ljava/lang/String;)Ljava/util/Optional; flags 1 signature (Ljava/lang/String;)Ljava/util/Optional; +method name downcallHandle descriptor (Ljdk/incubator/foreign/NativeSymbol;Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodHandle; flags 1 +method name downcallHandle descriptor (Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodHandle; flags 401 +method name upcallStub descriptor (Ljava/lang/invoke/MethodHandle;Ljdk/incubator/foreign/FunctionDescriptor;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/NativeSymbol; flags 401 +method name downcallType descriptor (Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodType; flags 9 +method name upcallType descriptor (Ljdk/incubator/foreign/FunctionDescriptor;)Ljava/lang/invoke/MethodType; flags 9 + +-class name jdk/incubator/foreign/CLinker$TypeKind + +-class name jdk/incubator/foreign/CLinker$VaList + +-class name jdk/incubator/foreign/CLinker$VaList$Builder + +class name jdk/incubator/foreign/FunctionDescriptor +header extends java/lang/Object implements java/lang/constant/Constable sealed true flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-field name TRIVIAL_ATTRIBUTE_NAME descriptor Ljava/lang/String; +-method name attribute descriptor (Ljava/lang/String;)Ljava/util/Optional; +-method name attributes descriptor ()Ljava/util/stream/Stream; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/FunctionDescriptor; +-method name withAppendedArgumentLayouts descriptor ([Ljdk/incubator/foreign/MemoryLayout;)Ljdk/incubator/foreign/FunctionDescriptor; +-method name withReturnLayout descriptor (Ljdk/incubator/foreign/MemoryLayout;)Ljdk/incubator/foreign/FunctionDescriptor; +-method name withVoidReturnLayout descriptor ()Ljdk/incubator/foreign/FunctionDescriptor; +method name asVariadic descriptor ([Ljdk/incubator/foreign/MemoryLayout;)Ljdk/incubator/foreign/FunctionDescriptor; flags 81 +method name firstVariadicArgumentIndex descriptor ()I flags 1 +method name appendArgumentLayouts descriptor ([Ljdk/incubator/foreign/MemoryLayout;)Ljdk/incubator/foreign/FunctionDescriptor; flags 81 +method name insertArgumentLayouts descriptor (I[Ljdk/incubator/foreign/MemoryLayout;)Ljdk/incubator/foreign/FunctionDescriptor; flags 81 +method name changeReturnLayout descriptor (Ljdk/incubator/foreign/MemoryLayout;)Ljdk/incubator/foreign/FunctionDescriptor; flags 1 +method name dropReturnLayout descriptor ()Ljdk/incubator/foreign/FunctionDescriptor; flags 1 + +class name jdk/incubator/foreign/GroupLayout +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/GroupLayout; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/AbstractLayout; +-method name attributes descriptor ()Ljava/util/stream/Stream; +-method name attribute descriptor (Ljava/lang/String;)Ljava/util/Optional; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/MemoryLayout; +method name byteSize descriptor ()J flags 1041 + +-class name jdk/incubator/foreign/MemoryAccess + +class name jdk/incubator/foreign/MemoryAddress +header extends java/lang/Object implements jdk/incubator/foreign/Addressable sealed true flags 601 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfByte outerClass jdk/incubator/foreign/ValueLayout innerClassName OfByte flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfBoolean outerClass jdk/incubator/foreign/ValueLayout innerClassName OfBoolean flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfChar outerClass jdk/incubator/foreign/ValueLayout innerClassName OfChar flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfShort outerClass jdk/incubator/foreign/ValueLayout innerClassName OfShort flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfInt outerClass jdk/incubator/foreign/ValueLayout innerClassName OfInt flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfFloat outerClass jdk/incubator/foreign/ValueLayout innerClassName OfFloat flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfLong outerClass jdk/incubator/foreign/ValueLayout innerClassName OfLong flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfDouble outerClass jdk/incubator/foreign/ValueLayout innerClassName OfDouble flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfAddress outerClass jdk/incubator/foreign/ValueLayout innerClassName OfAddress flags 19 +-method name address descriptor ()Ljdk/incubator/foreign/MemoryAddress; +-method name segmentOffset descriptor (Ljdk/incubator/foreign/MemorySegment;)J +-method name scope descriptor ()Ljdk/incubator/foreign/ResourceScope; +-method name asSegment descriptor (JLjdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/MemorySegment; +-method name asSegment descriptor (JLjava/lang/Runnable;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/MemorySegment; +-method name isNative descriptor ()Z +method name getUtf8String descriptor (J)Ljava/lang/String; flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name setUtf8String descriptor (JLjava/lang/String;)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfByte;J)B flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfByte;JB)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfBoolean;J)Z flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfBoolean;JZ)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;J)C flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;JC)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;J)S flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;JS)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;J)I flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;JI)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;J)F flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;JF)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;J)J flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;JJ)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;J)D flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;JD)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;J)Ljdk/incubator/foreign/MemoryAddress; flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;JLjdk/incubator/foreign/Addressable;)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;J)C flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;JC)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;J)S flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;JS)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;J)I flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;JI)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;J)F flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;JF)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;J)J flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;JJ)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;J)D flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;JD)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;J)Ljdk/incubator/foreign/MemoryAddress; flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;JLjdk/incubator/foreign/Addressable;)V flags 401 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; + +class name jdk/incubator/foreign/MemoryHandles +-method name varHandle descriptor (Ljava/lang/Class;Ljava/nio/ByteOrder;)Ljava/lang/invoke/VarHandle; +-method name varHandle descriptor (Ljava/lang/Class;JLjava/nio/ByteOrder;)Ljava/lang/invoke/VarHandle; +-method name asAddressVarHandle descriptor (Ljava/lang/invoke/VarHandle;)Ljava/lang/invoke/VarHandle; +method name varHandle descriptor (Ljdk/incubator/foreign/ValueLayout;)Ljava/lang/invoke/VarHandle; flags 9 + +class name jdk/incubator/foreign/MemoryLayout +header extends java/lang/Object implements java/lang/constant/Constable nestMembers jdk/incubator/foreign/MemoryLayout$PathElement sealed true flags 601 +innerclass innerClass jdk/incubator/foreign/MemoryLayout$PathElement outerClass jdk/incubator/foreign/MemoryLayout innerClassName PathElement flags 609 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfBoolean outerClass jdk/incubator/foreign/ValueLayout innerClassName OfBoolean flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfChar outerClass jdk/incubator/foreign/ValueLayout innerClassName OfChar flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfByte outerClass jdk/incubator/foreign/ValueLayout innerClassName OfByte flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfShort outerClass jdk/incubator/foreign/ValueLayout innerClassName OfShort flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfInt outerClass jdk/incubator/foreign/ValueLayout innerClassName OfInt flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfFloat outerClass jdk/incubator/foreign/ValueLayout innerClassName OfFloat flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfLong outerClass jdk/incubator/foreign/ValueLayout innerClassName OfLong flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfDouble outerClass jdk/incubator/foreign/ValueLayout innerClassName OfDouble flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfAddress outerClass jdk/incubator/foreign/ValueLayout innerClassName OfAddress flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-field name LAYOUT_NAME descriptor Ljava/lang/String; +-method name byteSize descriptor ()J +-method name varHandle descriptor (Ljava/lang/Class;[Ljdk/incubator/foreign/MemoryLayout$PathElement;)Ljava/lang/invoke/VarHandle; +-method name attribute descriptor (Ljava/lang/String;)Ljava/util/Optional; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/MemoryLayout; +-method name attributes descriptor ()Ljava/util/stream/Stream; +-method name valueLayout descriptor (JLjava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; +method name byteSize descriptor ()J flags 401 +method name varHandle descriptor ([Ljdk/incubator/foreign/MemoryLayout$PathElement;)Ljava/lang/invoke/VarHandle; flags 81 +method name valueLayout descriptor (Ljava/lang/Class;Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 9 signature (Ljava/lang/Class<*>;Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; + +class name jdk/incubator/foreign/MemoryLayout$PathElement +header extends java/lang/Object nestHost jdk/incubator/foreign/MemoryLayout sealed true flags 601 +innerclass innerClass jdk/incubator/foreign/MemoryLayout$PathElement outerClass jdk/incubator/foreign/MemoryLayout innerClassName PathElement flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +-class name jdk/incubator/foreign/MemoryLayouts + +class name jdk/incubator/foreign/MemorySegment +header extends java/lang/Object implements jdk/incubator/foreign/Addressable sealed true flags 601 +innerclass innerClass java/nio/channels/FileChannel$MapMode outerClass java/nio/channels/FileChannel innerClassName MapMode flags 9 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfByte outerClass jdk/incubator/foreign/ValueLayout innerClassName OfByte flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfBoolean outerClass jdk/incubator/foreign/ValueLayout innerClassName OfBoolean flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfChar outerClass jdk/incubator/foreign/ValueLayout innerClassName OfChar flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfShort outerClass jdk/incubator/foreign/ValueLayout innerClassName OfShort flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfInt outerClass jdk/incubator/foreign/ValueLayout innerClassName OfInt flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfFloat outerClass jdk/incubator/foreign/ValueLayout innerClassName OfFloat flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfLong outerClass jdk/incubator/foreign/ValueLayout innerClassName OfLong flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfDouble outerClass jdk/incubator/foreign/ValueLayout innerClassName OfDouble flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfAddress outerClass jdk/incubator/foreign/ValueLayout innerClassName OfAddress flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name toByteArray descriptor ()[B +-method name copyFrom descriptor (Ljdk/incubator/foreign/MemorySegment;)V +-method name asSlice descriptor (Ljdk/incubator/foreign/MemoryAddress;J)Ljdk/incubator/foreign/MemorySegment; +-method name asSlice descriptor (Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemorySegment; +-method name toShortArray descriptor ()[S +-method name toCharArray descriptor ()[C +-method name toIntArray descriptor ()[I +-method name toFloatArray descriptor ()[F +-method name toLongArray descriptor ()[J +-method name toDoubleArray descriptor ()[D +-method name asReadOnly descriptor ()Ljdk/incubator/foreign/MemorySegment; +-method name isReadOnly descriptor ()Z +-method name globalNativeSegment descriptor ()Ljdk/incubator/foreign/MemorySegment; +method name asReadOnly descriptor ()Ljdk/incubator/foreign/MemorySegment; flags 401 +method name isReadOnly descriptor ()Z flags 401 +method name asOverlappingSlice descriptor (Ljdk/incubator/foreign/MemorySegment;)Ljdk/incubator/foreign/MemorySegment; flags 401 +method name segmentOffset descriptor (Ljdk/incubator/foreign/MemorySegment;)J flags 401 +method name copyFrom descriptor (Ljdk/incubator/foreign/MemorySegment;)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name toArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfByte;)[B flags 401 +method name toArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;)[S flags 401 +method name toArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;)[C flags 401 +method name toArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;)[I flags 401 +method name toArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;)[F flags 401 +method name toArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;)[J flags 401 +method name toArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;)[D flags 401 +method name getUtf8String descriptor (J)Ljava/lang/String; flags 1 +method name setUtf8String descriptor (JLjava/lang/String;)V flags 1 +method name ofAddress descriptor (Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/MemorySegment; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name copy descriptor (Ljdk/incubator/foreign/MemorySegment;JLjdk/incubator/foreign/MemorySegment;JJ)V flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name copy descriptor (Ljdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/ValueLayout;JLjdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/ValueLayout;JJ)V flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfByte;J)B flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfByte;JB)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfBoolean;J)Z flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfBoolean;JZ)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;J)C flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;JC)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;J)S flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;JS)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;J)I flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;JI)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;J)F flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;JF)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;J)J flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;JJ)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;J)D flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;JD)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name get descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;J)Ljdk/incubator/foreign/MemoryAddress; flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name set descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;JLjdk/incubator/foreign/Addressable;)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;J)C flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;JC)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;J)S flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;JS)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;J)I flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;JI)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;J)F flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;JF)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;J)J flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;JJ)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;J)D flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;JD)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name getAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;J)Ljdk/incubator/foreign/MemoryAddress; flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name setAtIndex descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;JLjdk/incubator/foreign/Addressable;)V flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name copy descriptor (Ljdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/ValueLayout;JLjava/lang/Object;II)V flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name copy descriptor (Ljava/lang/Object;ILjdk/incubator/foreign/MemorySegment;Ljdk/incubator/foreign/ValueLayout;JI)V flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; + +class name jdk/incubator/foreign/NativeSymbol +header extends java/lang/Object implements jdk/incubator/foreign/Addressable sealed true flags 601 +method name name descriptor ()Ljava/lang/String; flags 401 +method name scope descriptor ()Ljdk/incubator/foreign/ResourceScope; flags 401 +method name address descriptor ()Ljdk/incubator/foreign/MemoryAddress; flags 401 +method name ofAddress descriptor (Ljava/lang/String;Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/NativeSymbol; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; + +class name jdk/incubator/foreign/ResourceScope +header extends java/lang/Object implements java/lang/AutoCloseable sealed true flags 601 +-method name isImplicit descriptor ()Z +-method name acquire descriptor ()Ljdk/incubator/foreign/ResourceScope$Handle; +-method name release descriptor (Ljdk/incubator/foreign/ResourceScope$Handle;)V +method name keepAlive descriptor (Ljdk/incubator/foreign/ResourceScope;)V flags 401 + +-class name jdk/incubator/foreign/ResourceScope$Handle + +class name jdk/incubator/foreign/SegmentAllocator +header extends java/lang/Object flags 601 runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass jdk/incubator/foreign/MemoryLayout$PathElement outerClass jdk/incubator/foreign/MemoryLayout innerClassName PathElement flags 609 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfByte outerClass jdk/incubator/foreign/ValueLayout innerClassName OfByte flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfChar outerClass jdk/incubator/foreign/ValueLayout innerClassName OfChar flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfShort outerClass jdk/incubator/foreign/ValueLayout innerClassName OfShort flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfInt outerClass jdk/incubator/foreign/ValueLayout innerClassName OfInt flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfFloat outerClass jdk/incubator/foreign/ValueLayout innerClassName OfFloat flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfLong outerClass jdk/incubator/foreign/ValueLayout innerClassName OfLong flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfDouble outerClass jdk/incubator/foreign/ValueLayout innerClassName OfDouble flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfAddress outerClass jdk/incubator/foreign/ValueLayout innerClassName OfAddress flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout;B)Ljdk/incubator/foreign/MemorySegment; +-method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout;C)Ljdk/incubator/foreign/MemorySegment; +-method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout;S)Ljdk/incubator/foreign/MemorySegment; +-method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout;I)Ljdk/incubator/foreign/MemorySegment; +-method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout;F)Ljdk/incubator/foreign/MemorySegment; +-method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout;J)Ljdk/incubator/foreign/MemorySegment; +-method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout;D)Ljdk/incubator/foreign/MemorySegment; +-method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout;Ljdk/incubator/foreign/Addressable;)Ljdk/incubator/foreign/MemorySegment; +-method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout;[B)Ljdk/incubator/foreign/MemorySegment; +-method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout;[S)Ljdk/incubator/foreign/MemorySegment; +-method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout;[C)Ljdk/incubator/foreign/MemorySegment; +-method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout;[I)Ljdk/incubator/foreign/MemorySegment; +-method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout;[F)Ljdk/incubator/foreign/MemorySegment; +-method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout;[J)Ljdk/incubator/foreign/MemorySegment; +-method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout;[D)Ljdk/incubator/foreign/MemorySegment; +-method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout;[Ljdk/incubator/foreign/Addressable;)Ljdk/incubator/foreign/MemorySegment; +-method name arenaAllocator descriptor (JLjdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/SegmentAllocator; +-method name arenaAllocator descriptor (Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/SegmentAllocator; +-method name ofSegment descriptor (Ljdk/incubator/foreign/MemorySegment;)Ljdk/incubator/foreign/SegmentAllocator; +-method name ofScope descriptor (Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/SegmentAllocator; +method name allocateUtf8String descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout$OfByte;B)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;C)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;S)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;I)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;F)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;J)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;D)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocate descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;Ljdk/incubator/foreign/Addressable;)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfByte;[B)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfShort;[S)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfChar;[C)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;[I)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfFloat;[F)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;[J)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name allocateArray descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;[D)Ljdk/incubator/foreign/MemorySegment; flags 1 +method name newNativeArena descriptor (Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/SegmentAllocator; flags 9 +method name newNativeArena descriptor (JLjdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/SegmentAllocator; flags 9 +method name newNativeArena descriptor (JJLjdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/SegmentAllocator; flags 9 +method name prefixAllocator descriptor (Ljdk/incubator/foreign/MemorySegment;)Ljdk/incubator/foreign/SegmentAllocator; flags 9 +method name nativeAllocator descriptor (Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/SegmentAllocator; flags 9 +method name implicitAllocator descriptor ()Ljdk/incubator/foreign/SegmentAllocator; flags 9 + +class name jdk/incubator/foreign/SequenceLayout +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/SequenceLayout; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/AbstractLayout; +-method name attributes descriptor ()Ljava/util/stream/Stream; +-method name attribute descriptor (Ljava/lang/String;)Ljava/util/Optional; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/MemoryLayout; +method name byteSize descriptor ()J flags 1041 + +class name jdk/incubator/foreign/SymbolLookup +-method name lookup descriptor (Ljava/lang/String;)Ljava/util/Optional; +method name lookup descriptor (Ljava/lang/String;)Ljava/util/Optional; flags 401 signature (Ljava/lang/String;)Ljava/util/Optional; + +class name jdk/incubator/foreign/VaList +header extends java/lang/Object implements jdk/incubator/foreign/Addressable nestMembers jdk/incubator/foreign/VaList$Builder sealed true flags 601 +innerclass innerClass jdk/incubator/foreign/VaList$Builder outerClass jdk/incubator/foreign/VaList innerClassName Builder flags 609 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfInt outerClass jdk/incubator/foreign/ValueLayout innerClassName OfInt flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfLong outerClass jdk/incubator/foreign/ValueLayout innerClassName OfLong flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfDouble outerClass jdk/incubator/foreign/ValueLayout innerClassName OfDouble flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfAddress outerClass jdk/incubator/foreign/ValueLayout innerClassName OfAddress flags 19 +method name nextVarg descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;)I flags 401 +method name nextVarg descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;)J flags 401 +method name nextVarg descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;)D flags 401 +method name nextVarg descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;)Ljdk/incubator/foreign/MemoryAddress; flags 401 +method name nextVarg descriptor (Ljdk/incubator/foreign/GroupLayout;Ljdk/incubator/foreign/SegmentAllocator;)Ljdk/incubator/foreign/MemorySegment; flags 401 +method name skip descriptor ([Ljdk/incubator/foreign/MemoryLayout;)V flags 481 +method name scope descriptor ()Ljdk/incubator/foreign/ResourceScope; flags 401 +method name copy descriptor ()Ljdk/incubator/foreign/VaList; flags 401 +method name address descriptor ()Ljdk/incubator/foreign/MemoryAddress; flags 401 +method name ofAddress descriptor (Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/VaList; flags 9 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive; +method name make descriptor (Ljava/util/function/Consumer;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/VaList; flags 9 signature (Ljava/util/function/Consumer;Ljdk/incubator/foreign/ResourceScope;)Ljdk/incubator/foreign/VaList; +method name empty descriptor ()Ljdk/incubator/foreign/VaList; flags 9 + +class name jdk/incubator/foreign/VaList$Builder +header extends java/lang/Object nestHost jdk/incubator/foreign/VaList sealed true flags 601 +innerclass innerClass jdk/incubator/foreign/VaList$Builder outerClass jdk/incubator/foreign/VaList innerClassName Builder flags 609 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfInt outerClass jdk/incubator/foreign/ValueLayout innerClassName OfInt flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfLong outerClass jdk/incubator/foreign/ValueLayout innerClassName OfLong flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfDouble outerClass jdk/incubator/foreign/ValueLayout innerClassName OfDouble flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfAddress outerClass jdk/incubator/foreign/ValueLayout innerClassName OfAddress flags 19 +method name addVarg descriptor (Ljdk/incubator/foreign/ValueLayout$OfInt;I)Ljdk/incubator/foreign/VaList$Builder; flags 401 +method name addVarg descriptor (Ljdk/incubator/foreign/ValueLayout$OfLong;J)Ljdk/incubator/foreign/VaList$Builder; flags 401 +method name addVarg descriptor (Ljdk/incubator/foreign/ValueLayout$OfDouble;D)Ljdk/incubator/foreign/VaList$Builder; flags 401 +method name addVarg descriptor (Ljdk/incubator/foreign/ValueLayout$OfAddress;Ljdk/incubator/foreign/Addressable;)Ljdk/incubator/foreign/VaList$Builder; flags 401 +method name addVarg descriptor (Ljdk/incubator/foreign/GroupLayout;Ljdk/incubator/foreign/MemorySegment;)Ljdk/incubator/foreign/VaList$Builder; flags 401 + +class name jdk/incubator/foreign/ValueLayout +header extends jdk/incubator/foreign/AbstractLayout implements jdk/incubator/foreign/MemoryLayout nestMembers jdk/incubator/foreign/ValueLayout$OfAddress,jdk/incubator/foreign/ValueLayout$OfDouble,jdk/incubator/foreign/ValueLayout$OfLong,jdk/incubator/foreign/ValueLayout$OfFloat,jdk/incubator/foreign/ValueLayout$OfInt,jdk/incubator/foreign/ValueLayout$OfShort,jdk/incubator/foreign/ValueLayout$OfChar,jdk/incubator/foreign/ValueLayout$OfByte,jdk/incubator/foreign/ValueLayout$OfBoolean sealed true flags 21 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfAddress outerClass jdk/incubator/foreign/ValueLayout innerClassName OfAddress flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfByte outerClass jdk/incubator/foreign/ValueLayout innerClassName OfByte flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfBoolean outerClass jdk/incubator/foreign/ValueLayout innerClassName OfBoolean flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfChar outerClass jdk/incubator/foreign/ValueLayout innerClassName OfChar flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfShort outerClass jdk/incubator/foreign/ValueLayout innerClassName OfShort flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfInt outerClass jdk/incubator/foreign/ValueLayout innerClassName OfInt flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfLong outerClass jdk/incubator/foreign/ValueLayout innerClassName OfLong flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfFloat outerClass jdk/incubator/foreign/ValueLayout innerClassName OfFloat flags 19 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfDouble outerClass jdk/incubator/foreign/ValueLayout innerClassName OfDouble flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/ValueLayout; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/AbstractLayout; +-method name attributes descriptor ()Ljava/util/stream/Stream; +-method name attribute descriptor (Ljava/lang/String;)Ljava/util/Optional; +-method name withAttribute descriptor (Ljava/lang/String;Ljava/lang/constant/Constable;)Ljdk/incubator/foreign/MemoryLayout; +field name ADDRESS descriptor Ljdk/incubator/foreign/ValueLayout$OfAddress; flags 19 +field name JAVA_BYTE descriptor Ljdk/incubator/foreign/ValueLayout$OfByte; flags 19 +field name JAVA_BOOLEAN descriptor Ljdk/incubator/foreign/ValueLayout$OfBoolean; flags 19 +field name JAVA_CHAR descriptor Ljdk/incubator/foreign/ValueLayout$OfChar; flags 19 +field name JAVA_SHORT descriptor Ljdk/incubator/foreign/ValueLayout$OfShort; flags 19 +field name JAVA_INT descriptor Ljdk/incubator/foreign/ValueLayout$OfInt; flags 19 +field name JAVA_LONG descriptor Ljdk/incubator/foreign/ValueLayout$OfLong; flags 19 +field name JAVA_FLOAT descriptor Ljdk/incubator/foreign/ValueLayout$OfFloat; flags 19 +field name JAVA_DOUBLE descriptor Ljdk/incubator/foreign/ValueLayout$OfDouble; flags 19 +method name carrier descriptor ()Ljava/lang/Class; flags 1 signature ()Ljava/lang/Class<*>; +method name byteSize descriptor ()J flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfAddress +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfAddress outerClass jdk/incubator/foreign/ValueLayout innerClassName OfAddress flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfAddress; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfAddress; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfAddress; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfBoolean +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfBoolean outerClass jdk/incubator/foreign/ValueLayout innerClassName OfBoolean flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfBoolean; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfBoolean; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfBoolean; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfByte +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfByte outerClass jdk/incubator/foreign/ValueLayout innerClassName OfByte flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfByte; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfByte; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfByte; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfChar +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfChar outerClass jdk/incubator/foreign/ValueLayout innerClassName OfChar flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfChar; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfChar; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfChar; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfDouble +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfDouble outerClass jdk/incubator/foreign/ValueLayout innerClassName OfDouble flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfDouble; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfDouble; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfDouble; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfFloat +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfFloat outerClass jdk/incubator/foreign/ValueLayout innerClassName OfFloat flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfFloat; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfFloat; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfFloat; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfInt +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfInt outerClass jdk/incubator/foreign/ValueLayout innerClassName OfInt flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfInt; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfInt; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfInt; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfLong +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfLong outerClass jdk/incubator/foreign/ValueLayout innerClassName OfLong flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfLong; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfLong; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfLong; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + +class name jdk/incubator/foreign/ValueLayout$OfShort +header extends jdk/incubator/foreign/ValueLayout nestHost jdk/incubator/foreign/ValueLayout flags 31 +innerclass innerClass jdk/incubator/foreign/ValueLayout$OfShort outerClass jdk/incubator/foreign/ValueLayout innerClassName OfShort flags 19 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout$OfShort; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout$OfShort; flags 1 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout$OfShort; flags 1 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withOrder descriptor (Ljava/nio/ByteOrder;)Ljdk/incubator/foreign/ValueLayout; flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/MemoryLayout; flags 1041 +method name isPadding descriptor ()Z flags 1041 +method name bitSize descriptor ()J flags 1041 +method name hasSize descriptor ()Z flags 1041 +method name byteSize descriptor ()J flags 1041 +method name withBitAlignment descriptor (J)Ljdk/incubator/foreign/AbstractLayout; flags 1041 +method name withName descriptor (Ljava/lang/String;)Ljdk/incubator/foreign/AbstractLayout; flags 1041 + diff --git a/make/data/symbols/jdk.incubator.vector-G.sym.txt b/make/data/symbols/jdk.incubator.vector-G.sym.txt index dec09658dc0d864278ee73557c011e410fca5ef9..35c8da2c622bb025f1a4250a6160029b57a87419 100644 --- a/make/data/symbols/jdk.incubator.vector-G.sym.txt +++ b/make/data/symbols/jdk.incubator.vector-G.sym.txt @@ -32,6 +32,8 @@ header exports jdk/incubator/vector requires name\u0020;java.base\u0020;flags\u0 class name jdk/incubator/vector/AbstractVector header extends jdk/incubator/vector/Vector flags 420 signature Ljdk/incubator/vector/Vector; innerclass innerClass jdk/incubator/vector/VectorOperators$Conversion outerClass jdk/incubator/vector/VectorOperators innerClassName Conversion flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 @@ -55,6 +57,7 @@ method name slice descriptor (I)Ljdk/incubator/vector/Vector; flags 1041 class name jdk/incubator/vector/ByteVector header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 @@ -230,6 +233,7 @@ method name slice descriptor (I)Ljdk/incubator/vector/AbstractVector; flags 1041 class name jdk/incubator/vector/DoubleVector header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 @@ -402,6 +406,7 @@ method name slice descriptor (I)Ljdk/incubator/vector/AbstractVector; flags 1041 class name jdk/incubator/vector/FloatVector header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 @@ -574,6 +579,7 @@ method name slice descriptor (I)Ljdk/incubator/vector/AbstractVector; flags 1041 class name jdk/incubator/vector/IntVector header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 @@ -750,6 +756,7 @@ method name slice descriptor (I)Ljdk/incubator/vector/AbstractVector; flags 1041 class name jdk/incubator/vector/LongVector header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 @@ -919,6 +926,7 @@ method name slice descriptor (I)Ljdk/incubator/vector/AbstractVector; flags 1041 class name jdk/incubator/vector/ShortVector header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 @@ -1184,6 +1192,7 @@ method name hashCode descriptor ()I flags 401 class name jdk/incubator/vector/VectorMask header extends jdk/internal/vm/vector/VectorSupport$VectorMask flags 421 signature Ljdk/internal/vm/vector/VectorSupport$VectorMask; innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 method name vectorSpecies descriptor ()Ljdk/incubator/vector/VectorSpecies; flags 401 signature ()Ljdk/incubator/vector/VectorSpecies; method name length descriptor ()I flags 11 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; diff --git a/make/data/symbols/jdk.incubator.vector-H.sym.txt b/make/data/symbols/jdk.incubator.vector-H.sym.txt index a815726e54b3835248f19404d7ebd8971772591a..b83ff570747edecaee54d7782258e3d9c880e4a5 100644 --- a/make/data/symbols/jdk.incubator.vector-H.sym.txt +++ b/make/data/symbols/jdk.incubator.vector-H.sym.txt @@ -27,6 +27,20 @@ # ########################################################## # class name jdk/incubator/vector/ByteVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 method name fromBooleanArray descriptor (Ljdk/incubator/vector/VectorSpecies;[ZI)Ljdk/incubator/vector/ByteVector; flags 9 signature (Ljdk/incubator/vector/VectorSpecies;[ZI)Ljdk/incubator/vector/ByteVector; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; method name fromBooleanArray descriptor (Ljdk/incubator/vector/VectorSpecies;[ZILjdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; flags 9 signature (Ljdk/incubator/vector/VectorSpecies;[ZILjdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; method name fromBooleanArray descriptor (Ljdk/incubator/vector/VectorSpecies;[ZI[II)Ljdk/incubator/vector/ByteVector; flags 9 signature (Ljdk/incubator/vector/VectorSpecies;[ZI[II)Ljdk/incubator/vector/ByteVector; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; @@ -36,7 +50,85 @@ method name intoBooleanArray descriptor ([ZILjdk/incubator/vector/VectorMask;)V method name intoBooleanArray descriptor ([ZI[II)V flags 11 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; method name intoBooleanArray descriptor ([ZI[IILjdk/incubator/vector/VectorMask;)V flags 11 signature ([ZI[IILjdk/incubator/vector/VectorMask;)V runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +class name jdk/incubator/vector/DoubleVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/incubator/vector/FloatVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/incubator/vector/IntVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/incubator/vector/LongVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + class name jdk/incubator/vector/ShortVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 method name fromCharArray descriptor (Ljdk/incubator/vector/VectorSpecies;[CI)Ljdk/incubator/vector/ShortVector; flags 9 signature (Ljdk/incubator/vector/VectorSpecies;[CI)Ljdk/incubator/vector/ShortVector; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; method name fromCharArray descriptor (Ljdk/incubator/vector/VectorSpecies;[CILjdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; flags 9 signature (Ljdk/incubator/vector/VectorSpecies;[CILjdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; method name fromCharArray descriptor (Ljdk/incubator/vector/VectorSpecies;[CI[II)Ljdk/incubator/vector/ShortVector; flags 9 signature (Ljdk/incubator/vector/VectorSpecies;[CI[II)Ljdk/incubator/vector/ShortVector; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; diff --git a/make/data/symbols/jdk.incubator.vector-I.sym.txt b/make/data/symbols/jdk.incubator.vector-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..bb95434d8f92887d7d15fd189222a5235d27e220 --- /dev/null +++ b/make/data/symbols/jdk.incubator.vector-I.sym.txt @@ -0,0 +1,209 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/incubator/vector/ByteVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; +-method name compare descriptor (Ljdk/incubator/vector/VectorOperators$Comparison;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/VectorMask; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ByteVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 + +class name jdk/incubator/vector/DoubleVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; +-method name compare descriptor (Ljdk/incubator/vector/VectorOperators$Comparison;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/VectorMask; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/DoubleVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 + +class name jdk/incubator/vector/FloatVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; +-method name compare descriptor (Ljdk/incubator/vector/VectorOperators$Comparison;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/VectorMask; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/FloatVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 + +class name jdk/incubator/vector/IntVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; +-method name compare descriptor (Ljdk/incubator/vector/VectorOperators$Comparison;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/VectorMask; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/IntVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 + +class name jdk/incubator/vector/LongVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; +-method name compare descriptor (Ljdk/incubator/vector/VectorOperators$Comparison;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/VectorMask; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/LongVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 + +class name jdk/incubator/vector/ShortVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; +-method name compare descriptor (Ljdk/incubator/vector/VectorOperators$Comparison;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/VectorMask; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +-method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; flags 401 signature (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/ShortVector; +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Ternary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Binary;Ljdk/incubator/vector/Vector;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 +method name lanewise descriptor (Ljdk/incubator/vector/VectorOperators$Unary;Ljdk/incubator/vector/VectorMask;)Ljdk/incubator/vector/Vector; flags 1041 + +class name jdk/incubator/vector/VectorMask +header extends jdk/internal/vm/vector/VectorSupport$VectorMask flags 421 signature Ljdk/internal/vm/vector/VectorSupport$VectorMask; +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/make/data/symbols/jdk.jartool-I.sym.txt b/make/data/symbols/jdk.jartool-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..9133449be101c8ec2bfb21b2236c7bebe56095ac --- /dev/null +++ b/make/data/symbols/jdk.jartool-I.sym.txt @@ -0,0 +1,31 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/security/jarsigner/JarSignerException +header extends java/lang/RuntimeException flags 21 + diff --git a/make/data/symbols/jdk.javadoc-H.sym.txt b/make/data/symbols/jdk.javadoc-H.sym.txt index b2ab2561f5c5a004ce9efdf761741c23bd46b948..d7d4a4c3779c29bf7e85113357d0a750c8fd831c 100644 --- a/make/data/symbols/jdk.javadoc-H.sym.txt +++ b/make/data/symbols/jdk.javadoc-H.sym.txt @@ -29,9 +29,9 @@ class name jdk/javadoc/doclet/Reporter header extends java/lang/Object flags 601 innerclass innerClass javax/tools/Diagnostic$Kind outerClass javax/tools/Diagnostic innerClassName Kind flags 4019 +method name print descriptor (Ljavax/tools/Diagnostic$Kind;Ljavax/tools/FileObject;IIILjava/lang/String;)V flags 1 method name getStandardWriter descriptor ()Ljava/io/PrintWriter; flags 1 method name getDiagnosticWriter descriptor ()Ljava/io/PrintWriter; flags 1 -method name print descriptor (Ljavax/tools/Diagnostic$Kind;Ljavax/tools/FileObject;IIILjava/lang/String;)V flags 1 class name jdk/javadoc/doclet/StandardDoclet header extends java/lang/Object implements jdk/javadoc/doclet/Doclet flags 21 diff --git a/make/data/symbols/jdk.javadoc-I.sym.txt b/make/data/symbols/jdk.javadoc-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..8c4ff94e5eb2f242688567b639bdb36837cb1600 --- /dev/null +++ b/make/data/symbols/jdk.javadoc-I.sym.txt @@ -0,0 +1,37 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/javadoc/doclet/Reporter +header extends java/lang/Object flags 601 +innerclass innerClass javax/tools/Diagnostic$Kind outerClass javax/tools/Diagnostic innerClassName Kind flags 4019 +method name print descriptor (Ljavax/tools/Diagnostic$Kind;Lcom/sun/source/util/DocTreePath;IIILjava/lang/String;)V flags 1 + +class name jdk/javadoc/doclet/StandardDoclet +header extends java/lang/Object implements jdk/javadoc/doclet/Doclet flags 21 +innerclass innerClass jdk/javadoc/doclet/Doclet$Option outerClass jdk/javadoc/doclet/Doclet innerClassName Option flags 609 + diff --git a/make/modules/jdk.unsupported.desktop/Java.gmk b/make/data/symbols/jdk.jconsole-I.sym.txt similarity index 76% rename from make/modules/jdk.unsupported.desktop/Java.gmk rename to make/data/symbols/jdk.jconsole-I.sym.txt index f892ebeb84c171d99d372a9203ace9abdbc16e5a..79977a63ab9300c5dfcf72010f18b355296793cb 100644 --- a/make/modules/jdk.unsupported.desktop/Java.gmk +++ b/make/data/symbols/jdk.jconsole-I.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. # 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,5 +22,10 @@ # or visit www.oracle.com if you need additional information or have any # questions. # +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/tools/jconsole/JConsolePlugin +header extends java/lang/Object flags 421 -DISABLED_WARNINGS_java += missing-explicit-ctor diff --git a/make/data/symbols/jdk.jdi-I.sym.txt b/make/data/symbols/jdk.jdi-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..55fc5be41abd4bc8a1a843169358988551e0410b --- /dev/null +++ b/make/data/symbols/jdk.jdi-I.sym.txt @@ -0,0 +1,395 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/jdi/AbsentInformationException +header extends java/lang/Exception flags 21 + +class name com/sun/jdi/Accessible +header extends java/lang/Object flags 601 + +class name com/sun/jdi/ArrayReference +header extends java/lang/Object implements com/sun/jdi/ObjectReference flags 601 + +class name com/sun/jdi/ArrayType +header extends java/lang/Object implements com/sun/jdi/ReferenceType flags 601 + +class name com/sun/jdi/BooleanType +header extends java/lang/Object implements com/sun/jdi/PrimitiveType flags 601 + +class name com/sun/jdi/BooleanValue +header extends java/lang/Object implements com/sun/jdi/PrimitiveValue flags 601 + +class name com/sun/jdi/Bootstrap +header extends java/lang/Object flags 21 + +class name com/sun/jdi/ByteType +header extends java/lang/Object implements com/sun/jdi/PrimitiveType flags 601 + +class name com/sun/jdi/ByteValue +header extends java/lang/Object implements com/sun/jdi/PrimitiveValue,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/PrimitiveValue;Ljava/lang/Comparable; + +class name com/sun/jdi/CharType +header extends java/lang/Object implements com/sun/jdi/PrimitiveType flags 601 + +class name com/sun/jdi/CharValue +header extends java/lang/Object implements com/sun/jdi/PrimitiveValue,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/PrimitiveValue;Ljava/lang/Comparable; + +class name com/sun/jdi/ClassLoaderReference +header extends java/lang/Object implements com/sun/jdi/ObjectReference flags 601 + +class name com/sun/jdi/ClassNotLoadedException +header extends java/lang/Exception flags 21 + +class name com/sun/jdi/ClassNotPreparedException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/ClassObjectReference +header extends java/lang/Object implements com/sun/jdi/ObjectReference flags 601 + +class name com/sun/jdi/ClassType +header extends java/lang/Object implements com/sun/jdi/ReferenceType flags 601 + +class name com/sun/jdi/DoubleType +header extends java/lang/Object implements com/sun/jdi/PrimitiveType flags 601 + +class name com/sun/jdi/DoubleValue +header extends java/lang/Object implements com/sun/jdi/PrimitiveValue,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/PrimitiveValue;Ljava/lang/Comparable; + +class name com/sun/jdi/Field +header extends java/lang/Object implements com/sun/jdi/TypeComponent,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/TypeComponent;Ljava/lang/Comparable; + +class name com/sun/jdi/FloatType +header extends java/lang/Object implements com/sun/jdi/PrimitiveType flags 601 + +class name com/sun/jdi/FloatValue +header extends java/lang/Object implements com/sun/jdi/PrimitiveValue,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/PrimitiveValue;Ljava/lang/Comparable; + +class name com/sun/jdi/IncompatibleThreadStateException +header extends java/lang/Exception flags 21 + +class name com/sun/jdi/InconsistentDebugInfoException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/IntegerType +header extends java/lang/Object implements com/sun/jdi/PrimitiveType flags 601 + +class name com/sun/jdi/IntegerValue +header extends java/lang/Object implements com/sun/jdi/PrimitiveValue,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/PrimitiveValue;Ljava/lang/Comparable; + +class name com/sun/jdi/InterfaceType +header extends java/lang/Object implements com/sun/jdi/ReferenceType flags 601 + +class name com/sun/jdi/InternalException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/InvalidCodeIndexException +header extends java/lang/RuntimeException flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated; + +class name com/sun/jdi/InvalidLineNumberException +header extends java/lang/RuntimeException flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated; + +class name com/sun/jdi/InvalidModuleException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/InvalidStackFrameException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/InvalidTypeException +header extends java/lang/Exception flags 21 + +class name com/sun/jdi/InvocationException +header extends java/lang/Exception flags 21 + +class name com/sun/jdi/JDIPermission +header extends java/security/BasicPermission flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/jdi/LocalVariable +header extends java/lang/Object implements com/sun/jdi/Mirror,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/Mirror;Ljava/lang/Comparable; + +class name com/sun/jdi/Locatable +header extends java/lang/Object flags 601 + +class name com/sun/jdi/Location +header extends java/lang/Object implements com/sun/jdi/Mirror,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/Mirror;Ljava/lang/Comparable; + +class name com/sun/jdi/LongType +header extends java/lang/Object implements com/sun/jdi/PrimitiveType flags 601 + +class name com/sun/jdi/LongValue +header extends java/lang/Object implements com/sun/jdi/PrimitiveValue,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/PrimitiveValue;Ljava/lang/Comparable; + +class name com/sun/jdi/Method +header extends java/lang/Object implements com/sun/jdi/TypeComponent,com/sun/jdi/Locatable,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/TypeComponent;Lcom/sun/jdi/Locatable;Ljava/lang/Comparable; + +class name com/sun/jdi/Mirror +header extends java/lang/Object flags 601 + +class name com/sun/jdi/ModuleReference +header extends java/lang/Object implements com/sun/jdi/ObjectReference flags 601 + +class name com/sun/jdi/MonitorInfo +header extends java/lang/Object implements com/sun/jdi/Mirror flags 601 + +class name com/sun/jdi/NativeMethodException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/ObjectCollectedException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/ObjectReference +header extends java/lang/Object implements com/sun/jdi/Value flags 601 + +class name com/sun/jdi/PathSearchingVirtualMachine +header extends java/lang/Object implements com/sun/jdi/VirtualMachine flags 601 + +class name com/sun/jdi/PrimitiveType +header extends java/lang/Object implements com/sun/jdi/Type flags 601 + +class name com/sun/jdi/PrimitiveValue +header extends java/lang/Object implements com/sun/jdi/Value flags 601 + +class name com/sun/jdi/ReferenceType +header extends java/lang/Object implements com/sun/jdi/Type,java/lang/Comparable,com/sun/jdi/Accessible flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/Type;Ljava/lang/Comparable;Lcom/sun/jdi/Accessible; + +class name com/sun/jdi/ShortType +header extends java/lang/Object implements com/sun/jdi/PrimitiveType flags 601 + +class name com/sun/jdi/ShortValue +header extends java/lang/Object implements com/sun/jdi/PrimitiveValue,java/lang/Comparable flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/PrimitiveValue;Ljava/lang/Comparable; + +class name com/sun/jdi/StackFrame +header extends java/lang/Object implements com/sun/jdi/Mirror,com/sun/jdi/Locatable flags 601 + +class name com/sun/jdi/StringReference +header extends java/lang/Object implements com/sun/jdi/ObjectReference flags 601 + +class name com/sun/jdi/ThreadGroupReference +header extends java/lang/Object implements com/sun/jdi/ObjectReference flags 601 + +class name com/sun/jdi/ThreadReference +header extends java/lang/Object implements com/sun/jdi/ObjectReference flags 601 + +class name com/sun/jdi/Type +header extends java/lang/Object implements com/sun/jdi/Mirror flags 601 + +class name com/sun/jdi/TypeComponent +header extends java/lang/Object implements com/sun/jdi/Mirror,com/sun/jdi/Accessible flags 601 + +class name com/sun/jdi/VMCannotBeModifiedException +header extends java/lang/UnsupportedOperationException flags 21 + +class name com/sun/jdi/VMDisconnectedException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/VMMismatchException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/VMOutOfMemoryException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/Value +header extends java/lang/Object implements com/sun/jdi/Mirror flags 601 + +class name com/sun/jdi/VirtualMachine +header extends java/lang/Object implements com/sun/jdi/Mirror flags 601 + +class name com/sun/jdi/VirtualMachineManager +header extends java/lang/Object flags 601 + +class name com/sun/jdi/VoidType +header extends java/lang/Object implements com/sun/jdi/Type flags 601 + +class name com/sun/jdi/VoidValue +header extends java/lang/Object implements com/sun/jdi/Value flags 601 + +class name com/sun/jdi/connect/AttachingConnector +header extends java/lang/Object implements com/sun/jdi/connect/Connector flags 601 +innerclass innerClass com/sun/jdi/connect/Connector$Argument outerClass com/sun/jdi/connect/Connector innerClassName Argument flags 609 + +class name com/sun/jdi/connect/IllegalConnectorArgumentsException +header extends java/lang/Exception flags 21 + +class name com/sun/jdi/connect/LaunchingConnector +header extends java/lang/Object implements com/sun/jdi/connect/Connector flags 601 +innerclass innerClass com/sun/jdi/connect/Connector$Argument outerClass com/sun/jdi/connect/Connector innerClassName Argument flags 609 + +class name com/sun/jdi/connect/ListeningConnector +header extends java/lang/Object implements com/sun/jdi/connect/Connector flags 601 +innerclass innerClass com/sun/jdi/connect/Connector$Argument outerClass com/sun/jdi/connect/Connector innerClassName Argument flags 609 + +class name com/sun/jdi/connect/Transport +header extends java/lang/Object flags 601 + +class name com/sun/jdi/connect/TransportTimeoutException +header extends java/io/IOException flags 21 + +class name com/sun/jdi/connect/VMStartException +header extends java/lang/Exception flags 21 + +class name com/sun/jdi/connect/spi/ClosedConnectionException +header extends java/io/IOException flags 21 + +class name com/sun/jdi/connect/spi/Connection +header extends java/lang/Object flags 421 + +class name com/sun/jdi/event/AccessWatchpointEvent +header extends java/lang/Object implements com/sun/jdi/event/WatchpointEvent flags 601 + +class name com/sun/jdi/event/BreakpointEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/ClassPrepareEvent +header extends java/lang/Object implements com/sun/jdi/event/Event flags 601 + +class name com/sun/jdi/event/ClassUnloadEvent +header extends java/lang/Object implements com/sun/jdi/event/Event flags 601 + +class name com/sun/jdi/event/Event +header extends java/lang/Object implements com/sun/jdi/Mirror flags 601 + +class name com/sun/jdi/event/EventIterator +header extends java/lang/Object implements java/util/Iterator flags 601 signature Ljava/lang/Object;Ljava/util/Iterator; + +class name com/sun/jdi/event/EventQueue +header extends java/lang/Object implements com/sun/jdi/Mirror flags 601 + +class name com/sun/jdi/event/EventSet +header extends java/lang/Object implements com/sun/jdi/Mirror,java/util/Set flags 601 signature Ljava/lang/Object;Lcom/sun/jdi/Mirror;Ljava/util/Set; + +class name com/sun/jdi/event/ExceptionEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/LocatableEvent +header extends java/lang/Object implements com/sun/jdi/event/Event,com/sun/jdi/Locatable flags 601 + +class name com/sun/jdi/event/MethodEntryEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/MethodExitEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/ModificationWatchpointEvent +header extends java/lang/Object implements com/sun/jdi/event/WatchpointEvent flags 601 + +class name com/sun/jdi/event/MonitorContendedEnterEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/MonitorContendedEnteredEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/MonitorWaitEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/MonitorWaitedEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/StepEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/event/ThreadDeathEvent +header extends java/lang/Object implements com/sun/jdi/event/Event flags 601 + +class name com/sun/jdi/event/ThreadStartEvent +header extends java/lang/Object implements com/sun/jdi/event/Event flags 601 + +class name com/sun/jdi/event/VMDeathEvent +header extends java/lang/Object implements com/sun/jdi/event/Event flags 601 + +class name com/sun/jdi/event/VMDisconnectEvent +header extends java/lang/Object implements com/sun/jdi/event/Event flags 601 + +class name com/sun/jdi/event/VMStartEvent +header extends java/lang/Object implements com/sun/jdi/event/Event flags 601 + +class name com/sun/jdi/event/WatchpointEvent +header extends java/lang/Object implements com/sun/jdi/event/LocatableEvent flags 601 + +class name com/sun/jdi/request/AccessWatchpointRequest +header extends java/lang/Object implements com/sun/jdi/request/WatchpointRequest flags 601 + +class name com/sun/jdi/request/BreakpointRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest,com/sun/jdi/Locatable flags 601 + +class name com/sun/jdi/request/ClassPrepareRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/ClassUnloadRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/DuplicateRequestException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/request/EventRequest +header extends java/lang/Object implements com/sun/jdi/Mirror flags 601 + +class name com/sun/jdi/request/EventRequestManager +header extends java/lang/Object implements com/sun/jdi/Mirror flags 601 + +class name com/sun/jdi/request/ExceptionRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/InvalidRequestStateException +header extends java/lang/RuntimeException flags 21 + +class name com/sun/jdi/request/MethodEntryRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/MethodExitRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/ModificationWatchpointRequest +header extends java/lang/Object implements com/sun/jdi/request/WatchpointRequest flags 601 + +class name com/sun/jdi/request/MonitorContendedEnterRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/MonitorContendedEnteredRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/MonitorWaitRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/MonitorWaitedRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/StepRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/ThreadDeathRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/ThreadStartRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/VMDeathRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + +class name com/sun/jdi/request/WatchpointRequest +header extends java/lang/Object implements com/sun/jdi/request/EventRequest flags 601 + diff --git a/make/data/symbols/jdk.jfr-B.sym.txt b/make/data/symbols/jdk.jfr-B.sym.txt index a42ce39defee3021814208120a6e5796f162ca88..be19cab9578fdaf7d8e1774607af8643ef2e805c 100644 --- a/make/data/symbols/jdk.jfr-B.sym.txt +++ b/make/data/symbols/jdk.jfr-B.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ # ########################################################## # module name jdk.jfr -header exports jdk/jfr,jdk/jfr/consumer requires name\u0020;java.base\u0020;flags\u0020;8000 target linux-amd64 flags 8000 +header exports jdk/jfr,jdk/jfr/consumer extraModulePackages jdk/jfr/internal requires name\u0020;java.base\u0020;flags\u0020;8000 target linux-amd64 flags 8000 class name jdk/jfr/AnnotationElement header extends java/lang/Object flags 31 @@ -390,3 +390,12 @@ method name readEventTypes descriptor ()Ljava/util/List; thrownTypes java/io/IOE method name close descriptor ()V thrownTypes java/io/IOException flags 1 method name readAllEvents descriptor (Ljava/nio/file/Path;)Ljava/util/List; thrownTypes java/io/IOException flags 9 signature (Ljava/nio/file/Path;)Ljava/util/List; +class name jdk/jfr/internal/Control +header extends java/lang/Object flags 421 +method name descriptor (Ljava/security/AccessControlContext;)V flags 1 +method name descriptor (Ljava/lang/String;)V flags 1 +method name combine descriptor (Ljava/util/Set;)Ljava/lang/String; flags 401 signature (Ljava/util/Set;)Ljava/lang/String; +method name setValue descriptor (Ljava/lang/String;)V flags 401 +method name getValue descriptor ()Ljava/lang/String; flags 401 +method name clone descriptor ()Ljava/lang/Object; thrownTypes java/lang/CloneNotSupportedException flags 11 + diff --git a/make/data/symbols/jdk.jfr-G.sym.txt b/make/data/symbols/jdk.jfr-G.sym.txt index 397e082021a2fcfdde89d1b909b867524d2a5acf..ba5b7e3a74331e6f4d5ab0d129d62f5806a26ebe 100644 --- a/make/data/symbols/jdk.jfr-G.sym.txt +++ b/make/data/symbols/jdk.jfr-G.sym.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,9 @@ # ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### # ########################################################## # +module name jdk.jfr +header exports jdk/jfr,jdk/jfr/consumer requires name\u0020;java.base\u0020;flags\u0020;8000 target linux-amd64 flags 8000 + class name jdk/jfr/SettingControl header extends java/lang/Object flags 421 runtimeAnnotations @Ljdk/jfr/MetadataDefinition; @@ -48,3 +51,5 @@ class name jdk/jfr/consumer/RecordedObject class name jdk/jfr/consumer/RecordingStream method name onMetadata descriptor (Ljava/util/function/Consumer;)V flags 1 signature (Ljava/util/function/Consumer;)V +-class name jdk/jfr/internal/Control + diff --git a/make/data/symbols/jdk.jlink-I.sym.txt b/make/data/symbols/jdk.jlink-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..7cc29b0fc2c05c2674271b0918ed85a5f0f4d49b --- /dev/null +++ b/make/data/symbols/jdk.jlink-I.sym.txt @@ -0,0 +1,31 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +module name jdk.jlink +header requires name\u0020;java.base\u0020;flags\u0020;8000,name\u0020;jdk.internal.opt\u0020;flags\u0020;0,name\u0020;jdk.jdeps\u0020;flags\u0020;0 uses jdk/tools/jlink/plugin/Plugin provides interface\u0020;java/util/spi/ToolProvider\u0020;impls\u0020;jdk/tools/jmod/Main$JmodToolProvider\u005C;u002C;jdk/tools/jlink/internal/Main$JlinkToolProvider,interface\u0020;jdk/tools/jlink/plugin/Plugin\u0020;impls\u0020;jdk/tools/jlink/internal/plugins/DefaultStripDebugPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/StripJavaDebugAttributesPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/ExcludePlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/LegalNoticeFilePlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/SystemModulesPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/OrderResourcesPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/DefaultCompressPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/ExcludeVMPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/AddOptionsPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/VendorBugURLPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/VendorVMBugURLPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/VendorVersionPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/CDSPlugin\u005C;u002C;jdk/tools/jlink/internal/plugins/StripNativeDebugSymbolsPlugin target linux-amd64 flags 8000 + diff --git a/make/data/symbols/jdk.jshell-I.sym.txt b/make/data/symbols/jdk.jshell-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..349690280cb7251d9e6aa1992b2709cca49cca8f --- /dev/null +++ b/make/data/symbols/jdk.jshell-I.sym.txt @@ -0,0 +1,108 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/jshell/DeclarationSnippet +header extends jdk/jshell/PersistentSnippet flags 421 +innerclass innerClass jdk/jshell/Snippet$SubKind outerClass jdk/jshell/Snippet innerClassName SubKind flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/jshell/Diag +header extends java/lang/Object flags 421 + +class name jdk/jshell/EvalException +header extends jdk/jshell/JShellException flags 21 + +class name jdk/jshell/ExpressionSnippet +header extends jdk/jshell/Snippet flags 21 +innerclass innerClass jdk/jshell/Snippet$SubKind outerClass jdk/jshell/Snippet innerClassName SubKind flags 4019 + +class name jdk/jshell/ImportSnippet +header extends jdk/jshell/PersistentSnippet flags 21 +innerclass innerClass jdk/jshell/Snippet$SubKind outerClass jdk/jshell/Snippet innerClassName SubKind flags 4019 + +class name jdk/jshell/JShellException +header extends java/lang/Exception flags 21 + +class name jdk/jshell/MethodSnippet +header extends jdk/jshell/DeclarationSnippet flags 21 +innerclass innerClass jdk/jshell/Snippet$SubKind outerClass jdk/jshell/Snippet innerClassName SubKind flags 4019 + +class name jdk/jshell/PersistentSnippet +header extends jdk/jshell/Snippet flags 421 +innerclass innerClass jdk/jshell/Snippet$SubKind outerClass jdk/jshell/Snippet innerClassName SubKind flags 4019 + +class name jdk/jshell/SnippetEvent +header extends java/lang/Object flags 21 +innerclass innerClass jdk/jshell/Snippet$Status outerClass jdk/jshell/Snippet innerClassName Status flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/jshell/StatementSnippet +header extends jdk/jshell/Snippet flags 21 +innerclass innerClass jdk/jshell/Snippet$SubKind outerClass jdk/jshell/Snippet innerClassName SubKind flags 4019 + +class name jdk/jshell/TypeDeclSnippet +header extends jdk/jshell/DeclarationSnippet flags 21 +innerclass innerClass jdk/jshell/Snippet$SubKind outerClass jdk/jshell/Snippet innerClassName SubKind flags 4019 + +class name jdk/jshell/execution/FailOverExecutionControlProvider +header extends java/lang/Object implements jdk/jshell/spi/ExecutionControlProvider flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/jshell/execution/JdiDefaultExecutionControl +header extends jdk/jshell/execution/JdiExecutionControl flags 21 +innerclass innerClass jdk/jshell/spi/ExecutionControl$InternalException outerClass jdk/jshell/spi/ExecutionControl innerClassName InternalException flags 9 +innerclass innerClass jdk/jshell/spi/ExecutionControl$EngineTerminationException outerClass jdk/jshell/spi/ExecutionControl innerClassName EngineTerminationException flags 9 +innerclass innerClass jdk/jshell/spi/ExecutionControl$RunException outerClass jdk/jshell/spi/ExecutionControl innerClassName RunException flags 409 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/jshell/execution/JdiExecutionControlProvider +header extends java/lang/Object implements jdk/jshell/spi/ExecutionControlProvider flags 21 + +class name jdk/jshell/execution/LoaderDelegate +header extends java/lang/Object flags 601 +innerclass innerClass jdk/jshell/spi/ExecutionControl$ClassBytecodes outerClass jdk/jshell/spi/ExecutionControl innerClassName ClassBytecodes flags 19 +innerclass innerClass jdk/jshell/spi/ExecutionControl$ClassInstallException outerClass jdk/jshell/spi/ExecutionControl innerClassName ClassInstallException flags 9 +innerclass innerClass jdk/jshell/spi/ExecutionControl$NotImplementedException outerClass jdk/jshell/spi/ExecutionControl innerClassName NotImplementedException flags 9 +innerclass innerClass jdk/jshell/spi/ExecutionControl$EngineTerminationException outerClass jdk/jshell/spi/ExecutionControl innerClassName EngineTerminationException flags 9 +innerclass innerClass jdk/jshell/spi/ExecutionControl$InternalException outerClass jdk/jshell/spi/ExecutionControl innerClassName InternalException flags 9 + +class name jdk/jshell/execution/LocalExecutionControlProvider +header extends java/lang/Object implements jdk/jshell/spi/ExecutionControlProvider flags 21 + +class name jdk/jshell/spi/ExecutionControlProvider +header extends java/lang/Object flags 601 + +class name jdk/jshell/spi/ExecutionEnv +header extends java/lang/Object flags 601 + +class name jdk/jshell/spi/SPIResolutionException +header extends java/lang/RuntimeException flags 21 + +class name jdk/jshell/tool/JavaShellToolBuilder +header extends java/lang/Object flags 601 + diff --git a/make/data/symbols/jdk.jsobject-I.sym.txt b/make/data/symbols/jdk.jsobject-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..a955e4bfe94126dafbee412bf3fcc81fb63b13f3 --- /dev/null +++ b/make/data/symbols/jdk.jsobject-I.sym.txt @@ -0,0 +1,31 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name netscape/javascript/JSException +header extends java/lang/RuntimeException flags 21 + diff --git a/make/data/symbols/jdk.management-I.sym.txt b/make/data/symbols/jdk.management-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..a6b7d08c1b4d2e57a5dac7ac5f227661a085362b --- /dev/null +++ b/make/data/symbols/jdk.management-I.sym.txt @@ -0,0 +1,49 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/management/GarbageCollectionNotificationInfo +header extends java/lang/Object implements javax/management/openmbean/CompositeDataView flags 21 + +class name com/sun/management/GarbageCollectorMXBean +header extends java/lang/Object implements java/lang/management/GarbageCollectorMXBean flags 601 + +class name com/sun/management/GcInfo +header extends java/lang/Object implements javax/management/openmbean/CompositeData,javax/management/openmbean/CompositeDataView flags 21 + +class name com/sun/management/HotSpotDiagnosticMXBean +header extends java/lang/Object implements java/lang/management/PlatformManagedObject flags 601 + +class name com/sun/management/OperatingSystemMXBean +header extends java/lang/Object implements java/lang/management/OperatingSystemMXBean flags 601 + +class name com/sun/management/ThreadMXBean +header extends java/lang/Object implements java/lang/management/ThreadMXBean flags 601 + +class name com/sun/management/UnixOperatingSystemMXBean +header extends java/lang/Object implements com/sun/management/OperatingSystemMXBean flags 601 + diff --git a/make/data/symbols/jdk.management.jfr-I.sym.txt b/make/data/symbols/jdk.management.jfr-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..e2ac7345ef96eca15b59e819c48addee47197cdd --- /dev/null +++ b/make/data/symbols/jdk.management.jfr-I.sym.txt @@ -0,0 +1,31 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +module name jdk.management.jfr +header exports jdk/management/jfr requires name\u0020;java.base\u0020;flags\u0020;8000,name\u0020;jdk.management\u0020;flags\u0020;0,name\u0020;java.management\u0020;flags\u0020;20,name\u0020;jdk.jfr\u0020;flags\u0020;20 provides interface\u0020;sun/management/spi/PlatformMBeanProvider\u0020;impls\u0020;jdk/management/jfr/internal/FlightRecorderMXBeanProvider target linux-amd64 flags 8000 + diff --git a/make/data/symbols/jdk.net-I.sym.txt b/make/data/symbols/jdk.net-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..51aada714d6b309efb237af405dfc9f5638f618b --- /dev/null +++ b/make/data/symbols/jdk.net-I.sym.txt @@ -0,0 +1,31 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/net/NetworkPermission +header extends java/security/BasicPermission flags 31 + diff --git a/make/data/symbols/jdk.sctp-I.sym.txt b/make/data/symbols/jdk.sctp-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..1694db9490daa9f6e60636053bb464abdba8e033 --- /dev/null +++ b/make/data/symbols/jdk.sctp-I.sym.txt @@ -0,0 +1,73 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/nio/sctp/AbstractNotificationHandler +header extends java/lang/Object implements com/sun/nio/sctp/NotificationHandler flags 21 signature Ljava/lang/Object;Lcom/sun/nio/sctp/NotificationHandler; + +class name com/sun/nio/sctp/Association +header extends java/lang/Object flags 21 + +class name com/sun/nio/sctp/HandlerResult +header extends java/lang/Enum flags 4031 signature Ljava/lang/Enum; + +class name com/sun/nio/sctp/IllegalReceiveException +header extends java/lang/IllegalStateException flags 21 + +class name com/sun/nio/sctp/IllegalUnbindException +header extends java/lang/IllegalStateException flags 21 + +class name com/sun/nio/sctp/InvalidStreamException +header extends java/lang/IllegalArgumentException flags 21 + +class name com/sun/nio/sctp/MessageInfo +header extends java/lang/Object flags 421 + +class name com/sun/nio/sctp/Notification +header extends java/lang/Object flags 601 + +class name com/sun/nio/sctp/NotificationHandler +header extends java/lang/Object flags 601 signature Ljava/lang/Object; + +class name com/sun/nio/sctp/SctpChannel +header extends java/nio/channels/spi/AbstractSelectableChannel flags 421 + +class name com/sun/nio/sctp/SctpMultiChannel +header extends java/nio/channels/spi/AbstractSelectableChannel flags 421 + +class name com/sun/nio/sctp/SctpServerChannel +header extends java/nio/channels/spi/AbstractSelectableChannel flags 421 + +class name com/sun/nio/sctp/SctpSocketOption +header extends java/lang/Object implements java/net/SocketOption flags 601 signature Ljava/lang/Object;Ljava/net/SocketOption; + +class name com/sun/nio/sctp/SendFailedNotification +header extends java/lang/Object implements com/sun/nio/sctp/Notification flags 421 + +class name com/sun/nio/sctp/ShutdownNotification +header extends java/lang/Object implements com/sun/nio/sctp/Notification flags 421 + diff --git a/make/data/symbols/jdk.security.auth-I.sym.txt b/make/data/symbols/jdk.security.auth-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..a144d3775a4e55487f31a86f3a9e73a984ad81a5 --- /dev/null +++ b/make/data/symbols/jdk.security.auth-I.sym.txt @@ -0,0 +1,106 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/security/auth/LdapPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 31 + +class name com/sun/security/auth/NTDomainPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 21 + +class name com/sun/security/auth/NTNumericCredential +header extends java/lang/Object flags 21 + +class name com/sun/security/auth/NTSid +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 21 + +class name com/sun/security/auth/NTSidDomainPrincipal +header extends com/sun/security/auth/NTSid flags 21 + +class name com/sun/security/auth/NTSidGroupPrincipal +header extends com/sun/security/auth/NTSid flags 21 + +class name com/sun/security/auth/NTSidPrimaryGroupPrincipal +header extends com/sun/security/auth/NTSid flags 21 + +class name com/sun/security/auth/NTSidUserPrincipal +header extends com/sun/security/auth/NTSid flags 21 + +class name com/sun/security/auth/NTUserPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 21 + +class name com/sun/security/auth/PrincipalComparator +header extends java/lang/Object flags 601 + +class name com/sun/security/auth/UnixNumericGroupPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 21 + +class name com/sun/security/auth/UnixNumericUserPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 21 + +class name com/sun/security/auth/UnixPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 21 + +class name com/sun/security/auth/UserPrincipal +header extends java/lang/Object implements java/security/Principal,java/io/Serializable flags 31 + +class name com/sun/security/auth/callback/TextCallbackHandler +header extends java/lang/Object implements javax/security/auth/callback/CallbackHandler flags 21 + +class name com/sun/security/auth/login/ConfigFile +header extends javax/security/auth/login/Configuration flags 21 + +class name com/sun/security/auth/module/JndiLoginModule +header extends java/lang/Object implements javax/security/auth/spi/LoginModule flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/security/auth/module/KeyStoreLoginModule +header extends java/lang/Object implements javax/security/auth/spi/LoginModule flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/security/auth/module/Krb5LoginModule +header extends java/lang/Object implements javax/security/auth/spi/LoginModule flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/security/auth/module/LdapLoginModule +header extends java/lang/Object implements javax/security/auth/spi/LoginModule flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/security/auth/module/NTLoginModule +header extends java/lang/Object implements javax/security/auth/spi/LoginModule flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/security/auth/module/NTSystem +header extends java/lang/Object flags 21 + +class name com/sun/security/auth/module/UnixLoginModule +header extends java/lang/Object implements javax/security/auth/spi/LoginModule flags 21 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/security/auth/module/UnixSystem +header extends java/lang/Object flags 21 + diff --git a/make/data/symbols/jdk.security.jgss-I.sym.txt b/make/data/symbols/jdk.security.jgss-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..a3fd927f93f800744d55d2f3a953ceb79d105fcc --- /dev/null +++ b/make/data/symbols/jdk.security.jgss-I.sym.txt @@ -0,0 +1,47 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/security/jgss/AuthorizationDataEntry +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name com/sun/security/jgss/ExtendedGSSContext +header extends java/lang/Object implements org/ietf/jgss/GSSContext flags 601 + +class name com/sun/security/jgss/ExtendedGSSCredential +header extends java/lang/Object implements org/ietf/jgss/GSSCredential flags 601 + +class name com/sun/security/jgss/GSSUtil +header extends java/lang/Object flags 21 + +class name com/sun/security/jgss/InquireSecContextPermission +header extends java/security/BasicPermission flags 31 + +class name com/sun/security/jgss/InquireType +header extends java/lang/Enum flags 4031 signature Ljava/lang/Enum; + diff --git a/make/data/symbols/jdk.unsupported-I.sym.txt b/make/data/symbols/jdk.unsupported-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..db2342c25e259d5415dcab0d052c0a1842f48bd9 --- /dev/null +++ b/make/data/symbols/jdk.unsupported-I.sym.txt @@ -0,0 +1,56 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/nio/file/ExtendedCopyOption +header extends java/lang/Enum implements java/nio/file/CopyOption flags 4031 signature Ljava/lang/Enum;Ljava/nio/file/CopyOption; classAnnotations @Lsun/Proprietary+Annotation; + +class name com/sun/nio/file/ExtendedOpenOption +header extends java/lang/Enum implements java/nio/file/OpenOption flags 4031 signature Ljava/lang/Enum;Ljava/nio/file/OpenOption; classAnnotations @Lsun/Proprietary+Annotation; + +class name com/sun/nio/file/ExtendedWatchEventModifier +header extends java/lang/Enum implements java/nio/file/WatchEvent$Modifier flags 4031 signature Ljava/lang/Enum;Ljava/nio/file/WatchEvent$Modifier; classAnnotations @Lsun/Proprietary+Annotation; +innerclass innerClass java/nio/file/WatchEvent$Modifier outerClass java/nio/file/WatchEvent innerClassName Modifier flags 609 + +class name com/sun/nio/file/SensitivityWatchEventModifier +header extends java/lang/Enum implements java/nio/file/WatchEvent$Modifier flags 4031 signature Ljava/lang/Enum;Ljava/nio/file/WatchEvent$Modifier; classAnnotations @Lsun/Proprietary+Annotation; +innerclass innerClass java/nio/file/WatchEvent$Modifier outerClass java/nio/file/WatchEvent innerClassName Modifier flags 609 + +class name sun/misc/SignalHandler +header extends java/lang/Object flags 601 classAnnotations @Lsun/Proprietary+Annotation; + +class name sun/misc/Unsafe +-method name objectFieldOffset descriptor (Ljava/lang/reflect/Field;)J +-method name staticFieldOffset descriptor (Ljava/lang/reflect/Field;)J +-method name staticFieldBase descriptor (Ljava/lang/reflect/Field;)Ljava/lang/Object; +method name objectFieldOffset descriptor (Ljava/lang/reflect/Field;)J flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="18")@Ljdk/internal/vm/annotation/ForceInline; +method name staticFieldOffset descriptor (Ljava/lang/reflect/Field;)J flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="18")@Ljdk/internal/vm/annotation/ForceInline; +method name staticFieldBase descriptor (Ljava/lang/reflect/Field;)Ljava/lang/Object; flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="18")@Ljdk/internal/vm/annotation/ForceInline; + +class name sun/reflect/ReflectionFactory +header extends java/lang/Object flags 21 classAnnotations @Lsun/Proprietary+Annotation; + diff --git a/make/data/symbols/jdk.xml.dom-I.sym.txt b/make/data/symbols/jdk.xml.dom-I.sym.txt new file mode 100644 index 0000000000000000000000000000000000000000..24fc87498177232e04afc5ed40c8ac8cdca4995e --- /dev/null +++ b/make/data/symbols/jdk.xml.dom-I.sym.txt @@ -0,0 +1,295 @@ +# +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name org/w3c/dom/css/CSS2Properties +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/CSSCharsetRule +header extends java/lang/Object implements org/w3c/dom/css/CSSRule flags 601 + +class name org/w3c/dom/css/CSSFontFaceRule +header extends java/lang/Object implements org/w3c/dom/css/CSSRule flags 601 + +class name org/w3c/dom/css/CSSImportRule +header extends java/lang/Object implements org/w3c/dom/css/CSSRule flags 601 + +class name org/w3c/dom/css/CSSMediaRule +header extends java/lang/Object implements org/w3c/dom/css/CSSRule flags 601 + +class name org/w3c/dom/css/CSSPageRule +header extends java/lang/Object implements org/w3c/dom/css/CSSRule flags 601 + +class name org/w3c/dom/css/CSSPrimitiveValue +header extends java/lang/Object implements org/w3c/dom/css/CSSValue flags 601 + +class name org/w3c/dom/css/CSSRule +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/CSSRuleList +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/CSSStyleDeclaration +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/CSSStyleRule +header extends java/lang/Object implements org/w3c/dom/css/CSSRule flags 601 + +class name org/w3c/dom/css/CSSStyleSheet +header extends java/lang/Object implements org/w3c/dom/stylesheets/StyleSheet flags 601 + +class name org/w3c/dom/css/CSSUnknownRule +header extends java/lang/Object implements org/w3c/dom/css/CSSRule flags 601 + +class name org/w3c/dom/css/CSSValue +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/CSSValueList +header extends java/lang/Object implements org/w3c/dom/css/CSSValue flags 601 + +class name org/w3c/dom/css/Counter +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/DOMImplementationCSS +header extends java/lang/Object implements org/w3c/dom/DOMImplementation flags 601 + +class name org/w3c/dom/css/DocumentCSS +header extends java/lang/Object implements org/w3c/dom/stylesheets/DocumentStyle flags 601 + +class name org/w3c/dom/css/ElementCSSInlineStyle +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/RGBColor +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/Rect +header extends java/lang/Object flags 601 + +class name org/w3c/dom/css/ViewCSS +header extends java/lang/Object implements org/w3c/dom/views/AbstractView flags 601 + +class name org/w3c/dom/html/HTMLAnchorElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLAppletElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLAreaElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLBRElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLBaseElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLBaseFontElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLBodyElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLButtonElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLCollection +header extends java/lang/Object flags 601 + +class name org/w3c/dom/html/HTMLDListElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLDOMImplementation +header extends java/lang/Object implements org/w3c/dom/DOMImplementation flags 601 + +class name org/w3c/dom/html/HTMLDirectoryElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLDivElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLDocument +header extends java/lang/Object implements org/w3c/dom/Document flags 601 + +class name org/w3c/dom/html/HTMLElement +header extends java/lang/Object implements org/w3c/dom/Element flags 601 + +class name org/w3c/dom/html/HTMLFieldSetElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLFontElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLFormElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLFrameElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLFrameSetElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLHRElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLHeadElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLHeadingElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLHtmlElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLIFrameElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLImageElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLInputElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLIsIndexElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLLIElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLLabelElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLLegendElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLLinkElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLMapElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLMenuElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLMetaElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLModElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLOListElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLObjectElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLOptGroupElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLOptionElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLParagraphElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLParamElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLPreElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLQuoteElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLScriptElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLSelectElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLStyleElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLTableCaptionElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLTableCellElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLTableColElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLTableElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLTableRowElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLTableSectionElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLTextAreaElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLTitleElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/html/HTMLUListElement +header extends java/lang/Object implements org/w3c/dom/html/HTMLElement flags 601 + +class name org/w3c/dom/stylesheets/DocumentStyle +header extends java/lang/Object flags 601 + +class name org/w3c/dom/stylesheets/LinkStyle +header extends java/lang/Object flags 601 + +class name org/w3c/dom/stylesheets/MediaList +header extends java/lang/Object flags 601 + +class name org/w3c/dom/stylesheets/StyleSheet +header extends java/lang/Object flags 601 + +class name org/w3c/dom/stylesheets/StyleSheetList +header extends java/lang/Object flags 601 + +class name org/w3c/dom/xpath/XPathEvaluator +header extends java/lang/Object flags 601 + +class name org/w3c/dom/xpath/XPathException +header extends java/lang/RuntimeException flags 21 + +class name org/w3c/dom/xpath/XPathExpression +header extends java/lang/Object flags 601 + +class name org/w3c/dom/xpath/XPathNSResolver +header extends java/lang/Object flags 601 + +class name org/w3c/dom/xpath/XPathNamespace +header extends java/lang/Object implements org/w3c/dom/Node flags 601 + +class name org/w3c/dom/xpath/XPathResult +header extends java/lang/Object flags 601 + diff --git a/make/data/symbols/symbols b/make/data/symbols/symbols index d05e92601ea7a4ce75e87e942097bf4efe47d614..691d1d85bf83068e3b058f1428408bddf64aecd7 100644 --- a/make/data/symbols/symbols +++ b/make/data/symbols/symbols @@ -29,7 +29,7 @@ #command used to generate this file: #build.tools.symbolgenerator.CreateSymbols build-description-incremental symbols include.list # -generate platforms 7:8:9:A:B:C:D:E:F:G:H +generate platforms 7:8:9:A:B:C:D:E:F:G:H:I platform version 8 files java.activation-8.sym.txt:java.base-8.sym.txt:java.compiler-8.sym.txt:java.corba-8.sym.txt:java.datatransfer-8.sym.txt:java.desktop-8.sym.txt:java.instrument-8.sym.txt:java.logging-8.sym.txt:java.management-8.sym.txt:java.management.rmi-8.sym.txt:java.naming-8.sym.txt:java.prefs-8.sym.txt:java.rmi-8.sym.txt:java.scripting-8.sym.txt:java.security.jgss-8.sym.txt:java.security.sasl-8.sym.txt:java.sql-8.sym.txt:java.sql.rowset-8.sym.txt:java.transaction-8.sym.txt:java.xml-8.sym.txt:java.xml.bind-8.sym.txt:java.xml.crypto-8.sym.txt:java.xml.ws-8.sym.txt:java.xml.ws.annotation-8.sym.txt:jdk.httpserver-8.sym.txt:jdk.management-8.sym.txt:jdk.scripting.nashorn-8.sym.txt:jdk.sctp-8.sym.txt:jdk.security.auth-8.sym.txt:jdk.security.jgss-8.sym.txt platform version 7 base 8 files java.base-7.sym.txt:java.compiler-7.sym.txt:java.datatransfer-7.sym.txt:java.desktop-7.sym.txt:java.logging-7.sym.txt:java.management-7.sym.txt:java.naming-7.sym.txt:java.prefs-7.sym.txt:java.rmi-7.sym.txt:java.scripting-7.sym.txt:java.security.jgss-7.sym.txt:java.security.sasl-7.sym.txt:java.sql-7.sym.txt:java.sql.rowset-7.sym.txt:java.xml-7.sym.txt:java.xml.bind-7.sym.txt:java.xml.ws.annotation-7.sym.txt:jdk.httpserver-7.sym.txt:jdk.management-7.sym.txt:jdk.scripting.nashorn-7.sym.txt:jdk.sctp-7.sym.txt:jdk.security.auth-7.sym.txt:jdk.security.jgss-7.sym.txt platform version 9 base 8 files java.activation-9.sym.txt:java.base-9.sym.txt:java.compiler-9.sym.txt:java.corba-9.sym.txt:java.datatransfer-9.sym.txt:java.desktop-9.sym.txt:java.instrument-9.sym.txt:java.logging-9.sym.txt:java.management-9.sym.txt:java.management.rmi-9.sym.txt:java.naming-9.sym.txt:java.prefs-9.sym.txt:java.rmi-9.sym.txt:java.scripting-9.sym.txt:java.se-9.sym.txt:java.se.ee-9.sym.txt:java.security.jgss-9.sym.txt:java.security.sasl-9.sym.txt:java.smartcardio-9.sym.txt:java.sql-9.sym.txt:java.sql.rowset-9.sym.txt:java.transaction-9.sym.txt:java.xml-9.sym.txt:java.xml.bind-9.sym.txt:java.xml.crypto-9.sym.txt:java.xml.ws-9.sym.txt:java.xml.ws.annotation-9.sym.txt:jdk.accessibility-9.sym.txt:jdk.attach-9.sym.txt:jdk.charsets-9.sym.txt:jdk.compiler-9.sym.txt:jdk.crypto.cryptoki-9.sym.txt:jdk.crypto.ec-9.sym.txt:jdk.dynalink-9.sym.txt:jdk.editpad-9.sym.txt:jdk.hotspot.agent-9.sym.txt:jdk.httpserver-9.sym.txt:jdk.incubator.httpclient-9.sym.txt:jdk.jartool-9.sym.txt:jdk.javadoc-9.sym.txt:jdk.jcmd-9.sym.txt:jdk.jconsole-9.sym.txt:jdk.jdeps-9.sym.txt:jdk.jdi-9.sym.txt:jdk.jdwp.agent-9.sym.txt:jdk.jlink-9.sym.txt:jdk.jshell-9.sym.txt:jdk.jsobject-9.sym.txt:jdk.jstatd-9.sym.txt:jdk.localedata-9.sym.txt:jdk.management-9.sym.txt:jdk.management.agent-9.sym.txt:jdk.naming.dns-9.sym.txt:jdk.naming.rmi-9.sym.txt:jdk.net-9.sym.txt:jdk.pack-9.sym.txt:jdk.policytool-9.sym.txt:jdk.rmic-9.sym.txt:jdk.scripting.nashorn-9.sym.txt:jdk.sctp-9.sym.txt:jdk.security.auth-9.sym.txt:jdk.security.jgss-9.sym.txt:jdk.unsupported-9.sym.txt:jdk.xml.dom-9.sym.txt:jdk.zipfs-9.sym.txt @@ -41,3 +41,4 @@ platform version E base D files java.base-E.sym.txt:java.compiler-E.sym.txt:java platform version F base E files java.base-F.sym.txt:java.compiler-F.sym.txt:java.desktop-F.sym.txt:java.management.rmi-F.sym.txt:java.naming-F.sym.txt:java.rmi-F.sym.txt:java.xml-F.sym.txt:jdk.compiler-F.sym.txt:jdk.incubator.foreign-F.sym.txt:jdk.jartool-F.sym.txt:jdk.javadoc-F.sym.txt:jdk.jdi-F.sym.txt:jdk.net-F.sym.txt:jdk.nio.mapmode-F.sym.txt:jdk.rmic-F.sym.txt:jdk.scripting.nashorn-F.sym.txt:jdk.unsupported-F.sym.txt platform version G base F files java.base-G.sym.txt:java.compiler-G.sym.txt:java.datatransfer-G.sym.txt:java.desktop-G.sym.txt:java.instrument-G.sym.txt:java.logging-G.sym.txt:java.management-G.sym.txt:java.management.rmi-G.sym.txt:java.naming-G.sym.txt:java.net.http-G.sym.txt:java.rmi-G.sym.txt:java.scripting-G.sym.txt:java.security.jgss-G.sym.txt:java.security.sasl-G.sym.txt:java.smartcardio-G.sym.txt:java.sql-G.sym.txt:java.sql.rowset-G.sym.txt:java.xml-G.sym.txt:java.xml.crypto-G.sym.txt:jdk.accessibility-G.sym.txt:jdk.attach-G.sym.txt:jdk.compiler-G.sym.txt:jdk.dynalink-G.sym.txt:jdk.httpserver-G.sym.txt:jdk.incubator.foreign-G.sym.txt:jdk.incubator.jpackage-G.sym.txt:jdk.incubator.vector-G.sym.txt:jdk.jartool-G.sym.txt:jdk.javadoc-G.sym.txt:jdk.jconsole-G.sym.txt:jdk.jdi-G.sym.txt:jdk.jfr-G.sym.txt:jdk.jpackage-G.sym.txt:jdk.jshell-G.sym.txt:jdk.jsobject-G.sym.txt:jdk.management-G.sym.txt:jdk.management.jfr-G.sym.txt:jdk.net-G.sym.txt:jdk.sctp-G.sym.txt:jdk.security.auth-G.sym.txt:jdk.security.jgss-G.sym.txt:jdk.unsupported-G.sym.txt:jdk.xml.dom-G.sym.txt platform version H base G files java.base-H.sym.txt:java.compiler-H.sym.txt:java.datatransfer-H.sym.txt:java.desktop-H.sym.txt:java.instrument-H.sym.txt:java.logging-H.sym.txt:java.management-H.sym.txt:java.management.rmi-H.sym.txt:java.naming-H.sym.txt:java.rmi-H.sym.txt:java.scripting-H.sym.txt:java.security.jgss-H.sym.txt:java.security.sasl-H.sym.txt:java.smartcardio-H.sym.txt:java.sql-H.sym.txt:java.sql.rowset-H.sym.txt:java.xml-H.sym.txt:java.xml.crypto-H.sym.txt:jdk.accessibility-H.sym.txt:jdk.attach-H.sym.txt:jdk.compiler-H.sym.txt:jdk.dynalink-H.sym.txt:jdk.httpserver-H.sym.txt:jdk.incubator.foreign-H.sym.txt:jdk.incubator.vector-H.sym.txt:jdk.jartool-H.sym.txt:jdk.javadoc-H.sym.txt:jdk.jconsole-H.sym.txt:jdk.jdi-H.sym.txt:jdk.jfr-H.sym.txt:jdk.jshell-H.sym.txt:jdk.jsobject-H.sym.txt:jdk.management-H.sym.txt:jdk.management.jfr-H.sym.txt:jdk.net-H.sym.txt:jdk.sctp-H.sym.txt:jdk.security.auth-H.sym.txt:jdk.security.jgss-H.sym.txt:jdk.unsupported-H.sym.txt:jdk.xml.dom-H.sym.txt +platform version I base H files java.base-I.sym.txt:java.compiler-I.sym.txt:java.datatransfer-I.sym.txt:java.desktop-I.sym.txt:java.instrument-I.sym.txt:java.logging-I.sym.txt:java.management-I.sym.txt:java.management.rmi-I.sym.txt:java.naming-I.sym.txt:java.net.http-I.sym.txt:java.rmi-I.sym.txt:java.scripting-I.sym.txt:java.security.jgss-I.sym.txt:java.security.sasl-I.sym.txt:java.smartcardio-I.sym.txt:java.sql-I.sym.txt:java.sql.rowset-I.sym.txt:java.xml-I.sym.txt:java.xml.crypto-I.sym.txt:jdk.accessibility-I.sym.txt:jdk.attach-I.sym.txt:jdk.compiler-I.sym.txt:jdk.dynalink-I.sym.txt:jdk.httpserver-I.sym.txt:jdk.incubator.foreign-I.sym.txt:jdk.incubator.vector-I.sym.txt:jdk.jartool-I.sym.txt:jdk.javadoc-I.sym.txt:jdk.jconsole-I.sym.txt:jdk.jdi-I.sym.txt:jdk.jlink-I.sym.txt:jdk.jshell-I.sym.txt:jdk.jsobject-I.sym.txt:jdk.management-I.sym.txt:jdk.management.jfr-I.sym.txt:jdk.net-I.sym.txt:jdk.sctp-I.sym.txt:jdk.security.auth-I.sym.txt:jdk.security.jgss-I.sym.txt:jdk.unsupported-I.sym.txt:jdk.xml.dom-I.sym.txt diff --git a/make/data/unicodedata/Blocks.txt b/make/data/unicodedata/Blocks.txt index b20570e06767f77dfe81d5d4787e12eed0f0e29b..d3c73191e76536281298300c2a8db56b114faf78 100644 --- a/make/data/unicodedata/Blocks.txt +++ b/make/data/unicodedata/Blocks.txt @@ -1,6 +1,6 @@ -# Blocks-13.0.0.txt -# Date: 2019-07-10, 19:06:00 GMT [KW] -# Copyright (c) 2019 Unicode, Inc. +# Blocks-14.0.0.txt +# Date: 2021-01-22, 23:29:00 GMT [KW] +# Copyright (c) 2021 Unicode, Inc. # For terms of use, see http://www.unicode.org/terms_of_use.html # # Unicode Character Database @@ -52,6 +52,7 @@ 0800..083F; Samaritan 0840..085F; Mandaic 0860..086F; Syriac Supplement +0870..089F; Arabic Extended-B 08A0..08FF; Arabic Extended-A 0900..097F; Devanagari 0980..09FF; Bengali @@ -215,7 +216,9 @@ FFF0..FFFF; Specials 104B0..104FF; Osage 10500..1052F; Elbasan 10530..1056F; Caucasian Albanian +10570..105BF; Vithkuqi 10600..1077F; Linear A +10780..107BF; Latin Extended-F 10800..1083F; Cypriot Syllabary 10840..1085F; Imperial Aramaic 10860..1087F; Palmyrene @@ -240,6 +243,7 @@ FFF0..FFFF; Specials 10E80..10EBF; Yezidi 10F00..10F2F; Old Sogdian 10F30..10F6F; Sogdian +10F70..10FAF; Old Uyghur 10FB0..10FDF; Chorasmian 10FE0..10FFF; Elymaic 11000..1107F; Brahmi @@ -259,13 +263,14 @@ FFF0..FFFF; Specials 11600..1165F; Modi 11660..1167F; Mongolian Supplement 11680..116CF; Takri -11700..1173F; Ahom +11700..1174F; Ahom 11800..1184F; Dogra 118A0..118FF; Warang Citi 11900..1195F; Dives Akuru 119A0..119FF; Nandinagari 11A00..11A4F; Zanabazar Square 11A50..11AAF; Soyombo +11AB0..11ABF; Unified Canadian Aboriginal Syllabics Extended-A 11AC0..11AFF; Pau Cin Hau 11C00..11C6F; Bhaiksuki 11C70..11CBF; Marchen @@ -277,11 +282,13 @@ FFF0..FFFF; Specials 12000..123FF; Cuneiform 12400..1247F; Cuneiform Numbers and Punctuation 12480..1254F; Early Dynastic Cuneiform +12F90..12FFF; Cypro-Minoan 13000..1342F; Egyptian Hieroglyphs 13430..1343F; Egyptian Hieroglyph Format Controls 14400..1467F; Anatolian Hieroglyphs 16800..16A3F; Bamum Supplement 16A40..16A6F; Mro +16A70..16ACF; Tangsa 16AD0..16AFF; Bassa Vah 16B00..16B8F; Pahawh Hmong 16E40..16E9F; Medefaidrin @@ -290,13 +297,15 @@ FFF0..FFFF; Specials 17000..187FF; Tangut 18800..18AFF; Tangut Components 18B00..18CFF; Khitan Small Script -18D00..18D8F; Tangut Supplement +18D00..18D7F; Tangut Supplement +1AFF0..1AFFF; Kana Extended-B 1B000..1B0FF; Kana Supplement 1B100..1B12F; Kana Extended-A 1B130..1B16F; Small Kana Extension 1B170..1B2FF; Nushu 1BC00..1BC9F; Duployan 1BCA0..1BCAF; Shorthand Format Controls +1CF00..1CFCF; Znamenny Musical Notation 1D000..1D0FF; Byzantine Musical Symbols 1D100..1D1FF; Musical Symbols 1D200..1D24F; Ancient Greek Musical Notation @@ -305,9 +314,12 @@ FFF0..FFFF; Specials 1D360..1D37F; Counting Rod Numerals 1D400..1D7FF; Mathematical Alphanumeric Symbols 1D800..1DAAF; Sutton SignWriting +1DF00..1DFFF; Latin Extended-G 1E000..1E02F; Glagolitic Supplement 1E100..1E14F; Nyiakeng Puachue Hmong +1E290..1E2BF; Toto 1E2C0..1E2FF; Wancho +1E7E0..1E7FF; Ethiopic Extended-B 1E800..1E8DF; Mende Kikakui 1E900..1E95F; Adlam 1EC70..1ECBF; Indic Siyaq Numbers diff --git a/make/data/unicodedata/DerivedCoreProperties.txt b/make/data/unicodedata/DerivedCoreProperties.txt index cbaa2d46ce1a68f40d08fe7591f7e87d7428c9ff..2fb971d7ff58a720e1cab9d0f17513baf9582bc7 100644 --- a/make/data/unicodedata/DerivedCoreProperties.txt +++ b/make/data/unicodedata/DerivedCoreProperties.txt @@ -1,6 +1,6 @@ -# DerivedCoreProperties-13.0.0.txt -# Date: 2020-01-22, 00:07:19 GMT -# Copyright (c) 2020 Unicode, Inc. +# DerivedCoreProperties-14.0.0.txt +# Date: 2021-08-12, 23:12:53 GMT +# Copyright (c) 2021 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -341,8 +341,10 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 0829..082C ; Alphabetic # Mn [4] SAMARITAN VOWEL SIGN LONG I..SAMARITAN VOWEL SIGN SUKUN 0840..0858 ; Alphabetic # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN 0860..086A ; Alphabetic # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA -08A0..08B4 ; Alphabetic # Lo [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW -08B6..08C7 ; Alphabetic # Lo [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE +0870..0887 ; Alphabetic # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT +0889..088E ; Alphabetic # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL +08A0..08C8 ; Alphabetic # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF +08C9 ; Alphabetic # Lm ARABIC SMALL FARSI YEH 08D4..08DF ; Alphabetic # Mn [12] ARABIC SMALL HIGH WORD AR-RUB..ARABIC SMALL HIGH WORD WAQFA 08E3..08E9 ; Alphabetic # Mn [7] ARABIC TURNED DAMMA BELOW..ARABIC CURLY KASRATAN 08F0..0902 ; Alphabetic # Mn [19] ARABIC OPEN FATHATAN..DEVANAGARI SIGN ANUSVARA @@ -471,6 +473,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 0C4A..0C4C ; Alphabetic # Mn [3] TELUGU VOWEL SIGN O..TELUGU VOWEL SIGN AU 0C55..0C56 ; Alphabetic # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK 0C58..0C5A ; Alphabetic # Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA +0C5D ; Alphabetic # Lo TELUGU LETTER NAKAARA POLLU 0C60..0C61 ; Alphabetic # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL 0C62..0C63 ; Alphabetic # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL 0C80 ; Alphabetic # Lo KANNADA SIGN SPACING CANDRABINDU @@ -490,7 +493,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 0CCA..0CCB ; Alphabetic # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CCC ; Alphabetic # Mn KANNADA VOWEL SIGN AU 0CD5..0CD6 ; Alphabetic # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK -0CDE ; Alphabetic # Lo KANNADA LETTER FA +0CDD..0CDE ; Alphabetic # Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA 0CE0..0CE1 ; Alphabetic # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL 0CE2..0CE3 ; Alphabetic # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL 0CF1..0CF2 ; Alphabetic # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA @@ -614,10 +617,9 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 16A0..16EA ; Alphabetic # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X 16EE..16F0 ; Alphabetic # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL 16F1..16F8 ; Alphabetic # Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC -1700..170C ; Alphabetic # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA -170E..1711 ; Alphabetic # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA +1700..1711 ; Alphabetic # Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA 1712..1713 ; Alphabetic # Mn [2] TAGALOG VOWEL SIGN I..TAGALOG VOWEL SIGN U -1720..1731 ; Alphabetic # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA +171F..1731 ; Alphabetic # Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA 1732..1733 ; Alphabetic # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U 1740..1751 ; Alphabetic # Lo [18] BUHID LETTER A..BUHID LETTER HA 1752..1753 ; Alphabetic # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U @@ -670,6 +672,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 1A73..1A74 ; Alphabetic # Mn [2] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN MAI KANG 1AA7 ; Alphabetic # Lm TAI THAM SIGN MAI YAMOK 1ABF..1AC0 ; Alphabetic # Mn [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW +1ACC..1ACE ; Alphabetic # Mn [3] COMBINING LATIN SMALL LETTER INSULAR G..COMBINING LATIN SMALL LETTER INSULAR T 1B00..1B03 ; Alphabetic # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG 1B04 ; Alphabetic # Mc BALINESE SIGN BISAH 1B05..1B33 ; Alphabetic # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA @@ -680,7 +683,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 1B3D..1B41 ; Alphabetic # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG 1B42 ; Alphabetic # Mn BALINESE VOWEL SIGN PEPET 1B43 ; Alphabetic # Mc BALINESE VOWEL SIGN PEPET TEDUNG -1B45..1B4B ; Alphabetic # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B45..1B4C ; Alphabetic # Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA 1B80..1B81 ; Alphabetic # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR 1B82 ; Alphabetic # Mc SUNDANESE SIGN PANGWISAD 1B83..1BA0 ; Alphabetic # Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA @@ -760,9 +763,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 2183..2184 ; Alphabetic # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C 2185..2188 ; Alphabetic # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND 24B6..24E9 ; Alphabetic # So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z -2C00..2C2E ; Alphabetic # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C30..2C5E ; Alphabetic # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE -2C60..2C7B ; Alphabetic # L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E +2C00..2C7B ; Alphabetic # L& [124] GLAGOLITIC CAPITAL LETTER AZU..LATIN LETTER SMALL CAPITAL TURNED E 2C7C..2C7D ; Alphabetic # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V 2C7E..2CE4 ; Alphabetic # L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI 2CEB..2CEE ; Alphabetic # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA @@ -802,8 +803,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 31A0..31BF ; Alphabetic # Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH 31F0..31FF ; Alphabetic # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO 3400..4DBF ; Alphabetic # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF -4E00..9FFC ; Alphabetic # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC -A000..A014 ; Alphabetic # Lo [21] YI SYLLABLE IT..YI SYLLABLE E +4E00..A014 ; Alphabetic # Lo [21013] CJK UNIFIED IDEOGRAPH-4E00..YI SYLLABLE E A015 ; Alphabetic # Lm YI SYLLABLE WU A016..A48C ; Alphabetic # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR A4D0..A4F7 ; Alphabetic # Lo [40] LISU LETTER BA..LISU LETTER OE @@ -828,8 +828,11 @@ A771..A787 ; Alphabetic # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER A788 ; Alphabetic # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; Alphabetic # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; Alphabetic # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7BF ; Alphabetic # L& [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U -A7C2..A7CA ; Alphabetic # L& [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CA ; Alphabetic # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D0..A7D1 ; Alphabetic # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G +A7D3 ; Alphabetic # L& LATIN SMALL LETTER DOUBLE THORN +A7D5..A7D9 ; Alphabetic # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7F2..A7F4 ; Alphabetic # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; Alphabetic # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; Alphabetic # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I A7F8..A7F9 ; Alphabetic # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE @@ -985,9 +988,20 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 104D8..104FB ; Alphabetic # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA 10500..10527 ; Alphabetic # Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE 10530..10563 ; Alphabetic # Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW +10570..1057A ; Alphabetic # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; Alphabetic # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; Alphabetic # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; Alphabetic # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE +10597..105A1 ; Alphabetic # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; Alphabetic # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; Alphabetic # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; Alphabetic # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10600..10736 ; Alphabetic # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; Alphabetic # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; Alphabetic # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 +10780..10785 ; Alphabetic # Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; Alphabetic # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; Alphabetic # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10800..10805 ; Alphabetic # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA 10808 ; Alphabetic # Lo CYPRIOT SYLLABLE JO 1080A..10835 ; Alphabetic # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO @@ -1028,6 +1042,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 10F00..10F1C ; Alphabetic # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F27 ; Alphabetic # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; Alphabetic # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN +10F70..10F81 ; Alphabetic # Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH 10FB0..10FC4 ; Alphabetic # Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW 10FE0..10FF6 ; Alphabetic # Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH 11000 ; Alphabetic # Mc BRAHMI SIGN CANDRABINDU @@ -1035,11 +1050,15 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 11002 ; Alphabetic # Mc BRAHMI SIGN VISARGA 11003..11037 ; Alphabetic # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA 11038..11045 ; Alphabetic # Mn [14] BRAHMI VOWEL SIGN AA..BRAHMI VOWEL SIGN AU +11071..11072 ; Alphabetic # Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O +11073..11074 ; Alphabetic # Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O +11075 ; Alphabetic # Lo BRAHMI LETTER OLD TAMIL LLA 11082 ; Alphabetic # Mc KAITHI SIGN VISARGA 11083..110AF ; Alphabetic # Lo [45] KAITHI LETTER A..KAITHI LETTER HA 110B0..110B2 ; Alphabetic # Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II 110B3..110B6 ; Alphabetic # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI 110B7..110B8 ; Alphabetic # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU +110C2 ; Alphabetic # Mn KAITHI VOWEL SIGN VOCALIC R 110D0..110E8 ; Alphabetic # Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE 11100..11102 ; Alphabetic # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA 11103..11126 ; Alphabetic # Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA @@ -1144,6 +1163,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 11722..11725 ; Alphabetic # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11726 ; Alphabetic # Mc AHOM VOWEL SIGN E 11727..1172A ; Alphabetic # Mn [4] AHOM VOWEL SIGN AW..AHOM VOWEL SIGN AM +11740..11746 ; Alphabetic # Lo [7] AHOM LETTER CA..AHOM LETTER LLA 11800..1182B ; Alphabetic # Lo [44] DOGRA LETTER A..DOGRA LETTER RRA 1182C..1182E ; Alphabetic # Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II 1182F..11837 ; Alphabetic # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA @@ -1185,7 +1205,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 11A8A..11A96 ; Alphabetic # Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA 11A97 ; Alphabetic # Mc SOYOMBO SIGN VISARGA 11A9D ; Alphabetic # Lo SOYOMBO MARK PLUTA -11AC0..11AF8 ; Alphabetic # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL +11AB0..11AF8 ; Alphabetic # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL 11C00..11C08 ; Alphabetic # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; Alphabetic # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C2F ; Alphabetic # Mc BHAIKSUKI VOWEL SIGN AA @@ -1227,10 +1247,12 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 12000..12399 ; Alphabetic # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U 12400..1246E ; Alphabetic # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM 12480..12543 ; Alphabetic # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU +12F90..12FF0 ; Alphabetic # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 13000..1342E ; Alphabetic # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 14400..14646 ; Alphabetic # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 16800..16A38 ; Alphabetic # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; Alphabetic # Lo [31] MRO LETTER TA..MRO LETTER TEK +16A70..16ABE ; Alphabetic # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA 16AD0..16AED ; Alphabetic # Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I 16B00..16B2F ; Alphabetic # Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU 16B40..16B43 ; Alphabetic # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM @@ -1249,7 +1271,10 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 17000..187F7 ; Alphabetic # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; Alphabetic # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 18D00..18D08 ; Alphabetic # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 -1B000..1B11E ; Alphabetic # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2 +1AFF0..1AFF3 ; Alphabetic # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 +1AFF5..1AFFB ; Alphabetic # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 +1AFFD..1AFFE ; Alphabetic # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 +1B000..1B122 ; Alphabetic # Lo [291] KATAKANA LETTER ARCHAIC E..KATAKANA LETTER ARCHAIC WU 1B150..1B152 ; Alphabetic # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO 1B164..1B167 ; Alphabetic # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N 1B170..1B2FB ; Alphabetic # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB @@ -1288,6 +1313,9 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 1D78A..1D7A8 ; Alphabetic # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA 1D7AA..1D7C2 ; Alphabetic # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA 1D7C4..1D7CB ; Alphabetic # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +1DF00..1DF09 ; Alphabetic # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK +1DF0A ; Alphabetic # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK +1DF0B..1DF1E ; Alphabetic # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL 1E000..1E006 ; Alphabetic # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE 1E008..1E018 ; Alphabetic # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU 1E01B..1E021 ; Alphabetic # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI @@ -1296,7 +1324,12 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 1E100..1E12C ; Alphabetic # Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W 1E137..1E13D ; Alphabetic # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER 1E14E ; Alphabetic # Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ +1E290..1E2AD ; Alphabetic # Lo [30] TOTO LETTER PA..TOTO LETTER A 1E2C0..1E2EB ; Alphabetic # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH +1E7E0..1E7E6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO +1E7E8..1E7EB ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE +1E7ED..1E7EE ; Alphabetic # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE +1E7F0..1E7FE ; Alphabetic # Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE 1E800..1E8C4 ; Alphabetic # Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON 1E900..1E943 ; Alphabetic # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA 1E947 ; Alphabetic # Mn ADLAM HAMZA @@ -1337,15 +1370,15 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 1F130..1F149 ; Alphabetic # So [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z 1F150..1F169 ; Alphabetic # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z 1F170..1F189 ; Alphabetic # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z -20000..2A6DD ; Alphabetic # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD -2A700..2B734 ; Alphabetic # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +20000..2A6DF ; Alphabetic # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF +2A700..2B738 ; Alphabetic # Lo [4153] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B738 2B740..2B81D ; Alphabetic # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D 2B820..2CEA1 ; Alphabetic # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 2CEB0..2EBE0 ; Alphabetic # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 2F800..2FA1D ; Alphabetic # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D 30000..3134A ; Alphabetic # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A -# Total code points: 132875 +# Total code points: 133396 # ================================================ @@ -1798,7 +1831,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 2170..217F ; Lowercase # Nl [16] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND 2184 ; Lowercase # L& LATIN SMALL LETTER REVERSED C 24D0..24E9 ; Lowercase # So [26] CIRCLED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z -2C30..2C5E ; Lowercase # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C30..2C5F ; Lowercase # L& [48] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI 2C61 ; Lowercase # L& LATIN SMALL LETTER L WITH DOUBLE BAR 2C65..2C66 ; Lowercase # L& [2] LATIN SMALL LETTER A WITH STROKE..LATIN SMALL LETTER T WITH DIAGONAL STROKE 2C68 ; Lowercase # L& LATIN SMALL LETTER H WITH DESCENDER @@ -1970,9 +2003,15 @@ A7B9 ; Lowercase # L& LATIN SMALL LETTER U WITH STROKE A7BB ; Lowercase # L& LATIN SMALL LETTER GLOTTAL A A7BD ; Lowercase # L& LATIN SMALL LETTER GLOTTAL I A7BF ; Lowercase # L& LATIN SMALL LETTER GLOTTAL U +A7C1 ; Lowercase # L& LATIN SMALL LETTER OLD POLISH O A7C3 ; Lowercase # L& LATIN SMALL LETTER ANGLICANA W A7C8 ; Lowercase # L& LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY A7CA ; Lowercase # L& LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D1 ; Lowercase # L& LATIN SMALL LETTER CLOSED INSULAR G +A7D3 ; Lowercase # L& LATIN SMALL LETTER DOUBLE THORN +A7D5 ; Lowercase # L& LATIN SMALL LETTER DOUBLE WYNN +A7D7 ; Lowercase # L& LATIN SMALL LETTER MIDDLE SCOTS S +A7D9 ; Lowercase # L& LATIN SMALL LETTER SIGMOID S A7F6 ; Lowercase # L& LATIN SMALL LETTER REVERSED HALF H A7F8..A7F9 ; Lowercase # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE A7FA ; Lowercase # L& LATIN LETTER SMALL CAPITAL TURNED M @@ -1985,6 +2024,14 @@ FB13..FB17 ; Lowercase # L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN S FF41..FF5A ; Lowercase # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z 10428..1044F ; Lowercase # L& [40] DESERET SMALL LETTER LONG I..DESERET SMALL LETTER EW 104D8..104FB ; Lowercase # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA +10597..105A1 ; Lowercase # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; Lowercase # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; Lowercase # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; Lowercase # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE +10780 ; Lowercase # Lm MODIFIER LETTER SMALL CAPITAL AA +10783..10785 ; Lowercase # Lm [3] MODIFIER LETTER SMALL AE..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; Lowercase # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; Lowercase # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10CC0..10CF2 ; Lowercase # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US 118C0..118DF ; Lowercase # L& [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E60..16E7F ; Lowercase # L& [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y @@ -2016,9 +2063,11 @@ FF41..FF5A ; Lowercase # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 1D7AA..1D7C2 ; Lowercase # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA 1D7C4..1D7C9 ; Lowercase # L& [6] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL 1D7CB ; Lowercase # L& MATHEMATICAL BOLD SMALL DIGAMMA +1DF00..1DF09 ; Lowercase # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK +1DF0B..1DF1E ; Lowercase # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL 1E922..1E943 ; Lowercase # L& [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA -# Total code points: 2344 +# Total code points: 2471 # ================================================ @@ -2458,7 +2507,7 @@ FF41..FF5A ; Lowercase # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 2160..216F ; Uppercase # Nl [16] ROMAN NUMERAL ONE..ROMAN NUMERAL ONE THOUSAND 2183 ; Uppercase # L& ROMAN NUMERAL REVERSED ONE HUNDRED 24B6..24CF ; Uppercase # So [26] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN CAPITAL LETTER Z -2C00..2C2E ; Uppercase # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C00..2C2F ; Uppercase # L& [48] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI 2C60 ; Uppercase # L& LATIN CAPITAL LETTER L WITH DOUBLE BAR 2C62..2C64 ; Uppercase # L& [3] LATIN CAPITAL LETTER L WITH MIDDLE TILDE..LATIN CAPITAL LETTER R WITH TAIL 2C67 ; Uppercase # L& LATIN CAPITAL LETTER H WITH DESCENDER @@ -2623,13 +2672,21 @@ A7B8 ; Uppercase # L& LATIN CAPITAL LETTER U WITH STROKE A7BA ; Uppercase # L& LATIN CAPITAL LETTER GLOTTAL A A7BC ; Uppercase # L& LATIN CAPITAL LETTER GLOTTAL I A7BE ; Uppercase # L& LATIN CAPITAL LETTER GLOTTAL U +A7C0 ; Uppercase # L& LATIN CAPITAL LETTER OLD POLISH O A7C2 ; Uppercase # L& LATIN CAPITAL LETTER ANGLICANA W A7C4..A7C7 ; Uppercase # L& [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY A7C9 ; Uppercase # L& LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +A7D0 ; Uppercase # L& LATIN CAPITAL LETTER CLOSED INSULAR G +A7D6 ; Uppercase # L& LATIN CAPITAL LETTER MIDDLE SCOTS S +A7D8 ; Uppercase # L& LATIN CAPITAL LETTER SIGMOID S A7F5 ; Uppercase # L& LATIN CAPITAL LETTER REVERSED HALF H FF21..FF3A ; Uppercase # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z 10400..10427 ; Uppercase # L& [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW 104B0..104D3 ; Uppercase # L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA +10570..1057A ; Uppercase # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; Uppercase # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; Uppercase # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; Uppercase # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE 10C80..10CB2 ; Uppercase # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 118A0..118BF ; Uppercase # L& [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO 16E40..16E5F ; Uppercase # L& [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y @@ -2669,7 +2726,7 @@ FF21..FF3A ; Uppercase # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH 1F150..1F169 ; Uppercase # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z 1F170..1F189 ; Uppercase # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z -# Total code points: 1911 +# Total code points: 1951 # ================================================ @@ -2761,9 +2818,7 @@ FF21..FF3A ; Uppercase # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH 2160..217F ; Cased # Nl [32] ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND 2183..2184 ; Cased # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C 24B6..24E9 ; Cased # So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z -2C00..2C2E ; Cased # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C30..2C5E ; Cased # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE -2C60..2C7B ; Cased # L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E +2C00..2C7B ; Cased # L& [124] GLAGOLITIC CAPITAL LETTER AZU..LATIN LETTER SMALL CAPITAL TURNED E 2C7C..2C7D ; Cased # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V 2C7E..2CE4 ; Cased # L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI 2CEB..2CEE ; Cased # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA @@ -2778,8 +2833,10 @@ A722..A76F ; Cased # L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN A770 ; Cased # Lm MODIFIER LETTER US A771..A787 ; Cased # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T A78B..A78E ; Cased # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT -A790..A7BF ; Cased # L& [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U -A7C2..A7CA ; Cased # L& [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CA ; Cased # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D0..A7D1 ; Cased # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G +A7D3 ; Cased # L& LATIN SMALL LETTER DOUBLE THORN +A7D5..A7D9 ; Cased # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S A7F5..A7F6 ; Cased # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F8..A7F9 ; Cased # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE A7FA ; Cased # L& LATIN LETTER SMALL CAPITAL TURNED M @@ -2794,6 +2851,18 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 10400..1044F ; Cased # L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW 104B0..104D3 ; Cased # L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA 104D8..104FB ; Cased # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA +10570..1057A ; Cased # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; Cased # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; Cased # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; Cased # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE +10597..105A1 ; Cased # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; Cased # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; Cased # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; Cased # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE +10780 ; Cased # Lm MODIFIER LETTER SMALL CAPITAL AA +10783..10785 ; Cased # Lm [3] MODIFIER LETTER SMALL AE..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; Cased # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; Cased # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10C80..10CB2 ; Cased # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 10CC0..10CF2 ; Cased # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US 118A0..118DF ; Cased # L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO @@ -2828,12 +2897,14 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 1D78A..1D7A8 ; Cased # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA 1D7AA..1D7C2 ; Cased # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA 1D7C4..1D7CB ; Cased # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +1DF00..1DF09 ; Cased # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK +1DF0B..1DF1E ; Cased # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL 1E900..1E943 ; Cased # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA 1F130..1F149 ; Cased # So [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z 1F150..1F169 ; Cased # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z 1F170..1F189 ; Cased # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z -# Total code points: 4286 +# Total code points: 4453 # ================================================ @@ -2908,7 +2979,11 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 0828 ; Case_Ignorable # Lm SAMARITAN MODIFIER LETTER I 0829..082D ; Case_Ignorable # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA 0859..085B ; Case_Ignorable # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK -08D3..08E1 ; Case_Ignorable # Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA +0888 ; Case_Ignorable # Sk ARABIC RAISED ROUND DOT +0890..0891 ; Case_Ignorable # Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE +0898..089F ; Case_Ignorable # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +08C9 ; Case_Ignorable # Lm ARABIC SMALL FARSI YEH +08CA..08E1 ; Case_Ignorable # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA 08E2 ; Case_Ignorable # Cf ARABIC DISPUTED END OF AYAH 08E3..0902 ; Case_Ignorable # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA 093A ; Case_Ignorable # Mn DEVANAGARI VOWEL SIGN OE @@ -2951,6 +3026,7 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 0BCD ; Case_Ignorable # Mn TAMIL SIGN VIRAMA 0C00 ; Case_Ignorable # Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE 0C04 ; Case_Ignorable # Mn TELUGU SIGN COMBINING ANUSVARA ABOVE +0C3C ; Case_Ignorable # Mn TELUGU SIGN NUKTA 0C3E..0C40 ; Case_Ignorable # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II 0C46..0C48 ; Case_Ignorable # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI 0C4A..0C4D ; Case_Ignorable # Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA @@ -3003,7 +3079,7 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 10FC ; Case_Ignorable # Lm MODIFIER LETTER GEORGIAN NAR 135D..135F ; Case_Ignorable # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK 1712..1714 ; Case_Ignorable # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA -1732..1734 ; Case_Ignorable # Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD +1732..1733 ; Case_Ignorable # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U 1752..1753 ; Case_Ignorable # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U 1772..1773 ; Case_Ignorable # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U 17B4..17B5 ; Case_Ignorable # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA @@ -3014,6 +3090,7 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 17DD ; Case_Ignorable # Mn KHMER SIGN ATTHACAN 180B..180D ; Case_Ignorable # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE 180E ; Case_Ignorable # Cf MONGOLIAN VOWEL SEPARATOR +180F ; Case_Ignorable # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR 1843 ; Case_Ignorable # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN 1885..1886 ; Case_Ignorable # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA 18A9 ; Case_Ignorable # Mn MONGOLIAN LETTER ALI GALI DAGALGA @@ -3033,7 +3110,7 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 1AA7 ; Case_Ignorable # Lm TAI THAM SIGN MAI YAMOK 1AB0..1ABD ; Case_Ignorable # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW 1ABE ; Case_Ignorable # Me COMBINING PARENTHESES OVERLAY -1ABF..1AC0 ; Case_Ignorable # Mn [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW +1ABF..1ACE ; Case_Ignorable # Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T 1B00..1B03 ; Case_Ignorable # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG 1B34 ; Case_Ignorable # Mn BALINESE SIGN REREKAN 1B36..1B3A ; Case_Ignorable # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA @@ -3060,8 +3137,7 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 1D2C..1D6A ; Case_Ignorable # Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI 1D78 ; Case_Ignorable # Lm MODIFIER LETTER CYRILLIC EN 1D9B..1DBF ; Case_Ignorable # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA -1DC0..1DF9 ; Case_Ignorable # Mn [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW -1DFB..1DFF ; Case_Ignorable # Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW +1DC0..1DFF ; Case_Ignorable # Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW 1FBD ; Case_Ignorable # Sk GREEK KORONIS 1FBF..1FC1 ; Case_Ignorable # Sk [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI 1FCD..1FCF ; Case_Ignorable # Sk [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI @@ -3114,6 +3190,7 @@ A720..A721 ; Case_Ignorable # Sk [2] MODIFIER LETTER STRESS AND HIGH TONE.. A770 ; Case_Ignorable # Lm MODIFIER LETTER US A788 ; Case_Ignorable # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A789..A78A ; Case_Ignorable # Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN +A7F2..A7F4 ; Case_Ignorable # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F8..A7F9 ; Case_Ignorable # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE A802 ; Case_Ignorable # Mn SYLOTI NAGRI SIGN DVISVARA A806 ; Case_Ignorable # Mn SYLOTI NAGRI SIGN HASANTA @@ -3156,7 +3233,7 @@ ABE5 ; Case_Ignorable # Mn MEETEI MAYEK VOWEL SIGN ANAP ABE8 ; Case_Ignorable # Mn MEETEI MAYEK VOWEL SIGN UNAP ABED ; Case_Ignorable # Mn MEETEI MAYEK APUN IYEK FB1E ; Case_Ignorable # Mn HEBREW POINT JUDEO-SPANISH VARIKA -FBB2..FBC1 ; Case_Ignorable # Sk [16] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL SMALL TAH BELOW +FBB2..FBC2 ; Case_Ignorable # Sk [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE FE00..FE0F ; Case_Ignorable # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 FE13 ; Case_Ignorable # Po PRESENTATION FORM FOR VERTICAL COLON FE20..FE2F ; Case_Ignorable # Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF @@ -3175,6 +3252,9 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 101FD ; Case_Ignorable # Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE 102E0 ; Case_Ignorable # Mn COPTIC EPACT THOUSANDS MARK 10376..1037A ; Case_Ignorable # Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII +10780..10785 ; Case_Ignorable # Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; Case_Ignorable # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; Case_Ignorable # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10A01..10A03 ; Case_Ignorable # Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R 10A05..10A06 ; Case_Ignorable # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O 10A0C..10A0F ; Case_Ignorable # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA @@ -3184,12 +3264,16 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 10D24..10D27 ; Case_Ignorable # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI 10EAB..10EAC ; Case_Ignorable # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK 10F46..10F50 ; Case_Ignorable # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW +10F82..10F85 ; Case_Ignorable # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW 11001 ; Case_Ignorable # Mn BRAHMI SIGN ANUSVARA 11038..11046 ; Case_Ignorable # Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA +11070 ; Case_Ignorable # Mn BRAHMI SIGN OLD TAMIL VIRAMA +11073..11074 ; Case_Ignorable # Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O 1107F..11081 ; Case_Ignorable # Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA 110B3..110B6 ; Case_Ignorable # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI 110B9..110BA ; Case_Ignorable # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA 110BD ; Case_Ignorable # Cf KAITHI NUMBER SIGN +110C2 ; Case_Ignorable # Mn KAITHI VOWEL SIGN VOCALIC R 110CD ; Case_Ignorable # Cf KAITHI NUMBER SIGN ABOVE 11100..11102 ; Case_Ignorable # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA 11127..1112B ; Case_Ignorable # Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU @@ -3274,8 +3358,13 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 16FE0..16FE1 ; Case_Ignorable # Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK 16FE3 ; Case_Ignorable # Lm OLD CHINESE ITERATION MARK 16FE4 ; Case_Ignorable # Mn KHITAN SMALL SCRIPT FILLER +1AFF0..1AFF3 ; Case_Ignorable # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 +1AFF5..1AFFB ; Case_Ignorable # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 +1AFFD..1AFFE ; Case_Ignorable # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 1BC9D..1BC9E ; Case_Ignorable # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK 1BCA0..1BCA3 ; Case_Ignorable # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP +1CF00..1CF2D ; Case_Ignorable # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT +1CF30..1CF46 ; Case_Ignorable # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG 1D167..1D169 ; Case_Ignorable # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 1D173..1D17A ; Case_Ignorable # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE 1D17B..1D182 ; Case_Ignorable # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE @@ -3295,6 +3384,7 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 1E026..1E02A ; Case_Ignorable # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA 1E130..1E136 ; Case_Ignorable # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D 1E137..1E13D ; Case_Ignorable # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER +1E2AE ; Case_Ignorable # Mn TOTO SIGN RISING TONE 1E2EC..1E2EF ; Case_Ignorable # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E8D0..1E8D6 ; Case_Ignorable # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E94A ; Case_Ignorable # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA @@ -3304,7 +3394,7 @@ E0001 ; Case_Ignorable # Cf LANGUAGE TAG E0020..E007F ; Case_Ignorable # Cf [96] TAG SPACE..CANCEL TAG E0100..E01EF ; Case_Ignorable # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 2413 +# Total code points: 2602 # ================================================ @@ -3738,7 +3828,7 @@ E0100..E01EF ; Case_Ignorable # Mn [240] VARIATION SELECTOR-17..VARIATION SELEC 2160..216F ; Changes_When_Lowercased # Nl [16] ROMAN NUMERAL ONE..ROMAN NUMERAL ONE THOUSAND 2183 ; Changes_When_Lowercased # L& ROMAN NUMERAL REVERSED ONE HUNDRED 24B6..24CF ; Changes_When_Lowercased # So [26] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN CAPITAL LETTER Z -2C00..2C2E ; Changes_When_Lowercased # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C00..2C2F ; Changes_When_Lowercased # L& [48] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI 2C60 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER L WITH DOUBLE BAR 2C62..2C64 ; Changes_When_Lowercased # L& [3] LATIN CAPITAL LETTER L WITH MIDDLE TILDE..LATIN CAPITAL LETTER R WITH TAIL 2C67 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER H WITH DESCENDER @@ -3903,19 +3993,27 @@ A7B8 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER U WITH S A7BA ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER GLOTTAL A A7BC ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER GLOTTAL I A7BE ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER GLOTTAL U +A7C0 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER OLD POLISH O A7C2 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER ANGLICANA W A7C4..A7C7 ; Changes_When_Lowercased # L& [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY A7C9 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +A7D0 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER CLOSED INSULAR G +A7D6 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER MIDDLE SCOTS S +A7D8 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER SIGMOID S A7F5 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER REVERSED HALF H FF21..FF3A ; Changes_When_Lowercased # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z 10400..10427 ; Changes_When_Lowercased # L& [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW 104B0..104D3 ; Changes_When_Lowercased # L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA +10570..1057A ; Changes_When_Lowercased # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; Changes_When_Lowercased # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; Changes_When_Lowercased # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; Changes_When_Lowercased # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE 10C80..10CB2 ; Changes_When_Lowercased # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 118A0..118BF ; Changes_When_Lowercased # L& [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO 16E40..16E5F ; Changes_When_Lowercased # L& [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y 1E900..1E921 ; Changes_When_Lowercased # L& [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA -# Total code points: 1393 +# Total code points: 1433 # ================================================ @@ -4363,7 +4461,7 @@ FF21..FF3A ; Changes_When_Lowercased # L& [26] FULLWIDTH LATIN CAPITAL LETTE 2170..217F ; Changes_When_Uppercased # Nl [16] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND 2184 ; Changes_When_Uppercased # L& LATIN SMALL LETTER REVERSED C 24D0..24E9 ; Changes_When_Uppercased # So [26] CIRCLED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z -2C30..2C5E ; Changes_When_Uppercased # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C30..2C5F ; Changes_When_Uppercased # L& [48] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI 2C61 ; Changes_When_Uppercased # L& LATIN SMALL LETTER L WITH DOUBLE BAR 2C65..2C66 ; Changes_When_Uppercased # L& [2] LATIN SMALL LETTER A WITH STROKE..LATIN SMALL LETTER T WITH DIAGONAL STROKE 2C68 ; Changes_When_Uppercased # L& LATIN SMALL LETTER H WITH DESCENDER @@ -4528,9 +4626,13 @@ A7B9 ; Changes_When_Uppercased # L& LATIN SMALL LETTER U WITH STR A7BB ; Changes_When_Uppercased # L& LATIN SMALL LETTER GLOTTAL A A7BD ; Changes_When_Uppercased # L& LATIN SMALL LETTER GLOTTAL I A7BF ; Changes_When_Uppercased # L& LATIN SMALL LETTER GLOTTAL U +A7C1 ; Changes_When_Uppercased # L& LATIN SMALL LETTER OLD POLISH O A7C3 ; Changes_When_Uppercased # L& LATIN SMALL LETTER ANGLICANA W A7C8 ; Changes_When_Uppercased # L& LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY A7CA ; Changes_When_Uppercased # L& LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D1 ; Changes_When_Uppercased # L& LATIN SMALL LETTER CLOSED INSULAR G +A7D7 ; Changes_When_Uppercased # L& LATIN SMALL LETTER MIDDLE SCOTS S +A7D9 ; Changes_When_Uppercased # L& LATIN SMALL LETTER SIGMOID S A7F6 ; Changes_When_Uppercased # L& LATIN SMALL LETTER REVERSED HALF H AB53 ; Changes_When_Uppercased # L& LATIN SMALL LETTER CHI AB70..ABBF ; Changes_When_Uppercased # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA @@ -4539,12 +4641,16 @@ FB13..FB17 ; Changes_When_Uppercased # L& [5] ARMENIAN SMALL LIGATURE MEN N FF41..FF5A ; Changes_When_Uppercased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z 10428..1044F ; Changes_When_Uppercased # L& [40] DESERET SMALL LETTER LONG I..DESERET SMALL LETTER EW 104D8..104FB ; Changes_When_Uppercased # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA +10597..105A1 ; Changes_When_Uppercased # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; Changes_When_Uppercased # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; Changes_When_Uppercased # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; Changes_When_Uppercased # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10CC0..10CF2 ; Changes_When_Uppercased # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US 118C0..118DF ; Changes_When_Uppercased # L& [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E60..16E7F ; Changes_When_Uppercased # L& [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y 1E922..1E943 ; Changes_When_Uppercased # L& [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA -# Total code points: 1485 +# Total code points: 1525 # ================================================ @@ -4991,7 +5097,7 @@ FF41..FF5A ; Changes_When_Uppercased # L& [26] FULLWIDTH LATIN SMALL LETTER 2170..217F ; Changes_When_Titlecased # Nl [16] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND 2184 ; Changes_When_Titlecased # L& LATIN SMALL LETTER REVERSED C 24D0..24E9 ; Changes_When_Titlecased # So [26] CIRCLED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z -2C30..2C5E ; Changes_When_Titlecased # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C30..2C5F ; Changes_When_Titlecased # L& [48] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI 2C61 ; Changes_When_Titlecased # L& LATIN SMALL LETTER L WITH DOUBLE BAR 2C65..2C66 ; Changes_When_Titlecased # L& [2] LATIN SMALL LETTER A WITH STROKE..LATIN SMALL LETTER T WITH DIAGONAL STROKE 2C68 ; Changes_When_Titlecased # L& LATIN SMALL LETTER H WITH DESCENDER @@ -5156,9 +5262,13 @@ A7B9 ; Changes_When_Titlecased # L& LATIN SMALL LETTER U WITH STR A7BB ; Changes_When_Titlecased # L& LATIN SMALL LETTER GLOTTAL A A7BD ; Changes_When_Titlecased # L& LATIN SMALL LETTER GLOTTAL I A7BF ; Changes_When_Titlecased # L& LATIN SMALL LETTER GLOTTAL U +A7C1 ; Changes_When_Titlecased # L& LATIN SMALL LETTER OLD POLISH O A7C3 ; Changes_When_Titlecased # L& LATIN SMALL LETTER ANGLICANA W A7C8 ; Changes_When_Titlecased # L& LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY A7CA ; Changes_When_Titlecased # L& LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D1 ; Changes_When_Titlecased # L& LATIN SMALL LETTER CLOSED INSULAR G +A7D7 ; Changes_When_Titlecased # L& LATIN SMALL LETTER MIDDLE SCOTS S +A7D9 ; Changes_When_Titlecased # L& LATIN SMALL LETTER SIGMOID S A7F6 ; Changes_When_Titlecased # L& LATIN SMALL LETTER REVERSED HALF H AB53 ; Changes_When_Titlecased # L& LATIN SMALL LETTER CHI AB70..ABBF ; Changes_When_Titlecased # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA @@ -5167,12 +5277,16 @@ FB13..FB17 ; Changes_When_Titlecased # L& [5] ARMENIAN SMALL LIGATURE MEN N FF41..FF5A ; Changes_When_Titlecased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z 10428..1044F ; Changes_When_Titlecased # L& [40] DESERET SMALL LETTER LONG I..DESERET SMALL LETTER EW 104D8..104FB ; Changes_When_Titlecased # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA +10597..105A1 ; Changes_When_Titlecased # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; Changes_When_Titlecased # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; Changes_When_Titlecased # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; Changes_When_Titlecased # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10CC0..10CF2 ; Changes_When_Titlecased # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US 118C0..118DF ; Changes_When_Titlecased # L& [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E60..16E7F ; Changes_When_Titlecased # L& [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y 1E922..1E943 ; Changes_When_Titlecased # L& [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA -# Total code points: 1412 +# Total code points: 1452 # ================================================ @@ -5616,7 +5730,7 @@ FF41..FF5A ; Changes_When_Titlecased # L& [26] FULLWIDTH LATIN SMALL LETTER 2160..216F ; Changes_When_Casefolded # Nl [16] ROMAN NUMERAL ONE..ROMAN NUMERAL ONE THOUSAND 2183 ; Changes_When_Casefolded # L& ROMAN NUMERAL REVERSED ONE HUNDRED 24B6..24CF ; Changes_When_Casefolded # So [26] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN CAPITAL LETTER Z -2C00..2C2E ; Changes_When_Casefolded # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C00..2C2F ; Changes_When_Casefolded # L& [48] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI 2C60 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER L WITH DOUBLE BAR 2C62..2C64 ; Changes_When_Casefolded # L& [3] LATIN CAPITAL LETTER L WITH MIDDLE TILDE..LATIN CAPITAL LETTER R WITH TAIL 2C67 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER H WITH DESCENDER @@ -5781,9 +5895,13 @@ A7B8 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER U WITH S A7BA ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER GLOTTAL A A7BC ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER GLOTTAL I A7BE ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER GLOTTAL U +A7C0 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER OLD POLISH O A7C2 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER ANGLICANA W A7C4..A7C7 ; Changes_When_Casefolded # L& [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY A7C9 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +A7D0 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER CLOSED INSULAR G +A7D6 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER MIDDLE SCOTS S +A7D8 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER SIGMOID S A7F5 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER REVERSED HALF H AB70..ABBF ; Changes_When_Casefolded # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA FB00..FB06 ; Changes_When_Casefolded # L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST @@ -5791,12 +5909,16 @@ FB13..FB17 ; Changes_When_Casefolded # L& [5] ARMENIAN SMALL LIGATURE MEN N FF21..FF3A ; Changes_When_Casefolded # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z 10400..10427 ; Changes_When_Casefolded # L& [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW 104B0..104D3 ; Changes_When_Casefolded # L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA +10570..1057A ; Changes_When_Casefolded # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; Changes_When_Casefolded # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; Changes_When_Casefolded # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; Changes_When_Casefolded # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE 10C80..10CB2 ; Changes_When_Casefolded # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 118A0..118BF ; Changes_When_Casefolded # L& [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO 16E40..16E5F ; Changes_When_Casefolded # L& [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y 1E900..1E921 ; Changes_When_Casefolded # L& [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA -# Total code points: 1466 +# Total code points: 1506 # ================================================ @@ -5893,9 +6015,7 @@ FF21..FF3A ; Changes_When_Casefolded # L& [26] FULLWIDTH LATIN CAPITAL LETTE 2160..217F ; Changes_When_Casemapped # Nl [32] ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND 2183..2184 ; Changes_When_Casemapped # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C 24B6..24E9 ; Changes_When_Casemapped # So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z -2C00..2C2E ; Changes_When_Casemapped # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C30..2C5E ; Changes_When_Casemapped # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE -2C60..2C70 ; Changes_When_Casemapped # L& [17] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN CAPITAL LETTER TURNED ALPHA +2C00..2C70 ; Changes_When_Casemapped # L& [113] GLAGOLITIC CAPITAL LETTER AZU..LATIN CAPITAL LETTER TURNED ALPHA 2C72..2C73 ; Changes_When_Casemapped # L& [2] LATIN CAPITAL LETTER W WITH HOOK..LATIN SMALL LETTER W WITH HOOK 2C75..2C76 ; Changes_When_Casemapped # L& [2] LATIN CAPITAL LETTER HALF H..LATIN SMALL LETTER HALF H 2C7E..2CE3 ; Changes_When_Casemapped # L& [102] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SMALL LETTER OLD NUBIAN WAU @@ -5912,8 +6032,9 @@ A779..A787 ; Changes_When_Casemapped # L& [15] LATIN CAPITAL LETTER INSULAR A78B..A78D ; Changes_When_Casemapped # L& [3] LATIN CAPITAL LETTER SALTILLO..LATIN CAPITAL LETTER TURNED H A790..A794 ; Changes_When_Casemapped # L& [5] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER C WITH PALATAL HOOK A796..A7AE ; Changes_When_Casemapped # L& [25] LATIN CAPITAL LETTER B WITH FLOURISH..LATIN CAPITAL LETTER SMALL CAPITAL I -A7B0..A7BF ; Changes_When_Casemapped # L& [16] LATIN CAPITAL LETTER TURNED K..LATIN SMALL LETTER GLOTTAL U -A7C2..A7CA ; Changes_When_Casemapped # L& [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7B0..A7CA ; Changes_When_Casemapped # L& [27] LATIN CAPITAL LETTER TURNED K..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D0..A7D1 ; Changes_When_Casemapped # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G +A7D6..A7D9 ; Changes_When_Casemapped # L& [4] LATIN CAPITAL LETTER MIDDLE SCOTS S..LATIN SMALL LETTER SIGMOID S A7F5..A7F6 ; Changes_When_Casemapped # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H AB53 ; Changes_When_Casemapped # L& LATIN SMALL LETTER CHI AB70..ABBF ; Changes_When_Casemapped # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA @@ -5924,13 +6045,21 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 10400..1044F ; Changes_When_Casemapped # L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW 104B0..104D3 ; Changes_When_Casemapped # L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA 104D8..104FB ; Changes_When_Casemapped # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA +10570..1057A ; Changes_When_Casemapped # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; Changes_When_Casemapped # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; Changes_When_Casemapped # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; Changes_When_Casemapped # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE +10597..105A1 ; Changes_When_Casemapped # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; Changes_When_Casemapped # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; Changes_When_Casemapped # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; Changes_When_Casemapped # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10C80..10CB2 ; Changes_When_Casemapped # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 10CC0..10CF2 ; Changes_When_Casemapped # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US 118A0..118DF ; Changes_When_Casemapped # L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E40..16E7F ; Changes_When_Casemapped # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 1E900..1E943 ; Changes_When_Casemapped # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA -# Total code points: 2847 +# Total code points: 2927 # ================================================ @@ -6003,8 +6132,10 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 0828 ; ID_Start # Lm SAMARITAN MODIFIER LETTER I 0840..0858 ; ID_Start # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN 0860..086A ; ID_Start # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA -08A0..08B4 ; ID_Start # Lo [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW -08B6..08C7 ; ID_Start # Lo [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE +0870..0887 ; ID_Start # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT +0889..088E ; ID_Start # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL +08A0..08C8 ; ID_Start # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF +08C9 ; ID_Start # Lm ARABIC SMALL FARSI YEH 0904..0939 ; ID_Start # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA 093D ; ID_Start # Lo DEVANAGARI SIGN AVAGRAHA 0950 ; ID_Start # Lo DEVANAGARI OM @@ -6070,6 +6201,7 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 0C2A..0C39 ; ID_Start # Lo [16] TELUGU LETTER PA..TELUGU LETTER HA 0C3D ; ID_Start # Lo TELUGU SIGN AVAGRAHA 0C58..0C5A ; ID_Start # Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA +0C5D ; ID_Start # Lo TELUGU LETTER NAKAARA POLLU 0C60..0C61 ; ID_Start # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL 0C80 ; ID_Start # Lo KANNADA SIGN SPACING CANDRABINDU 0C85..0C8C ; ID_Start # Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L @@ -6078,7 +6210,7 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 0CAA..0CB3 ; ID_Start # Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA 0CB5..0CB9 ; ID_Start # Lo [5] KANNADA LETTER VA..KANNADA LETTER HA 0CBD ; ID_Start # Lo KANNADA SIGN AVAGRAHA -0CDE ; ID_Start # Lo KANNADA LETTER FA +0CDD..0CDE ; ID_Start # Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA 0CE0..0CE1 ; ID_Start # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL 0CF1..0CF2 ; ID_Start # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA 0D04..0D0C ; ID_Start # Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L @@ -6153,9 +6285,8 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 16A0..16EA ; ID_Start # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X 16EE..16F0 ; ID_Start # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL 16F1..16F8 ; ID_Start # Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC -1700..170C ; ID_Start # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA -170E..1711 ; ID_Start # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA -1720..1731 ; ID_Start # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA +1700..1711 ; ID_Start # Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA +171F..1731 ; ID_Start # Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA 1740..1751 ; ID_Start # Lo [18] BUHID LETTER A..BUHID LETTER HA 1760..176C ; ID_Start # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA 176E..1770 ; ID_Start # Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA @@ -6179,7 +6310,7 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 1A20..1A54 ; ID_Start # Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA 1AA7 ; ID_Start # Lm TAI THAM SIGN MAI YAMOK 1B05..1B33 ; ID_Start # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA -1B45..1B4B ; ID_Start # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B45..1B4C ; ID_Start # Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA 1B83..1BA0 ; ID_Start # Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA 1BAE..1BAF ; ID_Start # Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA 1BBA..1BE5 ; ID_Start # Lo [44] SUNDANESE AVAGRAHA..BATAK LETTER U @@ -6242,9 +6373,7 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 2160..2182 ; ID_Start # Nl [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND 2183..2184 ; ID_Start # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C 2185..2188 ; ID_Start # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND -2C00..2C2E ; ID_Start # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C30..2C5E ; ID_Start # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE -2C60..2C7B ; ID_Start # L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E +2C00..2C7B ; ID_Start # L& [124] GLAGOLITIC CAPITAL LETTER AZU..LATIN LETTER SMALL CAPITAL TURNED E 2C7C..2C7D ; ID_Start # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V 2C7E..2CE4 ; ID_Start # L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI 2CEB..2CEE ; ID_Start # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA @@ -6283,8 +6412,7 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 31A0..31BF ; ID_Start # Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH 31F0..31FF ; ID_Start # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO 3400..4DBF ; ID_Start # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF -4E00..9FFC ; ID_Start # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC -A000..A014 ; ID_Start # Lo [21] YI SYLLABLE IT..YI SYLLABLE E +4E00..A014 ; ID_Start # Lo [21013] CJK UNIFIED IDEOGRAPH-4E00..YI SYLLABLE E A015 ; ID_Start # Lm YI SYLLABLE WU A016..A48C ; ID_Start # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR A4D0..A4F7 ; ID_Start # Lo [40] LISU LETTER BA..LISU LETTER OE @@ -6307,8 +6435,11 @@ A771..A787 ; ID_Start # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER I A788 ; ID_Start # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; ID_Start # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; ID_Start # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7BF ; ID_Start # L& [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U -A7C2..A7CA ; ID_Start # L& [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CA ; ID_Start # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D0..A7D1 ; ID_Start # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G +A7D3 ; ID_Start # L& LATIN SMALL LETTER DOUBLE THORN +A7D5..A7D9 ; ID_Start # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7F2..A7F4 ; ID_Start # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; ID_Start # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; ID_Start # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I A7F8..A7F9 ; ID_Start # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE @@ -6418,9 +6549,20 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 104D8..104FB ; ID_Start # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA 10500..10527 ; ID_Start # Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE 10530..10563 ; ID_Start # Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW +10570..1057A ; ID_Start # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; ID_Start # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; ID_Start # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; ID_Start # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE +10597..105A1 ; ID_Start # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; ID_Start # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; ID_Start # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; ID_Start # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10600..10736 ; ID_Start # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; ID_Start # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; ID_Start # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 +10780..10785 ; ID_Start # Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; ID_Start # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; ID_Start # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10800..10805 ; ID_Start # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA 10808 ; ID_Start # Lo CYPRIOT SYLLABLE JO 1080A..10835 ; ID_Start # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO @@ -6456,9 +6598,12 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 10F00..10F1C ; ID_Start # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F27 ; ID_Start # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; ID_Start # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN +10F70..10F81 ; ID_Start # Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH 10FB0..10FC4 ; ID_Start # Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW 10FE0..10FF6 ; ID_Start # Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH 11003..11037 ; ID_Start # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA +11071..11072 ; ID_Start # Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O +11075 ; ID_Start # Lo BRAHMI LETTER OLD TAMIL LLA 11083..110AF ; ID_Start # Lo [45] KAITHI LETTER A..KAITHI LETTER HA 110D0..110E8 ; ID_Start # Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE 11103..11126 ; ID_Start # Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA @@ -6500,6 +6645,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 11680..116AA ; ID_Start # Lo [43] TAKRI LETTER A..TAKRI LETTER RRA 116B8 ; ID_Start # Lo TAKRI LETTER ARCHAIC KHA 11700..1171A ; ID_Start # Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA +11740..11746 ; ID_Start # Lo [7] AHOM LETTER CA..AHOM LETTER LLA 11800..1182B ; ID_Start # Lo [44] DOGRA LETTER A..DOGRA LETTER RRA 118A0..118DF ; ID_Start # L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 118FF..11906 ; ID_Start # Lo [8] WARANG CITI OM..DIVES AKURU LETTER E @@ -6519,7 +6665,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 11A50 ; ID_Start # Lo SOYOMBO LETTER A 11A5C..11A89 ; ID_Start # Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA 11A9D ; ID_Start # Lo SOYOMBO MARK PLUTA -11AC0..11AF8 ; ID_Start # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL +11AB0..11AF8 ; ID_Start # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL 11C00..11C08 ; ID_Start # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; ID_Start # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C40 ; ID_Start # Lo BHAIKSUKI SIGN AVAGRAHA @@ -6537,10 +6683,12 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 12000..12399 ; ID_Start # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U 12400..1246E ; ID_Start # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM 12480..12543 ; ID_Start # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU +12F90..12FF0 ; ID_Start # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 13000..1342E ; ID_Start # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 14400..14646 ; ID_Start # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 16800..16A38 ; ID_Start # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; ID_Start # Lo [31] MRO LETTER TA..MRO LETTER TEK +16A70..16ABE ; ID_Start # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA 16AD0..16AED ; ID_Start # Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I 16B00..16B2F ; ID_Start # Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU 16B40..16B43 ; ID_Start # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM @@ -6555,7 +6703,10 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 17000..187F7 ; ID_Start # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; ID_Start # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 18D00..18D08 ; ID_Start # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 -1B000..1B11E ; ID_Start # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2 +1AFF0..1AFF3 ; ID_Start # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 +1AFF5..1AFFB ; ID_Start # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 +1AFFD..1AFFE ; ID_Start # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 +1B000..1B122 ; ID_Start # Lo [291] KATAKANA LETTER ARCHAIC E..KATAKANA LETTER ARCHAIC WU 1B150..1B152 ; ID_Start # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO 1B164..1B167 ; ID_Start # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N 1B170..1B2FB ; ID_Start # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB @@ -6593,10 +6744,18 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 1D78A..1D7A8 ; ID_Start # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA 1D7AA..1D7C2 ; ID_Start # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA 1D7C4..1D7CB ; ID_Start # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +1DF00..1DF09 ; ID_Start # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK +1DF0A ; ID_Start # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK +1DF0B..1DF1E ; ID_Start # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL 1E100..1E12C ; ID_Start # Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W 1E137..1E13D ; ID_Start # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER 1E14E ; ID_Start # Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ +1E290..1E2AD ; ID_Start # Lo [30] TOTO LETTER PA..TOTO LETTER A 1E2C0..1E2EB ; ID_Start # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH +1E7E0..1E7E6 ; ID_Start # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO +1E7E8..1E7EB ; ID_Start # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE +1E7ED..1E7EE ; ID_Start # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE +1E7F0..1E7FE ; ID_Start # Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE 1E800..1E8C4 ; ID_Start # Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON 1E900..1E943 ; ID_Start # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA 1E94B ; ID_Start # Lm ADLAM NASALIZATION MARK @@ -6633,15 +6792,15 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 1EEA1..1EEA3 ; ID_Start # Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL 1EEA5..1EEA9 ; ID_Start # Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH 1EEAB..1EEBB ; ID_Start # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN -20000..2A6DD ; ID_Start # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD -2A700..2B734 ; ID_Start # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +20000..2A6DF ; ID_Start # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF +2A700..2B738 ; ID_Start # Lo [4153] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B738 2B740..2B81D ; ID_Start # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D 2B820..2CEA1 ; ID_Start # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 2CEB0..2EBE0 ; ID_Start # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 2F800..2FA1D ; ID_Start # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D 30000..3134A ; ID_Start # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A -# Total code points: 131482 +# Total code points: 131997 # ================================================ @@ -6746,9 +6905,12 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 0840..0858 ; ID_Continue # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN 0859..085B ; ID_Continue # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK 0860..086A ; ID_Continue # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA -08A0..08B4 ; ID_Continue # Lo [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW -08B6..08C7 ; ID_Continue # Lo [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE -08D3..08E1 ; ID_Continue # Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA +0870..0887 ; ID_Continue # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT +0889..088E ; ID_Continue # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL +0898..089F ; ID_Continue # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +08A0..08C8 ; ID_Continue # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF +08C9 ; ID_Continue # Lm ARABIC SMALL FARSI YEH +08CA..08E1 ; ID_Continue # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA 08E3..0902 ; ID_Continue # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA 0903 ; ID_Continue # Mc DEVANAGARI SIGN VISARGA 0904..0939 ; ID_Continue # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA @@ -6886,6 +7048,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 0C0E..0C10 ; ID_Continue # Lo [3] TELUGU LETTER E..TELUGU LETTER AI 0C12..0C28 ; ID_Continue # Lo [23] TELUGU LETTER O..TELUGU LETTER NA 0C2A..0C39 ; ID_Continue # Lo [16] TELUGU LETTER PA..TELUGU LETTER HA +0C3C ; ID_Continue # Mn TELUGU SIGN NUKTA 0C3D ; ID_Continue # Lo TELUGU SIGN AVAGRAHA 0C3E..0C40 ; ID_Continue # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II 0C41..0C44 ; ID_Continue # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR @@ -6893,6 +7056,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 0C4A..0C4D ; ID_Continue # Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA 0C55..0C56 ; ID_Continue # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK 0C58..0C5A ; ID_Continue # Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA +0C5D ; ID_Continue # Lo TELUGU LETTER NAKAARA POLLU 0C60..0C61 ; ID_Continue # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL 0C62..0C63 ; ID_Continue # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL 0C66..0C6F ; ID_Continue # Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE @@ -6914,7 +7078,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 0CCA..0CCB ; ID_Continue # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CCC..0CCD ; ID_Continue # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA 0CD5..0CD6 ; ID_Continue # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK -0CDE ; ID_Continue # Lo KANNADA LETTER FA +0CDD..0CDE ; ID_Continue # Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA 0CE0..0CE1 ; ID_Continue # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL 0CE2..0CE3 ; ID_Continue # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL 0CE6..0CEF ; ID_Continue # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE @@ -7058,11 +7222,12 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 16A0..16EA ; ID_Continue # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X 16EE..16F0 ; ID_Continue # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL 16F1..16F8 ; ID_Continue # Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC -1700..170C ; ID_Continue # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA -170E..1711 ; ID_Continue # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA +1700..1711 ; ID_Continue # Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA 1712..1714 ; ID_Continue # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA -1720..1731 ; ID_Continue # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA -1732..1734 ; ID_Continue # Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD +1715 ; ID_Continue # Mc TAGALOG SIGN PAMUDPOD +171F..1731 ; ID_Continue # Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA +1732..1733 ; ID_Continue # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U +1734 ; ID_Continue # Mc HANUNOO SIGN PAMUDPOD 1740..1751 ; ID_Continue # Lo [18] BUHID LETTER A..BUHID LETTER HA 1752..1753 ; ID_Continue # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U 1760..176C ; ID_Continue # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA @@ -7081,6 +7246,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 17DD ; ID_Continue # Mn KHMER SIGN ATTHACAN 17E0..17E9 ; ID_Continue # Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE 180B..180D ; ID_Continue # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE +180F ; ID_Continue # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR 1810..1819 ; ID_Continue # Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE 1820..1842 ; ID_Continue # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI 1843 ; ID_Continue # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN @@ -7128,7 +7294,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 1A90..1A99 ; ID_Continue # Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE 1AA7 ; ID_Continue # Lm TAI THAM SIGN MAI YAMOK 1AB0..1ABD ; ID_Continue # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW -1ABF..1AC0 ; ID_Continue # Mn [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW +1ABF..1ACE ; ID_Continue # Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T 1B00..1B03 ; ID_Continue # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG 1B04 ; ID_Continue # Mc BALINESE SIGN BISAH 1B05..1B33 ; ID_Continue # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA @@ -7140,7 +7306,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 1B3D..1B41 ; ID_Continue # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG 1B42 ; ID_Continue # Mn BALINESE VOWEL SIGN PEPET 1B43..1B44 ; ID_Continue # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG -1B45..1B4B ; ID_Continue # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B45..1B4C ; ID_Continue # Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA 1B50..1B59 ; ID_Continue # Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE 1B6B..1B73 ; ID_Continue # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG 1B80..1B81 ; ID_Continue # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR @@ -7194,8 +7360,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 1D78 ; ID_Continue # Lm MODIFIER LETTER CYRILLIC EN 1D79..1D9A ; ID_Continue # L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK 1D9B..1DBF ; ID_Continue # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA -1DC0..1DF9 ; ID_Continue # Mn [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW -1DFB..1DFF ; ID_Continue # Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW +1DC0..1DFF ; ID_Continue # Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW 1E00..1F15 ; ID_Continue # L& [278] LATIN CAPITAL LETTER A WITH RING BELOW..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA 1F18..1F1D ; ID_Continue # L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA 1F20..1F45 ; ID_Continue # L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA @@ -7243,9 +7408,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 2160..2182 ; ID_Continue # Nl [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND 2183..2184 ; ID_Continue # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C 2185..2188 ; ID_Continue # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND -2C00..2C2E ; ID_Continue # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C30..2C5E ; ID_Continue # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE -2C60..2C7B ; ID_Continue # L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E +2C00..2C7B ; ID_Continue # L& [124] GLAGOLITIC CAPITAL LETTER AZU..LATIN LETTER SMALL CAPITAL TURNED E 2C7C..2C7D ; ID_Continue # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V 2C7E..2CE4 ; ID_Continue # L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI 2CEB..2CEE ; ID_Continue # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA @@ -7290,8 +7453,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 31A0..31BF ; ID_Continue # Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH 31F0..31FF ; ID_Continue # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO 3400..4DBF ; ID_Continue # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF -4E00..9FFC ; ID_Continue # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC -A000..A014 ; ID_Continue # Lo [21] YI SYLLABLE IT..YI SYLLABLE E +4E00..A014 ; ID_Continue # Lo [21013] CJK UNIFIED IDEOGRAPH-4E00..YI SYLLABLE E A015 ; ID_Continue # Lm YI SYLLABLE WU A016..A48C ; ID_Continue # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR A4D0..A4F7 ; ID_Continue # Lo [40] LISU LETTER BA..LISU LETTER OE @@ -7319,8 +7481,11 @@ A771..A787 ; ID_Continue # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTE A788 ; ID_Continue # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; ID_Continue # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; ID_Continue # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7BF ; ID_Continue # L& [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U -A7C2..A7CA ; ID_Continue # L& [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CA ; ID_Continue # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D0..A7D1 ; ID_Continue # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G +A7D3 ; ID_Continue # L& LATIN SMALL LETTER DOUBLE THORN +A7D5..A7D9 ; ID_Continue # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7F2..A7F4 ; ID_Continue # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; ID_Continue # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; ID_Continue # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I A7F8..A7F9 ; ID_Continue # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE @@ -7499,9 +7664,20 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 104D8..104FB ; ID_Continue # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA 10500..10527 ; ID_Continue # Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE 10530..10563 ; ID_Continue # Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW +10570..1057A ; ID_Continue # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; ID_Continue # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; ID_Continue # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; ID_Continue # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE +10597..105A1 ; ID_Continue # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; ID_Continue # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; ID_Continue # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; ID_Continue # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10600..10736 ; ID_Continue # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; ID_Continue # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; ID_Continue # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 +10780..10785 ; ID_Continue # Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; ID_Continue # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; ID_Continue # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10800..10805 ; ID_Continue # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA 10808 ; ID_Continue # Lo CYPRIOT SYLLABLE JO 1080A..10835 ; ID_Continue # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO @@ -7547,6 +7723,8 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 10F27 ; ID_Continue # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; ID_Continue # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN 10F46..10F50 ; ID_Continue # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW +10F70..10F81 ; ID_Continue # Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH +10F82..10F85 ; ID_Continue # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW 10FB0..10FC4 ; ID_Continue # Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW 10FE0..10FF6 ; ID_Continue # Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH 11000 ; ID_Continue # Mc BRAHMI SIGN CANDRABINDU @@ -7555,6 +7733,10 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 11003..11037 ; ID_Continue # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA 11038..11046 ; ID_Continue # Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA 11066..1106F ; ID_Continue # Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE +11070 ; ID_Continue # Mn BRAHMI SIGN OLD TAMIL VIRAMA +11071..11072 ; ID_Continue # Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O +11073..11074 ; ID_Continue # Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O +11075 ; ID_Continue # Lo BRAHMI LETTER OLD TAMIL LLA 1107F..11081 ; ID_Continue # Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA 11082 ; ID_Continue # Mc KAITHI SIGN VISARGA 11083..110AF ; ID_Continue # Lo [45] KAITHI LETTER A..KAITHI LETTER HA @@ -7562,6 +7744,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 110B3..110B6 ; ID_Continue # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI 110B7..110B8 ; ID_Continue # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU 110B9..110BA ; ID_Continue # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA +110C2 ; ID_Continue # Mn KAITHI VOWEL SIGN VOCALIC R 110D0..110E8 ; ID_Continue # Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE 110F0..110F9 ; ID_Continue # Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE 11100..11102 ; ID_Continue # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA @@ -7687,6 +7870,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 11726 ; ID_Continue # Mc AHOM VOWEL SIGN E 11727..1172B ; ID_Continue # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER 11730..11739 ; ID_Continue # Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE +11740..11746 ; ID_Continue # Lo [7] AHOM LETTER CA..AHOM LETTER LLA 11800..1182B ; ID_Continue # Lo [44] DOGRA LETTER A..DOGRA LETTER RRA 1182C..1182E ; ID_Continue # Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II 1182F..11837 ; ID_Continue # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA @@ -7737,7 +7921,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 11A97 ; ID_Continue # Mc SOYOMBO SIGN VISARGA 11A98..11A99 ; ID_Continue # Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER 11A9D ; ID_Continue # Lo SOYOMBO MARK PLUTA -11AC0..11AF8 ; ID_Continue # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL +11AB0..11AF8 ; ID_Continue # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL 11C00..11C08 ; ID_Continue # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; ID_Continue # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C2F ; ID_Continue # Mc BHAIKSUKI VOWEL SIGN AA @@ -7783,11 +7967,14 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 12000..12399 ; ID_Continue # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U 12400..1246E ; ID_Continue # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM 12480..12543 ; ID_Continue # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU +12F90..12FF0 ; ID_Continue # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 13000..1342E ; ID_Continue # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 14400..14646 ; ID_Continue # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 16800..16A38 ; ID_Continue # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; ID_Continue # Lo [31] MRO LETTER TA..MRO LETTER TEK 16A60..16A69 ; ID_Continue # Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE +16A70..16ABE ; ID_Continue # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA +16AC0..16AC9 ; ID_Continue # Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE 16AD0..16AED ; ID_Continue # Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I 16AF0..16AF4 ; ID_Continue # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE 16B00..16B2F ; ID_Continue # Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU @@ -7810,7 +7997,10 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 17000..187F7 ; ID_Continue # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; ID_Continue # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 18D00..18D08 ; ID_Continue # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 -1B000..1B11E ; ID_Continue # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2 +1AFF0..1AFF3 ; ID_Continue # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 +1AFF5..1AFFB ; ID_Continue # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 +1AFFD..1AFFE ; ID_Continue # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 +1B000..1B122 ; ID_Continue # Lo [291] KATAKANA LETTER ARCHAIC E..KATAKANA LETTER ARCHAIC WU 1B150..1B152 ; ID_Continue # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO 1B164..1B167 ; ID_Continue # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N 1B170..1B2FB ; ID_Continue # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB @@ -7819,6 +8009,8 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 1BC80..1BC88 ; ID_Continue # Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL 1BC90..1BC99 ; ID_Continue # Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW 1BC9D..1BC9E ; ID_Continue # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK +1CF00..1CF2D ; ID_Continue # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT +1CF30..1CF46 ; ID_Continue # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG 1D165..1D166 ; ID_Continue # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM 1D167..1D169 ; ID_Continue # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 1D16D..1D172 ; ID_Continue # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 @@ -7863,6 +8055,9 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 1DA84 ; ID_Continue # Mn SIGNWRITING LOCATION HEAD NECK 1DA9B..1DA9F ; ID_Continue # Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 1DAA1..1DAAF ; ID_Continue # Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 +1DF00..1DF09 ; ID_Continue # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK +1DF0A ; ID_Continue # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK +1DF0B..1DF1E ; ID_Continue # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL 1E000..1E006 ; ID_Continue # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE 1E008..1E018 ; ID_Continue # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU 1E01B..1E021 ; ID_Continue # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI @@ -7873,9 +8068,15 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 1E137..1E13D ; ID_Continue # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER 1E140..1E149 ; ID_Continue # Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE 1E14E ; ID_Continue # Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ +1E290..1E2AD ; ID_Continue # Lo [30] TOTO LETTER PA..TOTO LETTER A +1E2AE ; ID_Continue # Mn TOTO SIGN RISING TONE 1E2C0..1E2EB ; ID_Continue # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH 1E2EC..1E2EF ; ID_Continue # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E2F0..1E2F9 ; ID_Continue # Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE +1E7E0..1E7E6 ; ID_Continue # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO +1E7E8..1E7EB ; ID_Continue # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE +1E7ED..1E7EE ; ID_Continue # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE +1E7F0..1E7FE ; ID_Continue # Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE 1E800..1E8C4 ; ID_Continue # Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON 1E8D0..1E8D6 ; ID_Continue # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E900..1E943 ; ID_Continue # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA @@ -7916,8 +8117,8 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 1EEA5..1EEA9 ; ID_Continue # Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH 1EEAB..1EEBB ; ID_Continue # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN 1FBF0..1FBF9 ; ID_Continue # Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE -20000..2A6DD ; ID_Continue # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD -2A700..2B734 ; ID_Continue # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +20000..2A6DF ; ID_Continue # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF +2A700..2B738 ; ID_Continue # Lo [4153] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B738 2B740..2B81D ; ID_Continue # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D 2B820..2CEA1 ; ID_Continue # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 2CEB0..2EBE0 ; ID_Continue # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 @@ -7925,7 +8126,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 30000..3134A ; ID_Continue # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 134434 +# Total code points: 135072 # ================================================ @@ -7995,8 +8196,10 @@ E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR 0828 ; XID_Start # Lm SAMARITAN MODIFIER LETTER I 0840..0858 ; XID_Start # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN 0860..086A ; XID_Start # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA -08A0..08B4 ; XID_Start # Lo [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW -08B6..08C7 ; XID_Start # Lo [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE +0870..0887 ; XID_Start # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT +0889..088E ; XID_Start # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL +08A0..08C8 ; XID_Start # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF +08C9 ; XID_Start # Lm ARABIC SMALL FARSI YEH 0904..0939 ; XID_Start # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA 093D ; XID_Start # Lo DEVANAGARI SIGN AVAGRAHA 0950 ; XID_Start # Lo DEVANAGARI OM @@ -8062,6 +8265,7 @@ E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR 0C2A..0C39 ; XID_Start # Lo [16] TELUGU LETTER PA..TELUGU LETTER HA 0C3D ; XID_Start # Lo TELUGU SIGN AVAGRAHA 0C58..0C5A ; XID_Start # Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA +0C5D ; XID_Start # Lo TELUGU LETTER NAKAARA POLLU 0C60..0C61 ; XID_Start # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL 0C80 ; XID_Start # Lo KANNADA SIGN SPACING CANDRABINDU 0C85..0C8C ; XID_Start # Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L @@ -8070,7 +8274,7 @@ E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR 0CAA..0CB3 ; XID_Start # Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA 0CB5..0CB9 ; XID_Start # Lo [5] KANNADA LETTER VA..KANNADA LETTER HA 0CBD ; XID_Start # Lo KANNADA SIGN AVAGRAHA -0CDE ; XID_Start # Lo KANNADA LETTER FA +0CDD..0CDE ; XID_Start # Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA 0CE0..0CE1 ; XID_Start # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL 0CF1..0CF2 ; XID_Start # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA 0D04..0D0C ; XID_Start # Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L @@ -8145,9 +8349,8 @@ E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR 16A0..16EA ; XID_Start # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X 16EE..16F0 ; XID_Start # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL 16F1..16F8 ; XID_Start # Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC -1700..170C ; XID_Start # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA -170E..1711 ; XID_Start # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA -1720..1731 ; XID_Start # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA +1700..1711 ; XID_Start # Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA +171F..1731 ; XID_Start # Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA 1740..1751 ; XID_Start # Lo [18] BUHID LETTER A..BUHID LETTER HA 1760..176C ; XID_Start # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA 176E..1770 ; XID_Start # Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA @@ -8171,7 +8374,7 @@ E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR 1A20..1A54 ; XID_Start # Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA 1AA7 ; XID_Start # Lm TAI THAM SIGN MAI YAMOK 1B05..1B33 ; XID_Start # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA -1B45..1B4B ; XID_Start # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B45..1B4C ; XID_Start # Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA 1B83..1BA0 ; XID_Start # Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA 1BAE..1BAF ; XID_Start # Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA 1BBA..1BE5 ; XID_Start # Lo [44] SUNDANESE AVAGRAHA..BATAK LETTER U @@ -8234,9 +8437,7 @@ E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR 2160..2182 ; XID_Start # Nl [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND 2183..2184 ; XID_Start # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C 2185..2188 ; XID_Start # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND -2C00..2C2E ; XID_Start # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C30..2C5E ; XID_Start # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE -2C60..2C7B ; XID_Start # L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E +2C00..2C7B ; XID_Start # L& [124] GLAGOLITIC CAPITAL LETTER AZU..LATIN LETTER SMALL CAPITAL TURNED E 2C7C..2C7D ; XID_Start # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V 2C7E..2CE4 ; XID_Start # L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI 2CEB..2CEE ; XID_Start # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA @@ -8274,8 +8475,7 @@ E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR 31A0..31BF ; XID_Start # Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH 31F0..31FF ; XID_Start # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO 3400..4DBF ; XID_Start # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF -4E00..9FFC ; XID_Start # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC -A000..A014 ; XID_Start # Lo [21] YI SYLLABLE IT..YI SYLLABLE E +4E00..A014 ; XID_Start # Lo [21013] CJK UNIFIED IDEOGRAPH-4E00..YI SYLLABLE E A015 ; XID_Start # Lm YI SYLLABLE WU A016..A48C ; XID_Start # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR A4D0..A4F7 ; XID_Start # Lo [40] LISU LETTER BA..LISU LETTER OE @@ -8298,8 +8498,11 @@ A771..A787 ; XID_Start # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER A788 ; XID_Start # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; XID_Start # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; XID_Start # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7BF ; XID_Start # L& [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U -A7C2..A7CA ; XID_Start # L& [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CA ; XID_Start # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D0..A7D1 ; XID_Start # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G +A7D3 ; XID_Start # L& LATIN SMALL LETTER DOUBLE THORN +A7D5..A7D9 ; XID_Start # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7F2..A7F4 ; XID_Start # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; XID_Start # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; XID_Start # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I A7F8..A7F9 ; XID_Start # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE @@ -8414,9 +8617,20 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 104D8..104FB ; XID_Start # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA 10500..10527 ; XID_Start # Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE 10530..10563 ; XID_Start # Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW +10570..1057A ; XID_Start # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; XID_Start # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; XID_Start # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; XID_Start # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE +10597..105A1 ; XID_Start # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; XID_Start # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; XID_Start # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; XID_Start # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10600..10736 ; XID_Start # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; XID_Start # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; XID_Start # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 +10780..10785 ; XID_Start # Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; XID_Start # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; XID_Start # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10800..10805 ; XID_Start # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA 10808 ; XID_Start # Lo CYPRIOT SYLLABLE JO 1080A..10835 ; XID_Start # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO @@ -8452,9 +8666,12 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 10F00..10F1C ; XID_Start # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F27 ; XID_Start # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; XID_Start # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN +10F70..10F81 ; XID_Start # Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH 10FB0..10FC4 ; XID_Start # Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW 10FE0..10FF6 ; XID_Start # Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH 11003..11037 ; XID_Start # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA +11071..11072 ; XID_Start # Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O +11075 ; XID_Start # Lo BRAHMI LETTER OLD TAMIL LLA 11083..110AF ; XID_Start # Lo [45] KAITHI LETTER A..KAITHI LETTER HA 110D0..110E8 ; XID_Start # Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE 11103..11126 ; XID_Start # Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA @@ -8496,6 +8713,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 11680..116AA ; XID_Start # Lo [43] TAKRI LETTER A..TAKRI LETTER RRA 116B8 ; XID_Start # Lo TAKRI LETTER ARCHAIC KHA 11700..1171A ; XID_Start # Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA +11740..11746 ; XID_Start # Lo [7] AHOM LETTER CA..AHOM LETTER LLA 11800..1182B ; XID_Start # Lo [44] DOGRA LETTER A..DOGRA LETTER RRA 118A0..118DF ; XID_Start # L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 118FF..11906 ; XID_Start # Lo [8] WARANG CITI OM..DIVES AKURU LETTER E @@ -8515,7 +8733,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 11A50 ; XID_Start # Lo SOYOMBO LETTER A 11A5C..11A89 ; XID_Start # Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA 11A9D ; XID_Start # Lo SOYOMBO MARK PLUTA -11AC0..11AF8 ; XID_Start # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL +11AB0..11AF8 ; XID_Start # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL 11C00..11C08 ; XID_Start # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; XID_Start # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C40 ; XID_Start # Lo BHAIKSUKI SIGN AVAGRAHA @@ -8533,10 +8751,12 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 12000..12399 ; XID_Start # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U 12400..1246E ; XID_Start # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM 12480..12543 ; XID_Start # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU +12F90..12FF0 ; XID_Start # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 13000..1342E ; XID_Start # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 14400..14646 ; XID_Start # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 16800..16A38 ; XID_Start # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; XID_Start # Lo [31] MRO LETTER TA..MRO LETTER TEK +16A70..16ABE ; XID_Start # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA 16AD0..16AED ; XID_Start # Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I 16B00..16B2F ; XID_Start # Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU 16B40..16B43 ; XID_Start # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM @@ -8551,7 +8771,10 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 17000..187F7 ; XID_Start # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; XID_Start # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 18D00..18D08 ; XID_Start # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 -1B000..1B11E ; XID_Start # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2 +1AFF0..1AFF3 ; XID_Start # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 +1AFF5..1AFFB ; XID_Start # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 +1AFFD..1AFFE ; XID_Start # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 +1B000..1B122 ; XID_Start # Lo [291] KATAKANA LETTER ARCHAIC E..KATAKANA LETTER ARCHAIC WU 1B150..1B152 ; XID_Start # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO 1B164..1B167 ; XID_Start # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N 1B170..1B2FB ; XID_Start # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB @@ -8589,10 +8812,18 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 1D78A..1D7A8 ; XID_Start # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA 1D7AA..1D7C2 ; XID_Start # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA 1D7C4..1D7CB ; XID_Start # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +1DF00..1DF09 ; XID_Start # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK +1DF0A ; XID_Start # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK +1DF0B..1DF1E ; XID_Start # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL 1E100..1E12C ; XID_Start # Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W 1E137..1E13D ; XID_Start # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER 1E14E ; XID_Start # Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ +1E290..1E2AD ; XID_Start # Lo [30] TOTO LETTER PA..TOTO LETTER A 1E2C0..1E2EB ; XID_Start # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH +1E7E0..1E7E6 ; XID_Start # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO +1E7E8..1E7EB ; XID_Start # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE +1E7ED..1E7EE ; XID_Start # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE +1E7F0..1E7FE ; XID_Start # Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE 1E800..1E8C4 ; XID_Start # Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON 1E900..1E943 ; XID_Start # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA 1E94B ; XID_Start # Lm ADLAM NASALIZATION MARK @@ -8629,15 +8860,15 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 1EEA1..1EEA3 ; XID_Start # Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL 1EEA5..1EEA9 ; XID_Start # Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH 1EEAB..1EEBB ; XID_Start # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN -20000..2A6DD ; XID_Start # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD -2A700..2B734 ; XID_Start # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +20000..2A6DF ; XID_Start # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF +2A700..2B738 ; XID_Start # Lo [4153] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B738 2B740..2B81D ; XID_Start # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D 2B820..2CEA1 ; XID_Start # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 2CEB0..2EBE0 ; XID_Start # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 2F800..2FA1D ; XID_Start # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D 30000..3134A ; XID_Start # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A -# Total code points: 131459 +# Total code points: 131974 # ================================================ @@ -8738,9 +8969,12 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 0840..0858 ; XID_Continue # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN 0859..085B ; XID_Continue # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK 0860..086A ; XID_Continue # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA -08A0..08B4 ; XID_Continue # Lo [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW -08B6..08C7 ; XID_Continue # Lo [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE -08D3..08E1 ; XID_Continue # Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA +0870..0887 ; XID_Continue # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT +0889..088E ; XID_Continue # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL +0898..089F ; XID_Continue # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +08A0..08C8 ; XID_Continue # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF +08C9 ; XID_Continue # Lm ARABIC SMALL FARSI YEH +08CA..08E1 ; XID_Continue # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA 08E3..0902 ; XID_Continue # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA 0903 ; XID_Continue # Mc DEVANAGARI SIGN VISARGA 0904..0939 ; XID_Continue # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA @@ -8878,6 +9112,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 0C0E..0C10 ; XID_Continue # Lo [3] TELUGU LETTER E..TELUGU LETTER AI 0C12..0C28 ; XID_Continue # Lo [23] TELUGU LETTER O..TELUGU LETTER NA 0C2A..0C39 ; XID_Continue # Lo [16] TELUGU LETTER PA..TELUGU LETTER HA +0C3C ; XID_Continue # Mn TELUGU SIGN NUKTA 0C3D ; XID_Continue # Lo TELUGU SIGN AVAGRAHA 0C3E..0C40 ; XID_Continue # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II 0C41..0C44 ; XID_Continue # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR @@ -8885,6 +9120,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 0C4A..0C4D ; XID_Continue # Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA 0C55..0C56 ; XID_Continue # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK 0C58..0C5A ; XID_Continue # Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA +0C5D ; XID_Continue # Lo TELUGU LETTER NAKAARA POLLU 0C60..0C61 ; XID_Continue # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL 0C62..0C63 ; XID_Continue # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL 0C66..0C6F ; XID_Continue # Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE @@ -8906,7 +9142,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 0CCA..0CCB ; XID_Continue # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CCC..0CCD ; XID_Continue # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA 0CD5..0CD6 ; XID_Continue # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK -0CDE ; XID_Continue # Lo KANNADA LETTER FA +0CDD..0CDE ; XID_Continue # Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA 0CE0..0CE1 ; XID_Continue # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL 0CE2..0CE3 ; XID_Continue # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL 0CE6..0CEF ; XID_Continue # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE @@ -9050,11 +9286,12 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 16A0..16EA ; XID_Continue # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X 16EE..16F0 ; XID_Continue # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL 16F1..16F8 ; XID_Continue # Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC -1700..170C ; XID_Continue # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA -170E..1711 ; XID_Continue # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA +1700..1711 ; XID_Continue # Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA 1712..1714 ; XID_Continue # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA -1720..1731 ; XID_Continue # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA -1732..1734 ; XID_Continue # Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD +1715 ; XID_Continue # Mc TAGALOG SIGN PAMUDPOD +171F..1731 ; XID_Continue # Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA +1732..1733 ; XID_Continue # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U +1734 ; XID_Continue # Mc HANUNOO SIGN PAMUDPOD 1740..1751 ; XID_Continue # Lo [18] BUHID LETTER A..BUHID LETTER HA 1752..1753 ; XID_Continue # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U 1760..176C ; XID_Continue # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA @@ -9073,6 +9310,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 17DD ; XID_Continue # Mn KHMER SIGN ATTHACAN 17E0..17E9 ; XID_Continue # Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE 180B..180D ; XID_Continue # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE +180F ; XID_Continue # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR 1810..1819 ; XID_Continue # Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE 1820..1842 ; XID_Continue # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI 1843 ; XID_Continue # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN @@ -9120,7 +9358,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 1A90..1A99 ; XID_Continue # Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE 1AA7 ; XID_Continue # Lm TAI THAM SIGN MAI YAMOK 1AB0..1ABD ; XID_Continue # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW -1ABF..1AC0 ; XID_Continue # Mn [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW +1ABF..1ACE ; XID_Continue # Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T 1B00..1B03 ; XID_Continue # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG 1B04 ; XID_Continue # Mc BALINESE SIGN BISAH 1B05..1B33 ; XID_Continue # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA @@ -9132,7 +9370,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 1B3D..1B41 ; XID_Continue # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG 1B42 ; XID_Continue # Mn BALINESE VOWEL SIGN PEPET 1B43..1B44 ; XID_Continue # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG -1B45..1B4B ; XID_Continue # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B45..1B4C ; XID_Continue # Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA 1B50..1B59 ; XID_Continue # Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE 1B6B..1B73 ; XID_Continue # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG 1B80..1B81 ; XID_Continue # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR @@ -9186,8 +9424,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 1D78 ; XID_Continue # Lm MODIFIER LETTER CYRILLIC EN 1D79..1D9A ; XID_Continue # L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK 1D9B..1DBF ; XID_Continue # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA -1DC0..1DF9 ; XID_Continue # Mn [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW -1DFB..1DFF ; XID_Continue # Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW +1DC0..1DFF ; XID_Continue # Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW 1E00..1F15 ; XID_Continue # L& [278] LATIN CAPITAL LETTER A WITH RING BELOW..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA 1F18..1F1D ; XID_Continue # L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA 1F20..1F45 ; XID_Continue # L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA @@ -9235,9 +9472,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 2160..2182 ; XID_Continue # Nl [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND 2183..2184 ; XID_Continue # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C 2185..2188 ; XID_Continue # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND -2C00..2C2E ; XID_Continue # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C30..2C5E ; XID_Continue # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE -2C60..2C7B ; XID_Continue # L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E +2C00..2C7B ; XID_Continue # L& [124] GLAGOLITIC CAPITAL LETTER AZU..LATIN LETTER SMALL CAPITAL TURNED E 2C7C..2C7D ; XID_Continue # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V 2C7E..2CE4 ; XID_Continue # L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI 2CEB..2CEE ; XID_Continue # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA @@ -9281,8 +9516,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 31A0..31BF ; XID_Continue # Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH 31F0..31FF ; XID_Continue # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO 3400..4DBF ; XID_Continue # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF -4E00..9FFC ; XID_Continue # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC -A000..A014 ; XID_Continue # Lo [21] YI SYLLABLE IT..YI SYLLABLE E +4E00..A014 ; XID_Continue # Lo [21013] CJK UNIFIED IDEOGRAPH-4E00..YI SYLLABLE E A015 ; XID_Continue # Lm YI SYLLABLE WU A016..A48C ; XID_Continue # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR A4D0..A4F7 ; XID_Continue # Lo [40] LISU LETTER BA..LISU LETTER OE @@ -9310,8 +9544,11 @@ A771..A787 ; XID_Continue # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETT A788 ; XID_Continue # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; XID_Continue # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; XID_Continue # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7BF ; XID_Continue # L& [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U -A7C2..A7CA ; XID_Continue # L& [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CA ; XID_Continue # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D0..A7D1 ; XID_Continue # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G +A7D3 ; XID_Continue # L& LATIN SMALL LETTER DOUBLE THORN +A7D5..A7D9 ; XID_Continue # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7F2..A7F4 ; XID_Continue # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; XID_Continue # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; XID_Continue # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I A7F8..A7F9 ; XID_Continue # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE @@ -9496,9 +9733,20 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 104D8..104FB ; XID_Continue # L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA 10500..10527 ; XID_Continue # Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE 10530..10563 ; XID_Continue # Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW +10570..1057A ; XID_Continue # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; XID_Continue # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; XID_Continue # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; XID_Continue # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE +10597..105A1 ; XID_Continue # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; XID_Continue # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; XID_Continue # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; XID_Continue # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10600..10736 ; XID_Continue # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; XID_Continue # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; XID_Continue # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 +10780..10785 ; XID_Continue # Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; XID_Continue # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; XID_Continue # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10800..10805 ; XID_Continue # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA 10808 ; XID_Continue # Lo CYPRIOT SYLLABLE JO 1080A..10835 ; XID_Continue # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO @@ -9544,6 +9792,8 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 10F27 ; XID_Continue # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; XID_Continue # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN 10F46..10F50 ; XID_Continue # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW +10F70..10F81 ; XID_Continue # Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH +10F82..10F85 ; XID_Continue # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW 10FB0..10FC4 ; XID_Continue # Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW 10FE0..10FF6 ; XID_Continue # Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH 11000 ; XID_Continue # Mc BRAHMI SIGN CANDRABINDU @@ -9552,6 +9802,10 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 11003..11037 ; XID_Continue # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA 11038..11046 ; XID_Continue # Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA 11066..1106F ; XID_Continue # Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE +11070 ; XID_Continue # Mn BRAHMI SIGN OLD TAMIL VIRAMA +11071..11072 ; XID_Continue # Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O +11073..11074 ; XID_Continue # Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O +11075 ; XID_Continue # Lo BRAHMI LETTER OLD TAMIL LLA 1107F..11081 ; XID_Continue # Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA 11082 ; XID_Continue # Mc KAITHI SIGN VISARGA 11083..110AF ; XID_Continue # Lo [45] KAITHI LETTER A..KAITHI LETTER HA @@ -9559,6 +9813,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 110B3..110B6 ; XID_Continue # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI 110B7..110B8 ; XID_Continue # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU 110B9..110BA ; XID_Continue # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA +110C2 ; XID_Continue # Mn KAITHI VOWEL SIGN VOCALIC R 110D0..110E8 ; XID_Continue # Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE 110F0..110F9 ; XID_Continue # Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE 11100..11102 ; XID_Continue # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA @@ -9684,6 +9939,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 11726 ; XID_Continue # Mc AHOM VOWEL SIGN E 11727..1172B ; XID_Continue # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER 11730..11739 ; XID_Continue # Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE +11740..11746 ; XID_Continue # Lo [7] AHOM LETTER CA..AHOM LETTER LLA 11800..1182B ; XID_Continue # Lo [44] DOGRA LETTER A..DOGRA LETTER RRA 1182C..1182E ; XID_Continue # Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II 1182F..11837 ; XID_Continue # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA @@ -9734,7 +9990,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 11A97 ; XID_Continue # Mc SOYOMBO SIGN VISARGA 11A98..11A99 ; XID_Continue # Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER 11A9D ; XID_Continue # Lo SOYOMBO MARK PLUTA -11AC0..11AF8 ; XID_Continue # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL +11AB0..11AF8 ; XID_Continue # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL 11C00..11C08 ; XID_Continue # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; XID_Continue # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C2F ; XID_Continue # Mc BHAIKSUKI VOWEL SIGN AA @@ -9780,11 +10036,14 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 12000..12399 ; XID_Continue # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U 12400..1246E ; XID_Continue # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM 12480..12543 ; XID_Continue # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU +12F90..12FF0 ; XID_Continue # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 13000..1342E ; XID_Continue # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 14400..14646 ; XID_Continue # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 16800..16A38 ; XID_Continue # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; XID_Continue # Lo [31] MRO LETTER TA..MRO LETTER TEK 16A60..16A69 ; XID_Continue # Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE +16A70..16ABE ; XID_Continue # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA +16AC0..16AC9 ; XID_Continue # Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE 16AD0..16AED ; XID_Continue # Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I 16AF0..16AF4 ; XID_Continue # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE 16B00..16B2F ; XID_Continue # Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU @@ -9807,7 +10066,10 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 17000..187F7 ; XID_Continue # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; XID_Continue # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 18D00..18D08 ; XID_Continue # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 -1B000..1B11E ; XID_Continue # Lo [287] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER N-MU-MO-2 +1AFF0..1AFF3 ; XID_Continue # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 +1AFF5..1AFFB ; XID_Continue # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 +1AFFD..1AFFE ; XID_Continue # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 +1B000..1B122 ; XID_Continue # Lo [291] KATAKANA LETTER ARCHAIC E..KATAKANA LETTER ARCHAIC WU 1B150..1B152 ; XID_Continue # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO 1B164..1B167 ; XID_Continue # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N 1B170..1B2FB ; XID_Continue # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB @@ -9816,6 +10078,8 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 1BC80..1BC88 ; XID_Continue # Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL 1BC90..1BC99 ; XID_Continue # Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW 1BC9D..1BC9E ; XID_Continue # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK +1CF00..1CF2D ; XID_Continue # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT +1CF30..1CF46 ; XID_Continue # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG 1D165..1D166 ; XID_Continue # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM 1D167..1D169 ; XID_Continue # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 1D16D..1D172 ; XID_Continue # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 @@ -9860,6 +10124,9 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 1DA84 ; XID_Continue # Mn SIGNWRITING LOCATION HEAD NECK 1DA9B..1DA9F ; XID_Continue # Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 1DAA1..1DAAF ; XID_Continue # Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 +1DF00..1DF09 ; XID_Continue # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK +1DF0A ; XID_Continue # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK +1DF0B..1DF1E ; XID_Continue # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL 1E000..1E006 ; XID_Continue # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE 1E008..1E018 ; XID_Continue # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU 1E01B..1E021 ; XID_Continue # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI @@ -9870,9 +10137,15 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 1E137..1E13D ; XID_Continue # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER 1E140..1E149 ; XID_Continue # Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE 1E14E ; XID_Continue # Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ +1E290..1E2AD ; XID_Continue # Lo [30] TOTO LETTER PA..TOTO LETTER A +1E2AE ; XID_Continue # Mn TOTO SIGN RISING TONE 1E2C0..1E2EB ; XID_Continue # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH 1E2EC..1E2EF ; XID_Continue # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E2F0..1E2F9 ; XID_Continue # Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE +1E7E0..1E7E6 ; XID_Continue # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO +1E7E8..1E7EB ; XID_Continue # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE +1E7ED..1E7EE ; XID_Continue # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE +1E7F0..1E7FE ; XID_Continue # Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE 1E800..1E8C4 ; XID_Continue # Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON 1E8D0..1E8D6 ; XID_Continue # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E900..1E943 ; XID_Continue # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA @@ -9913,8 +10186,8 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 1EEA5..1EEA9 ; XID_Continue # Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH 1EEAB..1EEBB ; XID_Continue # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN 1FBF0..1FBF9 ; XID_Continue # Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE -20000..2A6DD ; XID_Continue # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD -2A700..2B734 ; XID_Continue # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +20000..2A6DF ; XID_Continue # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF +2A700..2B738 ; XID_Continue # Lo [4153] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B738 2B740..2B81D ; XID_Continue # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D 2B820..2CEA1 ; XID_Continue # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 2CEB0..2EBE0 ; XID_Continue # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 @@ -9922,7 +10195,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 30000..3134A ; XID_Continue # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A E0100..E01EF ; XID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 134415 +# Total code points: 135053 # ================================================ @@ -9943,6 +10216,7 @@ E0100..E01EF ; XID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTO 17B4..17B5 ; Default_Ignorable_Code_Point # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA 180B..180D ; Default_Ignorable_Code_Point # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE 180E ; Default_Ignorable_Code_Point # Cf MONGOLIAN VOWEL SEPARATOR +180F ; Default_Ignorable_Code_Point # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR 200B..200F ; Default_Ignorable_Code_Point # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK 202A..202E ; Default_Ignorable_Code_Point # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE 2060..2064 ; Default_Ignorable_Code_Point # Cf [5] WORD JOINER..INVISIBLE PLUS @@ -9963,7 +10237,7 @@ E0080..E00FF ; Default_Ignorable_Code_Point # Cn [128] .... -# Total code points: 4173 +# Total code points: 4174 # ================================================ @@ -9997,7 +10271,8 @@ E01F0..E0FFF ; Default_Ignorable_Code_Point # Cn [3600] .............. +2E52..2E54 ; Pattern_Syntax # Po [3] TIRONIAN SIGN CAPITAL ET..MEDIEVAL QUESTION MARK +2E55 ; Pattern_Syntax # Ps LEFT SQUARE BRACKET WITH STROKE +2E56 ; Pattern_Syntax # Pe RIGHT SQUARE BRACKET WITH STROKE +2E57 ; Pattern_Syntax # Ps LEFT SQUARE BRACKET WITH DOUBLE STROKE +2E58 ; Pattern_Syntax # Pe RIGHT SQUARE BRACKET WITH DOUBLE STROKE +2E59 ; Pattern_Syntax # Ps TOP HALF LEFT PARENTHESIS +2E5A ; Pattern_Syntax # Pe TOP HALF RIGHT PARENTHESIS +2E5B ; Pattern_Syntax # Ps BOTTOM HALF LEFT PARENTHESIS +2E5C ; Pattern_Syntax # Pe BOTTOM HALF RIGHT PARENTHESIS +2E5D ; Pattern_Syntax # Pd OBLIQUE HYPHEN +2E5E..2E7F ; Pattern_Syntax # Cn [34] .. 3001..3003 ; Pattern_Syntax # Po [3] IDEOGRAPHIC COMMA..DITTO MARK 3008 ; Pattern_Syntax # Ps LEFT ANGLE BRACKET 3009 ; Pattern_Syntax # Pe RIGHT ANGLE BRACKET @@ -1682,11 +1727,12 @@ FE45..FE46 ; Pattern_Syntax # Po [2] SESAME DOT..WHITE SESAME DOT 0600..0605 ; Prepended_Concatenation_Mark # Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE 06DD ; Prepended_Concatenation_Mark # Cf ARABIC END OF AYAH 070F ; Prepended_Concatenation_Mark # Cf SYRIAC ABBREVIATION MARK +0890..0891 ; Prepended_Concatenation_Mark # Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE 08E2 ; Prepended_Concatenation_Mark # Cf ARABIC DISPUTED END OF AYAH 110BD ; Prepended_Concatenation_Mark # Cf KAITHI NUMBER SIGN 110CD ; Prepended_Concatenation_Mark # Cf KAITHI NUMBER SIGN ABOVE -# Total code points: 11 +# Total code points: 13 # ================================================ diff --git a/make/data/unicodedata/PropertyValueAliases.txt b/make/data/unicodedata/PropertyValueAliases.txt index a72c86715917a4215584ee8b91ca4e4100a23532..0d9356fb8e955c3ed0ae39734348a13ee2b00fba 100644 --- a/make/data/unicodedata/PropertyValueAliases.txt +++ b/make/data/unicodedata/PropertyValueAliases.txt @@ -1,6 +1,6 @@ -# PropertyValueAliases-13.0.0.txt -# Date: 2019-11-13, 21:52:10 GMT -# Copyright (c) 2019 Unicode, Inc. +# PropertyValueAliases-14.0.0.txt +# Date: 2021-05-10, 21:08:53 GMT +# Copyright (c) 2021 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -89,6 +89,7 @@ age; 11.0 ; V11_0 age; 12.0 ; V12_0 age; 12.1 ; V12_1 age; 13.0 ; V13_0 +age; 14.0 ; V14_0 age; NA ; Unassigned # Alphabetic (Alpha) @@ -160,6 +161,7 @@ blk; Ancient_Greek_Numbers ; Ancient_Greek_Numbers blk; Ancient_Symbols ; Ancient_Symbols blk; Arabic ; Arabic blk; Arabic_Ext_A ; Arabic_Extended_A +blk; Arabic_Ext_B ; Arabic_Extended_B blk; Arabic_Math ; Arabic_Mathematical_Alphabetic_Symbols blk; Arabic_PF_A ; Arabic_Presentation_Forms_A ; Arabic_Presentation_Forms-A blk; Arabic_PF_B ; Arabic_Presentation_Forms_B @@ -216,6 +218,7 @@ blk; Cuneiform ; Cuneiform blk; Cuneiform_Numbers ; Cuneiform_Numbers_And_Punctuation blk; Currency_Symbols ; Currency_Symbols blk; Cypriot_Syllabary ; Cypriot_Syllabary +blk; Cypro_Minoan ; Cypro_Minoan blk; Cyrillic ; Cyrillic blk; Cyrillic_Ext_A ; Cyrillic_Extended_A blk; Cyrillic_Ext_B ; Cyrillic_Extended_B @@ -246,6 +249,7 @@ blk; Enclosed_Ideographic_Sup ; Enclosed_Ideographic_Supplement blk; Ethiopic ; Ethiopic blk; Ethiopic_Ext ; Ethiopic_Extended blk; Ethiopic_Ext_A ; Ethiopic_Extended_A +blk; Ethiopic_Ext_B ; Ethiopic_Extended_B blk; Ethiopic_Sup ; Ethiopic_Supplement blk; Geometric_Shapes ; Geometric_Shapes blk; Geometric_Shapes_Ext ; Geometric_Shapes_Extended @@ -285,6 +289,7 @@ blk; Jamo_Ext_B ; Hangul_Jamo_Extended_B blk; Javanese ; Javanese blk; Kaithi ; Kaithi blk; Kana_Ext_A ; Kana_Extended_A +blk; Kana_Ext_B ; Kana_Extended_B blk; Kana_Sup ; Kana_Supplement blk; Kanbun ; Kanbun blk; Kangxi ; Kangxi_Radicals @@ -306,6 +311,8 @@ blk; Latin_Ext_B ; Latin_Extended_B blk; Latin_Ext_C ; Latin_Extended_C blk; Latin_Ext_D ; Latin_Extended_D blk; Latin_Ext_E ; Latin_Extended_E +blk; Latin_Ext_F ; Latin_Extended_F +blk; Latin_Ext_G ; Latin_Extended_G blk; Lepcha ; Lepcha blk; Letterlike_Symbols ; Letterlike_Symbols blk; Limbu ; Limbu @@ -372,6 +379,7 @@ blk; Old_Persian ; Old_Persian blk; Old_Sogdian ; Old_Sogdian blk; Old_South_Arabian ; Old_South_Arabian blk; Old_Turkic ; Old_Turkic +blk; Old_Uyghur ; Old_Uyghur blk; Oriya ; Oriya blk; Ornamental_Dingbats ; Ornamental_Dingbats blk; Osage ; Osage @@ -433,6 +441,7 @@ blk; Tai_Xuan_Jing ; Tai_Xuan_Jing_Symbols blk; Takri ; Takri blk; Tamil ; Tamil blk; Tamil_Sup ; Tamil_Supplement +blk; Tangsa ; Tangsa blk; Tangut ; Tangut blk; Tangut_Components ; Tangut_Components blk; Tangut_Sup ; Tangut_Supplement @@ -442,13 +451,16 @@ blk; Thai ; Thai blk; Tibetan ; Tibetan blk; Tifinagh ; Tifinagh blk; Tirhuta ; Tirhuta +blk; Toto ; Toto blk; Transport_And_Map ; Transport_And_Map_Symbols blk; UCAS ; Unified_Canadian_Aboriginal_Syllabics; Canadian_Syllabics blk; UCAS_Ext ; Unified_Canadian_Aboriginal_Syllabics_Extended +blk; UCAS_Ext_A ; Unified_Canadian_Aboriginal_Syllabics_Extended_A blk; Ugaritic ; Ugaritic blk; Vai ; Vai blk; Vedic_Ext ; Vedic_Extensions blk; Vertical_Forms ; Vertical_Forms +blk; Vithkuqi ; Vithkuqi blk; VS ; Variation_Selectors blk; VS_Sup ; Variation_Selectors_Supplement blk; Wancho ; Wancho @@ -458,6 +470,7 @@ blk; Yi_Radicals ; Yi_Radicals blk; Yi_Syllables ; Yi_Syllables blk; Yijing ; Yijing_Hexagram_Symbols blk; Zanabazar_Square ; Zanabazar_Square +blk; Znamenny_Music ; Znamenny_Musical_Notation # Canonical_Combining_Class (ccc) @@ -1032,6 +1045,8 @@ jg ; Taw ; Taw jg ; Teh_Marbuta ; Teh_Marbuta jg ; Teh_Marbuta_Goal ; Hamza_On_Heh_Goal jg ; Teth ; Teth +jg ; Thin_Yeh ; Thin_Yeh +jg ; Vertical_Tail ; Vertical_Tail jg ; Waw ; Waw jg ; Yeh ; Yeh jg ; Yeh_Barree ; Yeh_Barree @@ -1262,6 +1277,7 @@ sc ; Cham ; Cham sc ; Cher ; Cherokee sc ; Chrs ; Chorasmian sc ; Copt ; Coptic ; Qaac +sc ; Cpmn ; Cypro_Minoan sc ; Cprt ; Cypriot sc ; Cyrl ; Cyrillic sc ; Deva ; Devanagari @@ -1341,6 +1357,7 @@ sc ; Orkh ; Old_Turkic sc ; Orya ; Oriya sc ; Osge ; Osage sc ; Osma ; Osmanya +sc ; Ougr ; Old_Uyghur sc ; Palm ; Palmyrene sc ; Pauc ; Pau_Cin_Hau sc ; Perm ; Old_Permic @@ -1383,8 +1400,11 @@ sc ; Thaa ; Thaana sc ; Thai ; Thai sc ; Tibt ; Tibetan sc ; Tirh ; Tirhuta +sc ; Tnsa ; Tangsa +sc ; Toto ; Toto sc ; Ugar ; Ugaritic sc ; Vaii ; Vai +sc ; Vith ; Vithkuqi sc ; Wara ; Warang_Citi sc ; Wcho ; Wancho sc ; Xpeo ; Old_Persian diff --git a/make/data/unicodedata/ReadMe.txt b/make/data/unicodedata/ReadMe.txt new file mode 100644 index 0000000000000000000000000000000000000000..154781ab2d2c91ba0905cdc3102296da30c3767d --- /dev/null +++ b/make/data/unicodedata/ReadMe.txt @@ -0,0 +1,16 @@ +# Unicode Character Database +# Date: 2021-09-10, 17:22:00 GMT [KW] +# Copyright (c) 2021 Unicode, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see https://www.unicode.org/terms_of_use.html +# +# For documentation, see the following: +# NamesList.html +# UAX #38, "Unicode Han Database (Unihan)" +# UAX #44, "Unicode Character Database" +# UTS #51, "Unicode Emoji" +# +# The UAXes and UTS #51 can be accessed at https://www.unicode.org/versions/Unicode14.0.0/ + +This directory contains the final data files +for the Unicode Character Database, for Version 14.0.0 of the Unicode Standard. diff --git a/make/data/unicodedata/Scripts.txt b/make/data/unicodedata/Scripts.txt index eb3cd86e0c723f9b72cabfa9e92bcca547940931..00a04f5587a659d178aac44b73012f63992250e8 100644 --- a/make/data/unicodedata/Scripts.txt +++ b/make/data/unicodedata/Scripts.txt @@ -1,16 +1,16 @@ -# Scripts-13.0.0.txt -# Date: 2020-01-22, 00:07:43 GMT -# Copyright (c) 2020 Unicode, Inc. +# Scripts-14.0.0.txt +# Date: 2021-07-10, 00:35:31 GMT +# Copyright (c) 2021 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see http://www.unicode.org/reports/tr44/ # For more information, see: -# UAX #24, Unicode Script Property: http://www.unicode.org/reports/tr24/ +# UAX #24, Unicode Script Property: https://www.unicode.org/reports/tr24/ # Especially the sections: -# http://www.unicode.org/reports/tr24/#Assignment_Script_Values -# http://www.unicode.org/reports/tr24/#Assignment_ScriptX_Values +# https://www.unicode.org/reports/tr24/#Assignment_Script_Values +# https://www.unicode.org/reports/tr24/#Assignment_ScriptX_Values # # ================================================ @@ -154,7 +154,7 @@ 208A..208C ; Common # Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN 208D ; Common # Ps SUBSCRIPT LEFT PARENTHESIS 208E ; Common # Pe SUBSCRIPT RIGHT PARENTHESIS -20A0..20BF ; Common # Sc [32] EURO-CURRENCY SIGN..BITCOIN SIGN +20A0..20C0 ; Common # Sc [33] EURO-CURRENCY SIGN..SOM SIGN 2100..2101 ; Common # So [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT 2102 ; Common # L& DOUBLE-STRUCK CAPITAL C 2103..2106 ; Common # So [4] DEGREE CELSIUS..CADA UNA @@ -347,7 +347,16 @@ 2E42 ; Common # Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK 2E43..2E4F ; Common # Po [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER 2E50..2E51 ; Common # So [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR -2E52 ; Common # Po TIRONIAN SIGN CAPITAL ET +2E52..2E54 ; Common # Po [3] TIRONIAN SIGN CAPITAL ET..MEDIEVAL QUESTION MARK +2E55 ; Common # Ps LEFT SQUARE BRACKET WITH STROKE +2E56 ; Common # Pe RIGHT SQUARE BRACKET WITH STROKE +2E57 ; Common # Ps LEFT SQUARE BRACKET WITH DOUBLE STROKE +2E58 ; Common # Pe RIGHT SQUARE BRACKET WITH DOUBLE STROKE +2E59 ; Common # Ps TOP HALF LEFT PARENTHESIS +2E5A ; Common # Pe TOP HALF RIGHT PARENTHESIS +2E5B ; Common # Ps BOTTOM HALF LEFT PARENTHESIS +2E5C ; Common # Pe BOTTOM HALF RIGHT PARENTHESIS +2E5D ; Common # Pd OBLIQUE HYPHEN 2FF0..2FFB ; Common # So [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID 3000 ; Common # Zs IDEOGRAPHIC SPACE 3001..3003 ; Common # Po [3] IDEOGRAPHIC COMMA..DITTO MARK @@ -511,9 +520,8 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR 10190..1019C ; Common # So [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL 101D0..101FC ; Common # So [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND 102E1..102FB ; Common # No [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED -16FE2 ; Common # Po OLD CHINESE HOOK MARK -16FE3 ; Common # Lm OLD CHINESE ITERATION MARK 1BCA0..1BCA3 ; Common # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP +1CF50..1CFC3 ; Common # So [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK 1D000..1D0F5 ; Common # So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO 1D100..1D126 ; Common # So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 1D129..1D164 ; Common # So [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE @@ -523,7 +531,7 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR 1D173..1D17A ; Common # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE 1D183..1D184 ; Common # So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN 1D18C..1D1A9 ; Common # So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH -1D1AE..1D1E8 ; Common # So [59] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KIEVAN FLAT SIGN +1D1AE..1D1EA ; Common # So [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON 1D2E0..1D2F3 ; Common # No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN 1D300..1D356 ; Common # So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING 1D360..1D378 ; Common # No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE @@ -593,35 +601,36 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR 1F300..1F3FA ; Common # So [251] CYCLONE..AMPHORA 1F3FB..1F3FF ; Common # Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 1F400..1F6D7 ; Common # So [728] RAT..ELEVATOR -1F6E0..1F6EC ; Common # So [13] HAMMER AND WRENCH..AIRPLANE ARRIVING +1F6DD..1F6EC ; Common # So [16] PLAYGROUND SLIDE..AIRPLANE ARRIVING 1F6F0..1F6FC ; Common # So [13] SATELLITE..ROLLER SKATE 1F700..1F773 ; Common # So [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE 1F780..1F7D8 ; Common # So [89] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NEGATIVE CIRCLED SQUARE 1F7E0..1F7EB ; Common # So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE +1F7F0 ; Common # So HEAVY EQUALS SIGN 1F800..1F80B ; Common # So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD 1F810..1F847 ; Common # So [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW 1F850..1F859 ; Common # So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW 1F860..1F887 ; Common # So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW 1F890..1F8AD ; Common # So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS 1F8B0..1F8B1 ; Common # So [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST -1F900..1F978 ; Common # So [121] CIRCLED CROSS FORMEE WITH FOUR DOTS..DISGUISED FACE -1F97A..1F9CB ; Common # So [82] FACE WITH PLEADING EYES..BUBBLE TEA -1F9CD..1FA53 ; Common # So [135] STANDING PERSON..BLACK CHESS KNIGHT-BISHOP +1F900..1FA53 ; Common # So [340] CIRCLED CROSS FORMEE WITH FOUR DOTS..BLACK CHESS KNIGHT-BISHOP 1FA60..1FA6D ; Common # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER 1FA70..1FA74 ; Common # So [5] BALLET SHOES..THONG SANDAL -1FA78..1FA7A ; Common # So [3] DROP OF BLOOD..STETHOSCOPE +1FA78..1FA7C ; Common # So [5] DROP OF BLOOD..CRUTCH 1FA80..1FA86 ; Common # So [7] YO-YO..NESTING DOLLS -1FA90..1FAA8 ; Common # So [25] RINGED PLANET..ROCK -1FAB0..1FAB6 ; Common # So [7] FLY..FEATHER -1FAC0..1FAC2 ; Common # So [3] ANATOMICAL HEART..PEOPLE HUGGING -1FAD0..1FAD6 ; Common # So [7] BLUEBERRIES..TEAPOT +1FA90..1FAAC ; Common # So [29] RINGED PLANET..HAMSA +1FAB0..1FABA ; Common # So [11] FLY..NEST WITH EGGS +1FAC0..1FAC5 ; Common # So [6] ANATOMICAL HEART..PERSON WITH CROWN +1FAD0..1FAD9 ; Common # So [10] BLUEBERRIES..JAR +1FAE0..1FAE7 ; Common # So [8] MELTING FACE..BUBBLES +1FAF0..1FAF6 ; Common # So [7] HAND WITH INDEX FINGER AND THUMB CROSSED..HEART HANDS 1FB00..1FB92 ; Common # So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK 1FB94..1FBCA ; Common # So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON 1FBF0..1FBF9 ; Common # Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE E0001 ; Common # Cf LANGUAGE TAG E0020..E007F ; Common # Cf [96] TAG SPACE..CANCEL TAG -# Total code points: 8087 +# Total code points: 8252 # ================================================ @@ -664,8 +673,11 @@ A770 ; Latin # Lm MODIFIER LETTER US A771..A787 ; Latin # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T A78B..A78E ; Latin # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; Latin # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7BF ; Latin # L& [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U -A7C2..A7CA ; Latin # L& [9] LATIN CAPITAL LETTER ANGLICANA W..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CA ; Latin # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7D0..A7D1 ; Latin # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G +A7D3 ; Latin # L& LATIN SMALL LETTER DOUBLE THORN +A7D5..A7D9 ; Latin # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7F2..A7F4 ; Latin # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; Latin # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; Latin # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I A7F8..A7F9 ; Latin # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE @@ -679,8 +691,14 @@ AB69 ; Latin # Lm MODIFIER LETTER SMALL TURNED W FB00..FB06 ; Latin # L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST FF21..FF3A ; Latin # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z FF41..FF5A ; Latin # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z +10780..10785 ; Latin # Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK +10787..107B0 ; Latin # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK +107B2..107BA ; Latin # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL +1DF00..1DF09 ; Latin # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK +1DF0A ; Latin # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK +1DF0B..1DF1E ; Latin # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL -# Total code points: 1374 +# Total code points: 1475 # ================================================ @@ -820,7 +838,7 @@ FB46..FB4F ; Hebrew # Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATU 060E..060F ; Arabic # So [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA 0610..061A ; Arabic # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA 061C ; Arabic # Cf ARABIC LETTER MARK -061E ; Arabic # Po ARABIC TRIPLE DOT PUNCTUATION MARK +061D..061E ; Arabic # Po [2] ARABIC END OF TEXT MARK..ARABIC TRIPLE DOT PUNCTUATION MARK 0620..063F ; Arabic # Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE 0641..064A ; Arabic # Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH 0656..065F ; Arabic # Mn [10] ARABIC SUBSCRIPT ALEF..ARABIC WAVY HAMZA BELOW @@ -843,18 +861,25 @@ FB46..FB4F ; Hebrew # Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATU 06FD..06FE ; Arabic # So [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN 06FF ; Arabic # Lo ARABIC LETTER HEH WITH INVERTED V 0750..077F ; Arabic # Lo [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE -08A0..08B4 ; Arabic # Lo [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW -08B6..08C7 ; Arabic # Lo [18] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE -08D3..08E1 ; Arabic # Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA +0870..0887 ; Arabic # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT +0888 ; Arabic # Sk ARABIC RAISED ROUND DOT +0889..088E ; Arabic # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL +0890..0891 ; Arabic # Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE +0898..089F ; Arabic # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +08A0..08C8 ; Arabic # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF +08C9 ; Arabic # Lm ARABIC SMALL FARSI YEH +08CA..08E1 ; Arabic # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA 08E3..08FF ; Arabic # Mn [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA FB50..FBB1 ; Arabic # Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM -FBB2..FBC1 ; Arabic # Sk [16] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL SMALL TAH BELOW +FBB2..FBC2 ; Arabic # Sk [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE FBD3..FD3D ; Arabic # Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM +FD40..FD4F ; Arabic # So [16] ARABIC LIGATURE RAHIMAHU ALLAAH..ARABIC LIGATURE RAHIMAHUM ALLAAH FD50..FD8F ; Arabic # Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM FD92..FDC7 ; Arabic # Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM +FDCF ; Arabic # So ARABIC LIGATURE SALAAMUHU ALAYNAA FDF0..FDFB ; Arabic # Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU FDFC ; Arabic # Sc RIAL SIGN -FDFD ; Arabic # So ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM +FDFD..FDFF ; Arabic # So [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM..ARABIC LIGATURE AZZA WA JALL FE70..FE74 ; Arabic # Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM FE76..FEFC ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM 10E60..10E7E ; Arabic # No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS @@ -893,7 +918,7 @@ FE76..FEFC ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LA 1EEAB..1EEBB ; Arabic # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN 1EEF0..1EEF1 ; Arabic # Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL -# Total code points: 1291 +# Total code points: 1365 # ================================================ @@ -1113,6 +1138,7 @@ A8FF ; Devanagari # Mn DEVANAGARI VOWEL SIGN AY 0C0E..0C10 ; Telugu # Lo [3] TELUGU LETTER E..TELUGU LETTER AI 0C12..0C28 ; Telugu # Lo [23] TELUGU LETTER O..TELUGU LETTER NA 0C2A..0C39 ; Telugu # Lo [16] TELUGU LETTER PA..TELUGU LETTER HA +0C3C ; Telugu # Mn TELUGU SIGN NUKTA 0C3D ; Telugu # Lo TELUGU SIGN AVAGRAHA 0C3E..0C40 ; Telugu # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II 0C41..0C44 ; Telugu # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR @@ -1120,6 +1146,7 @@ A8FF ; Devanagari # Mn DEVANAGARI VOWEL SIGN AY 0C4A..0C4D ; Telugu # Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA 0C55..0C56 ; Telugu # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK 0C58..0C5A ; Telugu # Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA +0C5D ; Telugu # Lo TELUGU LETTER NAKAARA POLLU 0C60..0C61 ; Telugu # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL 0C62..0C63 ; Telugu # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL 0C66..0C6F ; Telugu # Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE @@ -1127,7 +1154,7 @@ A8FF ; Devanagari # Mn DEVANAGARI VOWEL SIGN AY 0C78..0C7E ; Telugu # No [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR 0C7F ; Telugu # So TELUGU SIGN TUUMU -# Total code points: 98 +# Total code points: 100 # ================================================ @@ -1150,13 +1177,13 @@ A8FF ; Devanagari # Mn DEVANAGARI VOWEL SIGN AY 0CCA..0CCB ; Kannada # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CCC..0CCD ; Kannada # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA 0CD5..0CD6 ; Kannada # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK -0CDE ; Kannada # Lo KANNADA LETTER FA +0CDD..0CDE ; Kannada # Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA 0CE0..0CE1 ; Kannada # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL 0CE2..0CE3 ; Kannada # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL 0CE6..0CEF ; Kannada # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE 0CF1..0CF2 ; Kannada # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA -# Total code points: 89 +# Total code points: 90 # ================================================ @@ -1411,8 +1438,12 @@ AB09..AB0E ; Ethiopic # Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DD AB11..AB16 ; Ethiopic # Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO AB20..AB26 ; Ethiopic # Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO AB28..AB2E ; Ethiopic # Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO +1E7E0..1E7E6 ; Ethiopic # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO +1E7E8..1E7EB ; Ethiopic # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE +1E7ED..1E7EE ; Ethiopic # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE +1E7F0..1E7FE ; Ethiopic # Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE -# Total code points: 495 +# Total code points: 523 # ================================================ @@ -1430,8 +1461,9 @@ AB70..ABBF ; Cherokee # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETT 166E ; Canadian_Aboriginal # Po CANADIAN SYLLABICS FULL STOP 166F..167F ; Canadian_Aboriginal # Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W 18B0..18F5 ; Canadian_Aboriginal # Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S +11AB0..11ABF ; Canadian_Aboriginal # Lo [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA -# Total code points: 710 +# Total code points: 726 # ================================================ @@ -1480,6 +1512,7 @@ AB70..ABBF ; Cherokee # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETT 1807..180A ; Mongolian # Po [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU 180B..180D ; Mongolian # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE 180E ; Mongolian # Cf MONGOLIAN VOWEL SEPARATOR +180F ; Mongolian # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR 1810..1819 ; Mongolian # Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE 1820..1842 ; Mongolian # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI 1843 ; Mongolian # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN @@ -1491,18 +1524,18 @@ AB70..ABBF ; Cherokee # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETT 18AA ; Mongolian # Lo MONGOLIAN LETTER MANCHU ALI GALI LHA 11660..1166C ; Mongolian # Po [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT -# Total code points: 167 +# Total code points: 168 # ================================================ 3041..3096 ; Hiragana # Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE 309D..309E ; Hiragana # Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK 309F ; Hiragana # Lo HIRAGANA DIGRAPH YORI -1B001..1B11E ; Hiragana # Lo [286] HIRAGANA LETTER ARCHAIC YE..HENTAIGANA LETTER N-MU-MO-2 +1B001..1B11F ; Hiragana # Lo [287] HIRAGANA LETTER ARCHAIC YE..HIRAGANA LETTER ARCHAIC WU 1B150..1B152 ; Hiragana # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO 1F200 ; Hiragana # So SQUARE HIRAGANA HOKA -# Total code points: 379 +# Total code points: 380 # ================================================ @@ -1514,10 +1547,14 @@ AB70..ABBF ; Cherokee # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETT 3300..3357 ; Katakana # So [88] SQUARE APAATO..SQUARE WATTO FF66..FF6F ; Katakana # Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU FF71..FF9D ; Katakana # Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N +1AFF0..1AFF3 ; Katakana # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 +1AFF5..1AFFB ; Katakana # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 +1AFFD..1AFFE ; Katakana # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 1B000 ; Katakana # Lo KATAKANA LETTER ARCHAIC E +1B120..1B122 ; Katakana # Lo [3] KATAKANA LETTER ARCHAIC YI..KATAKANA LETTER ARCHAIC WU 1B164..1B167 ; Katakana # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N -# Total code points: 304 +# Total code points: 320 # ================================================ @@ -1538,19 +1575,21 @@ FF71..FF9D ; Katakana # Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAK 3038..303A ; Han # Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY 303B ; Han # Lm VERTICAL IDEOGRAPHIC ITERATION MARK 3400..4DBF ; Han # Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF -4E00..9FFC ; Han # Lo [20989] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFC +4E00..9FFF ; Han # Lo [20992] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFF F900..FA6D ; Han # Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D FA70..FAD9 ; Han # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +16FE2 ; Han # Po OLD CHINESE HOOK MARK +16FE3 ; Han # Lm OLD CHINESE ITERATION MARK 16FF0..16FF1 ; Han # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY -20000..2A6DD ; Han # Lo [42718] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DD -2A700..2B734 ; Han # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +20000..2A6DF ; Han # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF +2A700..2B738 ; Han # Lo [4153] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B738 2B740..2B81D ; Han # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D 2B820..2CEA1 ; Han # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 2CEB0..2EBE0 ; Han # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 2F800..2FA1D ; Han # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D 30000..3134A ; Han # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A -# Total code points: 94204 +# Total code points: 94215 # ================================================ @@ -1593,15 +1632,14 @@ A490..A4C6 ; Yi # So [55] YI RADICAL QOT..YI RADICAL KE 0951..0954 ; Inherited # Mn [4] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI ACUTE ACCENT 1AB0..1ABD ; Inherited # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW 1ABE ; Inherited # Me COMBINING PARENTHESES OVERLAY -1ABF..1AC0 ; Inherited # Mn [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW +1ABF..1ACE ; Inherited # Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T 1CD0..1CD2 ; Inherited # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA 1CD4..1CE0 ; Inherited # Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA 1CE2..1CE8 ; Inherited # Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL 1CED ; Inherited # Mn VEDIC SIGN TIRYAK 1CF4 ; Inherited # Mn VEDIC TONE CANDRA ABOVE 1CF8..1CF9 ; Inherited # Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE -1DC0..1DF9 ; Inherited # Mn [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW -1DFB..1DFF ; Inherited # Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW +1DC0..1DFF ; Inherited # Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW 200C..200D ; Inherited # Cf [2] ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER 20D0..20DC ; Inherited # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE 20DD..20E0 ; Inherited # Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH @@ -1615,26 +1653,30 @@ FE20..FE2D ; Inherited # Mn [14] COMBINING LIGATURE LEFT HALF..COMBINING CON 101FD ; Inherited # Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE 102E0 ; Inherited # Mn COPTIC EPACT THOUSANDS MARK 1133B ; Inherited # Mn COMBINING BINDU BELOW +1CF00..1CF2D ; Inherited # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT +1CF30..1CF46 ; Inherited # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG 1D167..1D169 ; Inherited # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 1D17B..1D182 ; Inherited # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE 1D185..1D18B ; Inherited # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE 1D1AA..1D1AD ; Inherited # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO E0100..E01EF ; Inherited # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 573 +# Total code points: 657 # ================================================ -1700..170C ; Tagalog # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA -170E..1711 ; Tagalog # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA +1700..1711 ; Tagalog # Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA 1712..1714 ; Tagalog # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA +1715 ; Tagalog # Mc TAGALOG SIGN PAMUDPOD +171F ; Tagalog # Lo TAGALOG LETTER ARCHAIC RA -# Total code points: 20 +# Total code points: 23 # ================================================ 1720..1731 ; Hanunoo # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA -1732..1734 ; Hanunoo # Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD +1732..1733 ; Hanunoo # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U +1734 ; Hanunoo # Mc HANUNOO SIGN PAMUDPOD # Total code points: 21 @@ -1762,15 +1804,14 @@ E0100..E01EF ; Inherited # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-2 # ================================================ -2C00..2C2E ; Glagolitic # L& [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C30..2C5E ; Glagolitic # L& [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C00..2C5F ; Glagolitic # L& [96] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI 1E000..1E006 ; Glagolitic # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE 1E008..1E018 ; Glagolitic # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU 1E01B..1E021 ; Glagolitic # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI 1E023..1E024 ; Glagolitic # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS 1E026..1E02A ; Glagolitic # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA -# Total code points: 132 +# Total code points: 134 # ================================================ @@ -1836,14 +1877,15 @@ A82C ; Syloti_Nagri # Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA 1B3D..1B41 ; Balinese # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG 1B42 ; Balinese # Mn BALINESE VOWEL SIGN PEPET 1B43..1B44 ; Balinese # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG -1B45..1B4B ; Balinese # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B45..1B4C ; Balinese # Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA 1B50..1B59 ; Balinese # Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE 1B5A..1B60 ; Balinese # Po [7] BALINESE PANTI..BALINESE PAMENENG 1B61..1B6A ; Balinese # So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE 1B6B..1B73 ; Balinese # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG 1B74..1B7C ; Balinese # So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING +1B7D..1B7E ; Balinese # Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG -# Total code points: 121 +# Total code points: 124 # ================================================ @@ -2178,9 +2220,10 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI 110BB..110BC ; Kaithi # Po [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN 110BD ; Kaithi # Cf KAITHI NUMBER SIGN 110BE..110C1 ; Kaithi # Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA +110C2 ; Kaithi # Mn KAITHI VOWEL SIGN VOCALIC R 110CD ; Kaithi # Cf KAITHI NUMBER SIGN ABOVE -# Total code points: 67 +# Total code points: 68 # ================================================ @@ -2207,9 +2250,13 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI 11047..1104D ; Brahmi # Po [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS 11052..11065 ; Brahmi # No [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND 11066..1106F ; Brahmi # Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE +11070 ; Brahmi # Mn BRAHMI SIGN OLD TAMIL VIRAMA +11071..11072 ; Brahmi # Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O +11073..11074 ; Brahmi # Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O +11075 ; Brahmi # Lo BRAHMI LETTER OLD TAMIL LLA 1107F ; Brahmi # Mn BRAHMI NUMBER JOINER -# Total code points: 109 +# Total code points: 115 # ================================================ @@ -2301,9 +2348,10 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI 116B6 ; Takri # Mc TAKRI SIGN VIRAMA 116B7 ; Takri # Mn TAKRI SIGN NUKTA 116B8 ; Takri # Lo TAKRI LETTER ARCHAIC KHA +116B9 ; Takri # Po TAKRI ABBREVIATION SIGN 116C0..116C9 ; Takri # Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE -# Total code points: 67 +# Total code points: 68 # ================================================ @@ -2561,8 +2609,9 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI 1173A..1173B ; Ahom # No [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY 1173C..1173E ; Ahom # Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI 1173F ; Ahom # So AHOM SYMBOL VI +11740..11746 ; Ahom # Lo [7] AHOM LETTER CA..AHOM LETTER LLA -# Total code points: 58 +# Total code points: 65 # ================================================ @@ -2897,4 +2946,46 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI # Total code points: 47 +# ================================================ + +12F90..12FF0 ; Cypro_Minoan # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 +12FF1..12FF2 ; Cypro_Minoan # Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302 + +# Total code points: 99 + +# ================================================ + +10F70..10F81 ; Old_Uyghur # Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH +10F82..10F85 ; Old_Uyghur # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW +10F86..10F89 ; Old_Uyghur # Po [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS + +# Total code points: 26 + +# ================================================ + +16A70..16ABE ; Tangsa # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA +16AC0..16AC9 ; Tangsa # Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + +# Total code points: 89 + +# ================================================ + +1E290..1E2AD ; Toto # Lo [30] TOTO LETTER PA..TOTO LETTER A +1E2AE ; Toto # Mn TOTO SIGN RISING TONE + +# Total code points: 31 + +# ================================================ + +10570..1057A ; Vithkuqi # L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA +1057C..1058A ; Vithkuqi # L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE +1058C..10592 ; Vithkuqi # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE +10594..10595 ; Vithkuqi # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE +10597..105A1 ; Vithkuqi # L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA +105A3..105B1 ; Vithkuqi # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE +105B3..105B9 ; Vithkuqi # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE +105BB..105BC ; Vithkuqi # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + +# Total code points: 70 + # EOF diff --git a/make/data/unicodedata/SpecialCasing.txt b/make/data/unicodedata/SpecialCasing.txt index ae71d58f644d7d814ac49fc73459b1e783039818..5c2a8aae46dd821120de5323797de270f1631c55 100644 --- a/make/data/unicodedata/SpecialCasing.txt +++ b/make/data/unicodedata/SpecialCasing.txt @@ -1,6 +1,6 @@ -# SpecialCasing-13.0.0.txt -# Date: 2019-09-08, 23:31:24 GMT -# Copyright (c) 2019 Unicode, Inc. +# SpecialCasing-14.0.0.txt +# Date: 2021-03-08, 19:35:55 GMT +# Copyright (c) 2021 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # diff --git a/make/data/unicodedata/UnicodeData.txt b/make/data/unicodedata/UnicodeData.txt index e22f967bbab8f2477a43533a334e21ebc0728eda..b5abef7ed437eefea5781e462e00d74ac5c02aba 100644 --- a/make/data/unicodedata/UnicodeData.txt +++ b/make/data/unicodedata/UnicodeData.txt @@ -1525,6 +1525,7 @@ 061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;; 061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;; 061C;ARABIC LETTER MARK;Cf;0;AL;;;;;N;;;;; +061D;ARABIC END OF TEXT MARK;Po;0;AL;;;;;N;;;;; 061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;; 061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;; 0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;; @@ -2089,6 +2090,47 @@ 0868;SYRIAC LETTER MALAYALAM LLA;Lo;0;AL;;;;;N;;;;; 0869;SYRIAC LETTER MALAYALAM LLLA;Lo;0;AL;;;;;N;;;;; 086A;SYRIAC LETTER MALAYALAM SSA;Lo;0;AL;;;;;N;;;;; +0870;ARABIC LETTER ALEF WITH ATTACHED FATHA;Lo;0;AL;;;;;N;;;;; +0871;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA;Lo;0;AL;;;;;N;;;;; +0872;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE;Lo;0;AL;;;;;N;;;;; +0873;ARABIC LETTER ALEF WITH LEFT MIDDLE STROKE;Lo;0;AL;;;;;N;;;;; +0874;ARABIC LETTER ALEF WITH ATTACHED KASRA;Lo;0;AL;;;;;N;;;;; +0875;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA;Lo;0;AL;;;;;N;;;;; +0876;ARABIC LETTER ALEF WITH ATTACHED ROUND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0877;ARABIC LETTER ALEF WITH ATTACHED RIGHT ROUND DOT;Lo;0;AL;;;;;N;;;;; +0878;ARABIC LETTER ALEF WITH ATTACHED LEFT ROUND DOT;Lo;0;AL;;;;;N;;;;; +0879;ARABIC LETTER ALEF WITH ATTACHED ROUND DOT BELOW;Lo;0;AL;;;;;N;;;;; +087A;ARABIC LETTER ALEF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +087B;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +087C;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +087D;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +087E;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA AND LEFT RING;Lo;0;AL;;;;;N;;;;; +087F;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE AND LEFT RING;Lo;0;AL;;;;;N;;;;; +0880;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA AND LEFT RING;Lo;0;AL;;;;;N;;;;; +0881;ARABIC LETTER ALEF WITH ATTACHED RIGHT HAMZA;Lo;0;AL;;;;;N;;;;; +0882;ARABIC LETTER ALEF WITH ATTACHED LEFT HAMZA;Lo;0;AL;;;;;N;;;;; +0883;ARABIC TATWEEL WITH OVERSTRUCK HAMZA;Lo;0;AL;;;;;N;;;;; +0884;ARABIC TATWEEL WITH OVERSTRUCK WAW;Lo;0;AL;;;;;N;;;;; +0885;ARABIC TATWEEL WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +0886;ARABIC LETTER THIN YEH;Lo;0;AL;;;;;N;;;;; +0887;ARABIC BASELINE ROUND DOT;Lo;0;AL;;;;;N;;;;; +0888;ARABIC RAISED ROUND DOT;Sk;0;AL;;;;;N;;;;; +0889;ARABIC LETTER NOON WITH INVERTED SMALL V;Lo;0;AL;;;;;N;;;;; +088A;ARABIC LETTER HAH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;; +088B;ARABIC LETTER TAH WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +088C;ARABIC LETTER TAH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +088D;ARABIC LETTER KEHEH WITH TWO DOTS VERTICALLY BELOW;Lo;0;AL;;;;;N;;;;; +088E;ARABIC VERTICAL TAIL;Lo;0;AL;;;;;N;;;;; +0890;ARABIC POUND MARK ABOVE;Cf;0;AN;;;;;N;;;;; +0891;ARABIC PIASTRE MARK ABOVE;Cf;0;AN;;;;;N;;;;; +0898;ARABIC SMALL HIGH WORD AL-JUZ;Mn;230;NSM;;;;;N;;;;; +0899;ARABIC SMALL LOW WORD ISHMAAM;Mn;220;NSM;;;;;N;;;;; +089A;ARABIC SMALL LOW WORD IMAALA;Mn;220;NSM;;;;;N;;;;; +089B;ARABIC SMALL LOW WORD TASHEEL;Mn;220;NSM;;;;;N;;;;; +089C;ARABIC MADDA WAAJIB;Mn;230;NSM;;;;;N;;;;; +089D;ARABIC SUPERSCRIPT ALEF MOKHASSAS;Mn;230;NSM;;;;;N;;;;; +089E;ARABIC DOUBLED MADDA;Mn;230;NSM;;;;;N;;;;; +089F;ARABIC HALF MADDA OVER MADDA;Mn;230;NSM;;;;;N;;;;; 08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;; 08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;; 08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; @@ -2110,6 +2152,7 @@ 08B2;ARABIC LETTER ZAIN WITH INVERTED V ABOVE;Lo;0;AL;;;;;N;;;;; 08B3;ARABIC LETTER AIN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; 08B4;ARABIC LETTER KAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +08B5;ARABIC LETTER QAF WITH DOT BELOW AND NO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 08B6;ARABIC LETTER BEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;; 08B7;ARABIC LETTER PEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;; 08B8;ARABIC LETTER TEH WITH SMALL TEH ABOVE;Lo;0;AL;;;;;N;;;;; @@ -2128,6 +2171,17 @@ 08C5;ARABIC LETTER JEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 08C6;ARABIC LETTER JEEM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; 08C7;ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;; +08C8;ARABIC LETTER GRAF;Lo;0;AL;;;;;N;;;;; +08C9;ARABIC SMALL FARSI YEH;Lm;0;AL;;;;;N;;;;; +08CA;ARABIC SMALL HIGH FARSI YEH;Mn;230;NSM;;;;;N;;;;; +08CB;ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW;Mn;230;NSM;;;;;N;;;;; +08CC;ARABIC SMALL HIGH WORD SAH;Mn;230;NSM;;;;;N;;;;; +08CD;ARABIC SMALL HIGH ZAH;Mn;230;NSM;;;;;N;;;;; +08CE;ARABIC LARGE ROUND DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +08CF;ARABIC LARGE ROUND DOT BELOW;Mn;220;NSM;;;;;N;;;;; +08D0;ARABIC SUKUN BELOW;Mn;220;NSM;;;;;N;;;;; +08D1;ARABIC LARGE CIRCLE BELOW;Mn;220;NSM;;;;;N;;;;; +08D2;ARABIC LARGE ROUND DOT INSIDE CIRCLE BELOW;Mn;220;NSM;;;;;N;;;;; 08D3;ARABIC SMALL LOW WAW;Mn;220;NSM;;;;;N;;;;; 08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;; 08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;; @@ -2786,6 +2840,7 @@ 0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;; 0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;; 0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;; +0C3C;TELUGU SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; 0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; 0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; @@ -2806,6 +2861,7 @@ 0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;; 0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;; 0C5A;TELUGU LETTER RRRA;Lo;0;L;;;;;N;;;;; +0C5D;TELUGU LETTER NAKAARA POLLU;Lo;0;L;;;;;N;;;;; 0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; 0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; @@ -2901,6 +2957,7 @@ 0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;; 0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CDD;KANNADA LETTER NAKAARA POLLU;Lo;0;L;;;;;N;;;;; 0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;; 0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; @@ -5258,6 +5315,7 @@ 170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;; 170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;; 170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;; +170D;TAGALOG LETTER RA;Lo;0;L;;;;;N;;;;; 170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;; 170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;; 1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;; @@ -5265,6 +5323,8 @@ 1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1715;TAGALOG SIGN PAMUDPOD;Mc;9;L;;;;;N;;;;; +171F;TAGALOG LETTER ARCHAIC RA;Lo;0;L;;;;;N;;;;; 1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;; 1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;; 1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;; @@ -5285,7 +5345,7 @@ 1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;; 1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; -1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;; +1734;HANUNOO SIGN PAMUDPOD;Mc;9;L;;;;;N;;;;; 1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; 1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;; 1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;; @@ -5455,6 +5515,7 @@ 180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;; 180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;; 180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;; +180F;MONGOLIAN FREE VARIATION SELECTOR FOUR;Mn;0;NSM;;;;;N;;;;; 1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -6059,6 +6120,20 @@ 1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;; 1ABF;COMBINING LATIN SMALL LETTER W BELOW;Mn;220;NSM;;;;;N;;;;; 1AC0;COMBINING LATIN SMALL LETTER TURNED W BELOW;Mn;220;NSM;;;;;N;;;;; +1AC1;COMBINING LEFT PARENTHESIS ABOVE LEFT;Mn;230;NSM;;;;;N;;;;; +1AC2;COMBINING RIGHT PARENTHESIS ABOVE RIGHT;Mn;230;NSM;;;;;N;;;;; +1AC3;COMBINING LEFT PARENTHESIS BELOW LEFT;Mn;220;NSM;;;;;N;;;;; +1AC4;COMBINING RIGHT PARENTHESIS BELOW RIGHT;Mn;220;NSM;;;;;N;;;;; +1AC5;COMBINING SQUARE BRACKETS ABOVE;Mn;230;NSM;;;;;N;;;;; +1AC6;COMBINING NUMBER SIGN ABOVE;Mn;230;NSM;;;;;N;;;;; +1AC7;COMBINING INVERTED DOUBLE ARCH ABOVE;Mn;230;NSM;;;;;N;;;;; +1AC8;COMBINING PLUS SIGN ABOVE;Mn;230;NSM;;;;;N;;;;; +1AC9;COMBINING DOUBLE PLUS SIGN ABOVE;Mn;230;NSM;;;;;N;;;;; +1ACA;COMBINING DOUBLE PLUS SIGN BELOW;Mn;220;NSM;;;;;N;;;;; +1ACB;COMBINING TRIPLE ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +1ACC;COMBINING LATIN SMALL LETTER INSULAR G;Mn;230;NSM;;;;;N;;;;; +1ACD;COMBINING LATIN SMALL LETTER INSULAR R;Mn;230;NSM;;;;;N;;;;; +1ACE;COMBINING LATIN SMALL LETTER INSULAR T;Mn;230;NSM;;;;;N;;;;; 1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;; 1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;; 1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;; @@ -6135,6 +6210,7 @@ 1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;; 1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;; 1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;; +1B4C;BALINESE LETTER ARCHAIC JNYA;Lo;0;L;;;;;N;;;;; 1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -6180,6 +6256,8 @@ 1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;; 1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;; 1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;; +1B7D;BALINESE PANTI LANTANG;Po;0;L;;;;;N;;;;; +1B7E;BALINESE PAMADA LANTANG;Po;0;L;;;;;N;;;;; 1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;; 1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;; 1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;; @@ -6778,6 +6856,7 @@ 1DF7;COMBINING KAVYKA ABOVE LEFT;Mn;228;NSM;;;;;N;;;;; 1DF8;COMBINING DOT ABOVE LEFT;Mn;228;NSM;;;;;N;;;;; 1DF9;COMBINING WIDE INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;;;;; +1DFA;COMBINING DOT BELOW LEFT;Mn;218;NSM;;;;;N;;;;; 1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;; 1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;; 1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;; @@ -7457,6 +7536,7 @@ 20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;; 20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;; 20BF;BITCOIN SIGN;Sc;0;ET;;;;;N;;;;; +20C0;SOM SIGN;Sc;0;ET;;;;;N;;;;; 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; @@ -10300,6 +10380,7 @@ 2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C; 2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D; 2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E; +2C2F;GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI;Lu;0;L;;;;;N;;;;2C5F; 2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00 2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01 2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02 @@ -10347,6 +10428,7 @@ 2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C 2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D 2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E +2C5F;GLAGOLITIC SMALL LETTER CAUDATE CHRIVI;Ll;0;L;;;;;N;;;2C2F;;2C2F 2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61; 2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60 2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B; @@ -10795,6 +10877,17 @@ 2E50;CROSS PATTY WITH RIGHT CROSSBAR;So;0;ON;;;;;N;;;;; 2E51;CROSS PATTY WITH LEFT CROSSBAR;So;0;ON;;;;;N;;;;; 2E52;TIRONIAN SIGN CAPITAL ET;Po;0;ON;;;;;N;;;;; +2E53;MEDIEVAL EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +2E54;MEDIEVAL QUESTION MARK;Po;0;ON;;;;;N;;;;; +2E55;LEFT SQUARE BRACKET WITH STROKE;Ps;0;ON;;;;;Y;;;;; +2E56;RIGHT SQUARE BRACKET WITH STROKE;Pe;0;ON;;;;;Y;;;;; +2E57;LEFT SQUARE BRACKET WITH DOUBLE STROKE;Ps;0;ON;;;;;Y;;;;; +2E58;RIGHT SQUARE BRACKET WITH DOUBLE STROKE;Pe;0;ON;;;;;Y;;;;; +2E59;TOP HALF LEFT PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2E5A;TOP HALF RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2E5B;BOTTOM HALF LEFT PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2E5C;BOTTOM HALF RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2E5D;OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;; 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; @@ -12204,7 +12297,7 @@ 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;; 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;; 4E00;;Lo;0;L;;;;;N;;;;; -9FFC;;Lo;0;L;;;;;N;;;;; +9FFF;;Lo;0;L;;;;;N;;;;; A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; @@ -14149,6 +14242,8 @@ A7BC;LATIN CAPITAL LETTER GLOTTAL I;Lu;0;L;;;;;N;;;;A7BD; A7BD;LATIN SMALL LETTER GLOTTAL I;Ll;0;L;;;;;N;;;A7BC;;A7BC A7BE;LATIN CAPITAL LETTER GLOTTAL U;Lu;0;L;;;;;N;;;;A7BF; A7BF;LATIN SMALL LETTER GLOTTAL U;Ll;0;L;;;;;N;;;A7BE;;A7BE +A7C0;LATIN CAPITAL LETTER OLD POLISH O;Lu;0;L;;;;;N;;;;A7C1; +A7C1;LATIN SMALL LETTER OLD POLISH O;Ll;0;L;;;;;N;;;A7C0;;A7C0 A7C2;LATIN CAPITAL LETTER ANGLICANA W;Lu;0;L;;;;;N;;;;A7C3; A7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2 A7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794; @@ -14158,6 +14253,17 @@ A7C7;LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7C8; A7C8;LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C7;;A7C7 A7C9;LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7CA; A7CA;LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C9;;A7C9 +A7D0;LATIN CAPITAL LETTER CLOSED INSULAR G;Lu;0;L;;;;;N;;;;A7D1; +A7D1;LATIN SMALL LETTER CLOSED INSULAR G;Ll;0;L;;;;;N;;;A7D0;;A7D0 +A7D3;LATIN SMALL LETTER DOUBLE THORN;Ll;0;L;;;;;N;;;;; +A7D5;LATIN SMALL LETTER DOUBLE WYNN;Ll;0;L;;;;;N;;;;; +A7D6;LATIN CAPITAL LETTER MIDDLE SCOTS S;Lu;0;L;;;;;N;;;;A7D7; +A7D7;LATIN SMALL LETTER MIDDLE SCOTS S;Ll;0;L;;;;;N;;;A7D6;;A7D6 +A7D8;LATIN CAPITAL LETTER SIGMOID S;Lu;0;L;;;;;N;;;;A7D9; +A7D9;LATIN SMALL LETTER SIGMOID S;Ll;0;L;;;;;N;;;A7D8;;A7D8 +A7F2;MODIFIER LETTER CAPITAL C;Lm;0;L; 0043;;;;N;;;;; +A7F3;MODIFIER LETTER CAPITAL F;Lm;0;L; 0046;;;;N;;;;; +A7F4;MODIFIER LETTER CAPITAL Q;Lm;0;L; 0051;;;;N;;;;; A7F5;LATIN CAPITAL LETTER REVERSED HALF H;Lu;0;L;;;;;N;;;;A7F6; A7F6;LATIN SMALL LETTER REVERSED HALF H;Ll;0;L;;;;;N;;;A7F5;;A7F5 A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;; @@ -15794,6 +15900,7 @@ FBBE;ARABIC SYMBOL TWO DOTS VERTICALLY BELOW;Sk;0;AL;;;;;N;;;;; FBBF;ARABIC SYMBOL RING;Sk;0;AL;;;;;N;;;;; FBC0;ARABIC SYMBOL SMALL TAH ABOVE;Sk;0;AL;;;;;N;;;;; FBC1;ARABIC SYMBOL SMALL TAH BELOW;Sk;0;AL;;;;;N;;;;; +FBC2;ARABIC SYMBOL WASLA ABOVE;Sk;0;AL;;;;;N;;;;; FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL; 06AD;;;;N;;;;; FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL; 06AD;;;;N;;;;; FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; @@ -16159,6 +16266,22 @@ FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL; 0627 064B;;;; FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL; 0627 064B;;;;N;;;;; FD3E;ORNATE LEFT PARENTHESIS;Pe;0;ON;;;;;N;;;;; FD3F;ORNATE RIGHT PARENTHESIS;Ps;0;ON;;;;;N;;;;; +FD40;ARABIC LIGATURE RAHIMAHU ALLAAH;So;0;ON;;;;;N;;;;; +FD41;ARABIC LIGATURE RADI ALLAAHU ANH;So;0;ON;;;;;N;;;;; +FD42;ARABIC LIGATURE RADI ALLAAHU ANHAA;So;0;ON;;;;;N;;;;; +FD43;ARABIC LIGATURE RADI ALLAAHU ANHUM;So;0;ON;;;;;N;;;;; +FD44;ARABIC LIGATURE RADI ALLAAHU ANHUMAA;So;0;ON;;;;;N;;;;; +FD45;ARABIC LIGATURE RADI ALLAAHU ANHUNNA;So;0;ON;;;;;N;;;;; +FD46;ARABIC LIGATURE SALLALLAAHU ALAYHI WA-AALIH;So;0;ON;;;;;N;;;;; +FD47;ARABIC LIGATURE ALAYHI AS-SALAAM;So;0;ON;;;;;N;;;;; +FD48;ARABIC LIGATURE ALAYHIM AS-SALAAM;So;0;ON;;;;;N;;;;; +FD49;ARABIC LIGATURE ALAYHIMAA AS-SALAAM;So;0;ON;;;;;N;;;;; +FD4A;ARABIC LIGATURE ALAYHI AS-SALAATU WAS-SALAAM;So;0;ON;;;;;N;;;;; +FD4B;ARABIC LIGATURE QUDDISA SIRRAH;So;0;ON;;;;;N;;;;; +FD4C;ARABIC LIGATURE SALLALLAHU ALAYHI WAAALIHEE WA-SALLAM;So;0;ON;;;;;N;;;;; +FD4D;ARABIC LIGATURE ALAYHAA AS-SALAAM;So;0;ON;;;;;N;;;;; +FD4E;ARABIC LIGATURE TABAARAKA WA-TAAALAA;So;0;ON;;;;;N;;;;; +FD4F;ARABIC LIGATURE RAHIMAHUM ALLAAH;So;0;ON;;;;;N;;;;; FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062C 0645;;;;N;;;;; FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; @@ -16277,6 +16400,7 @@ FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0633 062E 064A;;;;N;;;;; FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 062C 064A;;;;N;;;;; +FDCF;ARABIC LIGATURE SALAAMUHU ALAYNAA;So;0;ON;;;;;N;;;;; FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0635 0644 06D2;;;;N;;;;; FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0642 0644 06D2;;;;N;;;;; FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL; 0627 0644 0644 0647;;;;N;;;;; @@ -16291,6 +16415,8 @@ FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL; 0635 0644 06 FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL; 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;; FDFC;RIAL SIGN;Sc;0;AL; 0631 06CC 0627 0644;;;;N;;;;; FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;; +FDFE;ARABIC LIGATURE SUBHAANAHU WA TAAALAA;So;0;ON;;;;;N;;;;; +FDFF;ARABIC LIGATURE AZZA WA JALL;So;0;ON;;;;;N;;;;; FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;; FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;; FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;; @@ -17798,6 +17924,76 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10562;CAUCASIAN ALBANIAN LETTER PIWR;Lo;0;L;;;;;N;;;;; 10563;CAUCASIAN ALBANIAN LETTER KIW;Lo;0;L;;;;;N;;;;; 1056F;CAUCASIAN ALBANIAN CITATION MARK;Po;0;L;;;;;N;;;;; +10570;VITHKUQI CAPITAL LETTER A;Lu;0;L;;;;;N;;;;10597; +10571;VITHKUQI CAPITAL LETTER BBE;Lu;0;L;;;;;N;;;;10598; +10572;VITHKUQI CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;10599; +10573;VITHKUQI CAPITAL LETTER CE;Lu;0;L;;;;;N;;;;1059A; +10574;VITHKUQI CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;1059B; +10575;VITHKUQI CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;1059C; +10576;VITHKUQI CAPITAL LETTER DHE;Lu;0;L;;;;;N;;;;1059D; +10577;VITHKUQI CAPITAL LETTER EI;Lu;0;L;;;;;N;;;;1059E; +10578;VITHKUQI CAPITAL LETTER E;Lu;0;L;;;;;N;;;;1059F; +10579;VITHKUQI CAPITAL LETTER FE;Lu;0;L;;;;;N;;;;105A0; +1057A;VITHKUQI CAPITAL LETTER GA;Lu;0;L;;;;;N;;;;105A1; +1057C;VITHKUQI CAPITAL LETTER HA;Lu;0;L;;;;;N;;;;105A3; +1057D;VITHKUQI CAPITAL LETTER HHA;Lu;0;L;;;;;N;;;;105A4; +1057E;VITHKUQI CAPITAL LETTER I;Lu;0;L;;;;;N;;;;105A5; +1057F;VITHKUQI CAPITAL LETTER IJE;Lu;0;L;;;;;N;;;;105A6; +10580;VITHKUQI CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;105A7; +10581;VITHKUQI CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;105A8; +10582;VITHKUQI CAPITAL LETTER LA;Lu;0;L;;;;;N;;;;105A9; +10583;VITHKUQI CAPITAL LETTER LLA;Lu;0;L;;;;;N;;;;105AA; +10584;VITHKUQI CAPITAL LETTER ME;Lu;0;L;;;;;N;;;;105AB; +10585;VITHKUQI CAPITAL LETTER NE;Lu;0;L;;;;;N;;;;105AC; +10586;VITHKUQI CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;105AD; +10587;VITHKUQI CAPITAL LETTER O;Lu;0;L;;;;;N;;;;105AE; +10588;VITHKUQI CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;105AF; +10589;VITHKUQI CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;105B0; +1058A;VITHKUQI CAPITAL LETTER RE;Lu;0;L;;;;;N;;;;105B1; +1058C;VITHKUQI CAPITAL LETTER SE;Lu;0;L;;;;;N;;;;105B3; +1058D;VITHKUQI CAPITAL LETTER SHE;Lu;0;L;;;;;N;;;;105B4; +1058E;VITHKUQI CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;105B5; +1058F;VITHKUQI CAPITAL LETTER THE;Lu;0;L;;;;;N;;;;105B6; +10590;VITHKUQI CAPITAL LETTER U;Lu;0;L;;;;;N;;;;105B7; +10591;VITHKUQI CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;105B8; +10592;VITHKUQI CAPITAL LETTER XE;Lu;0;L;;;;;N;;;;105B9; +10594;VITHKUQI CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;105BB; +10595;VITHKUQI CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;105BC; +10597;VITHKUQI SMALL LETTER A;Ll;0;L;;;;;N;;;10570;;10570 +10598;VITHKUQI SMALL LETTER BBE;Ll;0;L;;;;;N;;;10571;;10571 +10599;VITHKUQI SMALL LETTER BE;Ll;0;L;;;;;N;;;10572;;10572 +1059A;VITHKUQI SMALL LETTER CE;Ll;0;L;;;;;N;;;10573;;10573 +1059B;VITHKUQI SMALL LETTER CHE;Ll;0;L;;;;;N;;;10574;;10574 +1059C;VITHKUQI SMALL LETTER DE;Ll;0;L;;;;;N;;;10575;;10575 +1059D;VITHKUQI SMALL LETTER DHE;Ll;0;L;;;;;N;;;10576;;10576 +1059E;VITHKUQI SMALL LETTER EI;Ll;0;L;;;;;N;;;10577;;10577 +1059F;VITHKUQI SMALL LETTER E;Ll;0;L;;;;;N;;;10578;;10578 +105A0;VITHKUQI SMALL LETTER FE;Ll;0;L;;;;;N;;;10579;;10579 +105A1;VITHKUQI SMALL LETTER GA;Ll;0;L;;;;;N;;;1057A;;1057A +105A3;VITHKUQI SMALL LETTER HA;Ll;0;L;;;;;N;;;1057C;;1057C +105A4;VITHKUQI SMALL LETTER HHA;Ll;0;L;;;;;N;;;1057D;;1057D +105A5;VITHKUQI SMALL LETTER I;Ll;0;L;;;;;N;;;1057E;;1057E +105A6;VITHKUQI SMALL LETTER IJE;Ll;0;L;;;;;N;;;1057F;;1057F +105A7;VITHKUQI SMALL LETTER JE;Ll;0;L;;;;;N;;;10580;;10580 +105A8;VITHKUQI SMALL LETTER KA;Ll;0;L;;;;;N;;;10581;;10581 +105A9;VITHKUQI SMALL LETTER LA;Ll;0;L;;;;;N;;;10582;;10582 +105AA;VITHKUQI SMALL LETTER LLA;Ll;0;L;;;;;N;;;10583;;10583 +105AB;VITHKUQI SMALL LETTER ME;Ll;0;L;;;;;N;;;10584;;10584 +105AC;VITHKUQI SMALL LETTER NE;Ll;0;L;;;;;N;;;10585;;10585 +105AD;VITHKUQI SMALL LETTER NJE;Ll;0;L;;;;;N;;;10586;;10586 +105AE;VITHKUQI SMALL LETTER O;Ll;0;L;;;;;N;;;10587;;10587 +105AF;VITHKUQI SMALL LETTER PE;Ll;0;L;;;;;N;;;10588;;10588 +105B0;VITHKUQI SMALL LETTER QA;Ll;0;L;;;;;N;;;10589;;10589 +105B1;VITHKUQI SMALL LETTER RE;Ll;0;L;;;;;N;;;1058A;;1058A +105B3;VITHKUQI SMALL LETTER SE;Ll;0;L;;;;;N;;;1058C;;1058C +105B4;VITHKUQI SMALL LETTER SHE;Ll;0;L;;;;;N;;;1058D;;1058D +105B5;VITHKUQI SMALL LETTER TE;Ll;0;L;;;;;N;;;1058E;;1058E +105B6;VITHKUQI SMALL LETTER THE;Ll;0;L;;;;;N;;;1058F;;1058F +105B7;VITHKUQI SMALL LETTER U;Ll;0;L;;;;;N;;;10590;;10590 +105B8;VITHKUQI SMALL LETTER VE;Ll;0;L;;;;;N;;;10591;;10591 +105B9;VITHKUQI SMALL LETTER XE;Ll;0;L;;;;;N;;;10592;;10592 +105BB;VITHKUQI SMALL LETTER Y;Ll;0;L;;;;;N;;;10594;;10594 +105BC;VITHKUQI SMALL LETTER ZE;Ll;0;L;;;;;N;;;10595;;10595 10600;LINEAR A SIGN AB001;Lo;0;L;;;;;N;;;;; 10601;LINEAR A SIGN AB002;Lo;0;L;;;;;N;;;;; 10602;LINEAR A SIGN AB003;Lo;0;L;;;;;N;;;;; @@ -18139,6 +18335,63 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10765;LINEAR A SIGN A805;Lo;0;L;;;;;N;;;;; 10766;LINEAR A SIGN A806;Lo;0;L;;;;;N;;;;; 10767;LINEAR A SIGN A807;Lo;0;L;;;;;N;;;;; +10780;MODIFIER LETTER SMALL CAPITAL AA;Lm;0;L;;;;;N;;;;; +10781;MODIFIER LETTER SUPERSCRIPT TRIANGULAR COLON;Lm;0;L; 02D0;;;;N;;;;; +10782;MODIFIER LETTER SUPERSCRIPT HALF TRIANGULAR COLON;Lm;0;L; 02D1;;;;N;;;;; +10783;MODIFIER LETTER SMALL AE;Lm;0;L; 00E6;;;;N;;;;; +10784;MODIFIER LETTER SMALL CAPITAL B;Lm;0;L; 0299;;;;N;;;;; +10785;MODIFIER LETTER SMALL B WITH HOOK;Lm;0;L; 0253;;;;N;;;;; +10787;MODIFIER LETTER SMALL DZ DIGRAPH;Lm;0;L; 02A3;;;;N;;;;; +10788;MODIFIER LETTER SMALL DZ DIGRAPH WITH RETROFLEX HOOK;Lm;0;L; AB66;;;;N;;;;; +10789;MODIFIER LETTER SMALL DZ DIGRAPH WITH CURL;Lm;0;L; 02A5;;;;N;;;;; +1078A;MODIFIER LETTER SMALL DEZH DIGRAPH;Lm;0;L; 02A4;;;;N;;;;; +1078B;MODIFIER LETTER SMALL D WITH TAIL;Lm;0;L; 0256;;;;N;;;;; +1078C;MODIFIER LETTER SMALL D WITH HOOK;Lm;0;L; 0257;;;;N;;;;; +1078D;MODIFIER LETTER SMALL D WITH HOOK AND TAIL;Lm;0;L; 1D91;;;;N;;;;; +1078E;MODIFIER LETTER SMALL REVERSED E;Lm;0;L; 0258;;;;N;;;;; +1078F;MODIFIER LETTER SMALL CLOSED REVERSED OPEN E;Lm;0;L; 025E;;;;N;;;;; +10790;MODIFIER LETTER SMALL FENG DIGRAPH;Lm;0;L; 02A9;;;;N;;;;; +10791;MODIFIER LETTER SMALL RAMS HORN;Lm;0;L; 0264;;;;N;;;;; +10792;MODIFIER LETTER SMALL CAPITAL G;Lm;0;L; 0262;;;;N;;;;; +10793;MODIFIER LETTER SMALL G WITH HOOK;Lm;0;L; 0260;;;;N;;;;; +10794;MODIFIER LETTER SMALL CAPITAL G WITH HOOK;Lm;0;L; 029B;;;;N;;;;; +10795;MODIFIER LETTER SMALL H WITH STROKE;Lm;0;L; 0127;;;;N;;;;; +10796;MODIFIER LETTER SMALL CAPITAL H;Lm;0;L; 029C;;;;N;;;;; +10797;MODIFIER LETTER SMALL HENG WITH HOOK;Lm;0;L; 0267;;;;N;;;;; +10798;MODIFIER LETTER SMALL DOTLESS J WITH STROKE AND HOOK;Lm;0;L; 0284;;;;N;;;;; +10799;MODIFIER LETTER SMALL LS DIGRAPH;Lm;0;L; 02AA;;;;N;;;;; +1079A;MODIFIER LETTER SMALL LZ DIGRAPH;Lm;0;L; 02AB;;;;N;;;;; +1079B;MODIFIER LETTER SMALL L WITH BELT;Lm;0;L; 026C;;;;N;;;;; +1079C;MODIFIER LETTER SMALL CAPITAL L WITH BELT;Lm;0;L; 1DF04;;;;N;;;;; +1079D;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK AND BELT;Lm;0;L; A78E;;;;N;;;;; +1079E;MODIFIER LETTER SMALL LEZH;Lm;0;L; 026E;;;;N;;;;; +1079F;MODIFIER LETTER SMALL LEZH WITH RETROFLEX HOOK;Lm;0;L; 1DF05;;;;N;;;;; +107A0;MODIFIER LETTER SMALL TURNED Y;Lm;0;L; 028E;;;;N;;;;; +107A1;MODIFIER LETTER SMALL TURNED Y WITH BELT;Lm;0;L; 1DF06;;;;N;;;;; +107A2;MODIFIER LETTER SMALL O WITH STROKE;Lm;0;L; 00F8;;;;N;;;;; +107A3;MODIFIER LETTER SMALL CAPITAL OE;Lm;0;L; 0276;;;;N;;;;; +107A4;MODIFIER LETTER SMALL CLOSED OMEGA;Lm;0;L; 0277;;;;N;;;;; +107A5;MODIFIER LETTER SMALL Q;Lm;0;L; 0071;;;;N;;;;; +107A6;MODIFIER LETTER SMALL TURNED R WITH LONG LEG;Lm;0;L; 027A;;;;N;;;;; +107A7;MODIFIER LETTER SMALL TURNED R WITH LONG LEG AND RETROFLEX HOOK;Lm;0;L; 1DF08;;;;N;;;;; +107A8;MODIFIER LETTER SMALL R WITH TAIL;Lm;0;L; 027D;;;;N;;;;; +107A9;MODIFIER LETTER SMALL R WITH FISHHOOK;Lm;0;L; 027E;;;;N;;;;; +107AA;MODIFIER LETTER SMALL CAPITAL R;Lm;0;L; 0280;;;;N;;;;; +107AB;MODIFIER LETTER SMALL TC DIGRAPH WITH CURL;Lm;0;L; 02A8;;;;N;;;;; +107AC;MODIFIER LETTER SMALL TS DIGRAPH;Lm;0;L; 02A6;;;;N;;;;; +107AD;MODIFIER LETTER SMALL TS DIGRAPH WITH RETROFLEX HOOK;Lm;0;L; AB67;;;;N;;;;; +107AE;MODIFIER LETTER SMALL TESH DIGRAPH;Lm;0;L; 02A7;;;;N;;;;; +107AF;MODIFIER LETTER SMALL T WITH RETROFLEX HOOK;Lm;0;L; 0288;;;;N;;;;; +107B0;MODIFIER LETTER SMALL V WITH RIGHT HOOK;Lm;0;L; 2C71;;;;N;;;;; +107B2;MODIFIER LETTER SMALL CAPITAL Y;Lm;0;L; 028F;;;;N;;;;; +107B3;MODIFIER LETTER GLOTTAL STOP WITH STROKE;Lm;0;L; 02A1;;;;N;;;;; +107B4;MODIFIER LETTER REVERSED GLOTTAL STOP WITH STROKE;Lm;0;L; 02A2;;;;N;;;;; +107B5;MODIFIER LETTER BILABIAL CLICK;Lm;0;L; 0298;;;;N;;;;; +107B6;MODIFIER LETTER DENTAL CLICK;Lm;0;L; 01C0;;;;N;;;;; +107B7;MODIFIER LETTER LATERAL CLICK;Lm;0;L; 01C1;;;;N;;;;; +107B8;MODIFIER LETTER ALVEOLAR CLICK;Lm;0;L; 01C2;;;;N;;;;; +107B9;MODIFIER LETTER RETROFLEX CLICK WITH RETROFLEX HOOK;Lm;0;L; 1DF0A;;;;N;;;;; +107BA;MODIFIER LETTER SMALL S WITH CURL;Lm;0;L; 1DF1E;;;;N;;;;; 10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;; 10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;; 10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;; @@ -19222,6 +19475,32 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;; 10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;; 10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;; +10F70;OLD UYGHUR LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10F71;OLD UYGHUR LETTER BETH;Lo;0;R;;;;;N;;;;; +10F72;OLD UYGHUR LETTER GIMEL-HETH;Lo;0;R;;;;;N;;;;; +10F73;OLD UYGHUR LETTER WAW;Lo;0;R;;;;;N;;;;; +10F74;OLD UYGHUR LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10F75;OLD UYGHUR LETTER FINAL HETH;Lo;0;R;;;;;N;;;;; +10F76;OLD UYGHUR LETTER YODH;Lo;0;R;;;;;N;;;;; +10F77;OLD UYGHUR LETTER KAPH;Lo;0;R;;;;;N;;;;; +10F78;OLD UYGHUR LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10F79;OLD UYGHUR LETTER MEM;Lo;0;R;;;;;N;;;;; +10F7A;OLD UYGHUR LETTER NUN;Lo;0;R;;;;;N;;;;; +10F7B;OLD UYGHUR LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10F7C;OLD UYGHUR LETTER PE;Lo;0;R;;;;;N;;;;; +10F7D;OLD UYGHUR LETTER SADHE;Lo;0;R;;;;;N;;;;; +10F7E;OLD UYGHUR LETTER RESH;Lo;0;R;;;;;N;;;;; +10F7F;OLD UYGHUR LETTER SHIN;Lo;0;R;;;;;N;;;;; +10F80;OLD UYGHUR LETTER TAW;Lo;0;R;;;;;N;;;;; +10F81;OLD UYGHUR LETTER LESH;Lo;0;R;;;;;N;;;;; +10F82;OLD UYGHUR COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +10F83;OLD UYGHUR COMBINING DOT BELOW;Mn;220;NSM;;;;;N;;;;; +10F84;OLD UYGHUR COMBINING TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +10F85;OLD UYGHUR COMBINING TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +10F86;OLD UYGHUR PUNCTUATION BAR;Po;0;R;;;;;N;;;;; +10F87;OLD UYGHUR PUNCTUATION TWO BARS;Po;0;R;;;;;N;;;;; +10F88;OLD UYGHUR PUNCTUATION TWO DOTS;Po;0;R;;;;;N;;;;; +10F89;OLD UYGHUR PUNCTUATION FOUR DOTS;Po;0;R;;;;;N;;;;; 10FB0;CHORASMIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; 10FB1;CHORASMIAN LETTER SMALL ALEPH;Lo;0;R;;;;;N;;;;; 10FB2;CHORASMIAN LETTER BETH;Lo;0;R;;;;;N;;;;; @@ -19381,6 +19660,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1106D;BRAHMI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 1106E;BRAHMI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1106F;BRAHMI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11070;BRAHMI SIGN OLD TAMIL VIRAMA;Mn;9;NSM;;;;;N;;;;; +11071;BRAHMI LETTER OLD TAMIL SHORT E;Lo;0;L;;;;;N;;;;; +11072;BRAHMI LETTER OLD TAMIL SHORT O;Lo;0;L;;;;;N;;;;; +11073;BRAHMI VOWEL SIGN OLD TAMIL SHORT E;Mn;0;NSM;;;;;N;;;;; +11074;BRAHMI VOWEL SIGN OLD TAMIL SHORT O;Mn;0;NSM;;;;;N;;;;; +11075;BRAHMI LETTER OLD TAMIL LLA;Lo;0;L;;;;;N;;;;; 1107F;BRAHMI NUMBER JOINER;Mn;9;NSM;;;;;N;;;;; 11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; @@ -19448,6 +19733,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;; 110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;; 110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +110C2;KAITHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; 110CD;KAITHI NUMBER SIGN ABOVE;Cf;0;L;;;;;N;;;;; 110D0;SORA SOMPENG LETTER SAH;Lo;0;L;;;;;N;;;;; 110D1;SORA SOMPENG LETTER TAH;Lo;0;L;;;;;N;;;;; @@ -20385,6 +20671,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;; 116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 116B8;TAKRI LETTER ARCHAIC KHA;Lo;0;L;;;;;N;;;;; +116B9;TAKRI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -20453,6 +20740,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1173D;AHOM SIGN SECTION;Po;0;L;;;;;N;;;;; 1173E;AHOM SIGN RULAI;Po;0;L;;;;;N;;;;; 1173F;AHOM SYMBOL VI;So;0;L;;;;;N;;;;; +11740;AHOM LETTER CA;Lo;0;L;;;;;N;;;;; +11741;AHOM LETTER TTA;Lo;0;L;;;;;N;;;;; +11742;AHOM LETTER TTHA;Lo;0;L;;;;;N;;;;; +11743;AHOM LETTER DDA;Lo;0;L;;;;;N;;;;; +11744;AHOM LETTER DDHA;Lo;0;L;;;;;N;;;;; +11745;AHOM LETTER NNA;Lo;0;L;;;;;N;;;;; +11746;AHOM LETTER LLA;Lo;0;L;;;;;N;;;;; 11800;DOGRA LETTER A;Lo;0;L;;;;;N;;;;; 11801;DOGRA LETTER AA;Lo;0;L;;;;;N;;;;; 11802;DOGRA LETTER I;Lo;0;L;;;;;N;;;;; @@ -20889,6 +21183,22 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11AA0;SOYOMBO HEAD MARK WITH MOON AND SUN;Po;0;L;;;;;N;;;;; 11AA1;SOYOMBO TERMINAL MARK-1;Po;0;L;;;;;N;;;;; 11AA2;SOYOMBO TERMINAL MARK-2;Po;0;L;;;;;N;;;;; +11AB0;CANADIAN SYLLABICS NATTILIK HI;Lo;0;L;;;;;N;;;;; +11AB1;CANADIAN SYLLABICS NATTILIK HII;Lo;0;L;;;;;N;;;;; +11AB2;CANADIAN SYLLABICS NATTILIK HO;Lo;0;L;;;;;N;;;;; +11AB3;CANADIAN SYLLABICS NATTILIK HOO;Lo;0;L;;;;;N;;;;; +11AB4;CANADIAN SYLLABICS NATTILIK HA;Lo;0;L;;;;;N;;;;; +11AB5;CANADIAN SYLLABICS NATTILIK HAA;Lo;0;L;;;;;N;;;;; +11AB6;CANADIAN SYLLABICS NATTILIK SHRI;Lo;0;L;;;;;N;;;;; +11AB7;CANADIAN SYLLABICS NATTILIK SHRII;Lo;0;L;;;;;N;;;;; +11AB8;CANADIAN SYLLABICS NATTILIK SHRO;Lo;0;L;;;;;N;;;;; +11AB9;CANADIAN SYLLABICS NATTILIK SHROO;Lo;0;L;;;;;N;;;;; +11ABA;CANADIAN SYLLABICS NATTILIK SHRA;Lo;0;L;;;;;N;;;;; +11ABB;CANADIAN SYLLABICS NATTILIK SHRAA;Lo;0;L;;;;;N;;;;; +11ABC;CANADIAN SYLLABICS SPE;Lo;0;L;;;;;N;;;;; +11ABD;CANADIAN SYLLABICS SPI;Lo;0;L;;;;;N;;;;; +11ABE;CANADIAN SYLLABICS SPO;Lo;0;L;;;;;N;;;;; +11ABF;CANADIAN SYLLABICS SPA;Lo;0;L;;;;;N;;;;; 11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;; 11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;; 11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;; @@ -22560,6 +22870,105 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 12541;CUNEIFORM SIGN ZA7;Lo;0;L;;;;;N;;;;; 12542;CUNEIFORM SIGN ZU OVER ZU PLUS SAR;Lo;0;L;;;;;N;;;;; 12543;CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU;Lo;0;L;;;;;N;;;;; +12F90;CYPRO-MINOAN SIGN CM001;Lo;0;L;;;;;N;;;;; +12F91;CYPRO-MINOAN SIGN CM002;Lo;0;L;;;;;N;;;;; +12F92;CYPRO-MINOAN SIGN CM004;Lo;0;L;;;;;N;;;;; +12F93;CYPRO-MINOAN SIGN CM005;Lo;0;L;;;;;N;;;;; +12F94;CYPRO-MINOAN SIGN CM006;Lo;0;L;;;;;N;;;;; +12F95;CYPRO-MINOAN SIGN CM007;Lo;0;L;;;;;N;;;;; +12F96;CYPRO-MINOAN SIGN CM008;Lo;0;L;;;;;N;;;;; +12F97;CYPRO-MINOAN SIGN CM009;Lo;0;L;;;;;N;;;;; +12F98;CYPRO-MINOAN SIGN CM010;Lo;0;L;;;;;N;;;;; +12F99;CYPRO-MINOAN SIGN CM011;Lo;0;L;;;;;N;;;;; +12F9A;CYPRO-MINOAN SIGN CM012;Lo;0;L;;;;;N;;;;; +12F9B;CYPRO-MINOAN SIGN CM012B;Lo;0;L;;;;;N;;;;; +12F9C;CYPRO-MINOAN SIGN CM013;Lo;0;L;;;;;N;;;;; +12F9D;CYPRO-MINOAN SIGN CM015;Lo;0;L;;;;;N;;;;; +12F9E;CYPRO-MINOAN SIGN CM017;Lo;0;L;;;;;N;;;;; +12F9F;CYPRO-MINOAN SIGN CM019;Lo;0;L;;;;;N;;;;; +12FA0;CYPRO-MINOAN SIGN CM021;Lo;0;L;;;;;N;;;;; +12FA1;CYPRO-MINOAN SIGN CM023;Lo;0;L;;;;;N;;;;; +12FA2;CYPRO-MINOAN SIGN CM024;Lo;0;L;;;;;N;;;;; +12FA3;CYPRO-MINOAN SIGN CM025;Lo;0;L;;;;;N;;;;; +12FA4;CYPRO-MINOAN SIGN CM026;Lo;0;L;;;;;N;;;;; +12FA5;CYPRO-MINOAN SIGN CM027;Lo;0;L;;;;;N;;;;; +12FA6;CYPRO-MINOAN SIGN CM028;Lo;0;L;;;;;N;;;;; +12FA7;CYPRO-MINOAN SIGN CM029;Lo;0;L;;;;;N;;;;; +12FA8;CYPRO-MINOAN SIGN CM030;Lo;0;L;;;;;N;;;;; +12FA9;CYPRO-MINOAN SIGN CM033;Lo;0;L;;;;;N;;;;; +12FAA;CYPRO-MINOAN SIGN CM034;Lo;0;L;;;;;N;;;;; +12FAB;CYPRO-MINOAN SIGN CM035;Lo;0;L;;;;;N;;;;; +12FAC;CYPRO-MINOAN SIGN CM036;Lo;0;L;;;;;N;;;;; +12FAD;CYPRO-MINOAN SIGN CM037;Lo;0;L;;;;;N;;;;; +12FAE;CYPRO-MINOAN SIGN CM038;Lo;0;L;;;;;N;;;;; +12FAF;CYPRO-MINOAN SIGN CM039;Lo;0;L;;;;;N;;;;; +12FB0;CYPRO-MINOAN SIGN CM040;Lo;0;L;;;;;N;;;;; +12FB1;CYPRO-MINOAN SIGN CM041;Lo;0;L;;;;;N;;;;; +12FB2;CYPRO-MINOAN SIGN CM044;Lo;0;L;;;;;N;;;;; +12FB3;CYPRO-MINOAN SIGN CM046;Lo;0;L;;;;;N;;;;; +12FB4;CYPRO-MINOAN SIGN CM047;Lo;0;L;;;;;N;;;;; +12FB5;CYPRO-MINOAN SIGN CM049;Lo;0;L;;;;;N;;;;; +12FB6;CYPRO-MINOAN SIGN CM050;Lo;0;L;;;;;N;;;;; +12FB7;CYPRO-MINOAN SIGN CM051;Lo;0;L;;;;;N;;;;; +12FB8;CYPRO-MINOAN SIGN CM052;Lo;0;L;;;;;N;;;;; +12FB9;CYPRO-MINOAN SIGN CM053;Lo;0;L;;;;;N;;;;; +12FBA;CYPRO-MINOAN SIGN CM054;Lo;0;L;;;;;N;;;;; +12FBB;CYPRO-MINOAN SIGN CM055;Lo;0;L;;;;;N;;;;; +12FBC;CYPRO-MINOAN SIGN CM056;Lo;0;L;;;;;N;;;;; +12FBD;CYPRO-MINOAN SIGN CM058;Lo;0;L;;;;;N;;;;; +12FBE;CYPRO-MINOAN SIGN CM059;Lo;0;L;;;;;N;;;;; +12FBF;CYPRO-MINOAN SIGN CM060;Lo;0;L;;;;;N;;;;; +12FC0;CYPRO-MINOAN SIGN CM061;Lo;0;L;;;;;N;;;;; +12FC1;CYPRO-MINOAN SIGN CM062;Lo;0;L;;;;;N;;;;; +12FC2;CYPRO-MINOAN SIGN CM063;Lo;0;L;;;;;N;;;;; +12FC3;CYPRO-MINOAN SIGN CM064;Lo;0;L;;;;;N;;;;; +12FC4;CYPRO-MINOAN SIGN CM066;Lo;0;L;;;;;N;;;;; +12FC5;CYPRO-MINOAN SIGN CM067;Lo;0;L;;;;;N;;;;; +12FC6;CYPRO-MINOAN SIGN CM068;Lo;0;L;;;;;N;;;;; +12FC7;CYPRO-MINOAN SIGN CM069;Lo;0;L;;;;;N;;;;; +12FC8;CYPRO-MINOAN SIGN CM070;Lo;0;L;;;;;N;;;;; +12FC9;CYPRO-MINOAN SIGN CM071;Lo;0;L;;;;;N;;;;; +12FCA;CYPRO-MINOAN SIGN CM072;Lo;0;L;;;;;N;;;;; +12FCB;CYPRO-MINOAN SIGN CM073;Lo;0;L;;;;;N;;;;; +12FCC;CYPRO-MINOAN SIGN CM074;Lo;0;L;;;;;N;;;;; +12FCD;CYPRO-MINOAN SIGN CM075;Lo;0;L;;;;;N;;;;; +12FCE;CYPRO-MINOAN SIGN CM075B;Lo;0;L;;;;;N;;;;; +12FCF;CYPRO-MINOAN SIGN CM076;Lo;0;L;;;;;N;;;;; +12FD0;CYPRO-MINOAN SIGN CM078;Lo;0;L;;;;;N;;;;; +12FD1;CYPRO-MINOAN SIGN CM079;Lo;0;L;;;;;N;;;;; +12FD2;CYPRO-MINOAN SIGN CM080;Lo;0;L;;;;;N;;;;; +12FD3;CYPRO-MINOAN SIGN CM081;Lo;0;L;;;;;N;;;;; +12FD4;CYPRO-MINOAN SIGN CM082;Lo;0;L;;;;;N;;;;; +12FD5;CYPRO-MINOAN SIGN CM083;Lo;0;L;;;;;N;;;;; +12FD6;CYPRO-MINOAN SIGN CM084;Lo;0;L;;;;;N;;;;; +12FD7;CYPRO-MINOAN SIGN CM085;Lo;0;L;;;;;N;;;;; +12FD8;CYPRO-MINOAN SIGN CM086;Lo;0;L;;;;;N;;;;; +12FD9;CYPRO-MINOAN SIGN CM087;Lo;0;L;;;;;N;;;;; +12FDA;CYPRO-MINOAN SIGN CM088;Lo;0;L;;;;;N;;;;; +12FDB;CYPRO-MINOAN SIGN CM089;Lo;0;L;;;;;N;;;;; +12FDC;CYPRO-MINOAN SIGN CM090;Lo;0;L;;;;;N;;;;; +12FDD;CYPRO-MINOAN SIGN CM091;Lo;0;L;;;;;N;;;;; +12FDE;CYPRO-MINOAN SIGN CM092;Lo;0;L;;;;;N;;;;; +12FDF;CYPRO-MINOAN SIGN CM094;Lo;0;L;;;;;N;;;;; +12FE0;CYPRO-MINOAN SIGN CM095;Lo;0;L;;;;;N;;;;; +12FE1;CYPRO-MINOAN SIGN CM096;Lo;0;L;;;;;N;;;;; +12FE2;CYPRO-MINOAN SIGN CM097;Lo;0;L;;;;;N;;;;; +12FE3;CYPRO-MINOAN SIGN CM098;Lo;0;L;;;;;N;;;;; +12FE4;CYPRO-MINOAN SIGN CM099;Lo;0;L;;;;;N;;;;; +12FE5;CYPRO-MINOAN SIGN CM100;Lo;0;L;;;;;N;;;;; +12FE6;CYPRO-MINOAN SIGN CM101;Lo;0;L;;;;;N;;;;; +12FE7;CYPRO-MINOAN SIGN CM102;Lo;0;L;;;;;N;;;;; +12FE8;CYPRO-MINOAN SIGN CM103;Lo;0;L;;;;;N;;;;; +12FE9;CYPRO-MINOAN SIGN CM104;Lo;0;L;;;;;N;;;;; +12FEA;CYPRO-MINOAN SIGN CM105;Lo;0;L;;;;;N;;;;; +12FEB;CYPRO-MINOAN SIGN CM107;Lo;0;L;;;;;N;;;;; +12FEC;CYPRO-MINOAN SIGN CM108;Lo;0;L;;;;;N;;;;; +12FED;CYPRO-MINOAN SIGN CM109;Lo;0;L;;;;;N;;;;; +12FEE;CYPRO-MINOAN SIGN CM110;Lo;0;L;;;;;N;;;;; +12FEF;CYPRO-MINOAN SIGN CM112;Lo;0;L;;;;;N;;;;; +12FF0;CYPRO-MINOAN SIGN CM114;Lo;0;L;;;;;N;;;;; +12FF1;CYPRO-MINOAN SIGN CM301;Po;0;L;;;;;N;;;;; +12FF2;CYPRO-MINOAN SIGN CM302;Po;0;L;;;;;N;;;;; 13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; 13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; 13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; @@ -24835,6 +25244,95 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16A69;MRO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 16A6E;MRO DANDA;Po;0;L;;;;;N;;;;; 16A6F;MRO DOUBLE DANDA;Po;0;L;;;;;N;;;;; +16A70;TANGSA LETTER OZ;Lo;0;L;;;;;N;;;;; +16A71;TANGSA LETTER OC;Lo;0;L;;;;;N;;;;; +16A72;TANGSA LETTER OQ;Lo;0;L;;;;;N;;;;; +16A73;TANGSA LETTER OX;Lo;0;L;;;;;N;;;;; +16A74;TANGSA LETTER AZ;Lo;0;L;;;;;N;;;;; +16A75;TANGSA LETTER AC;Lo;0;L;;;;;N;;;;; +16A76;TANGSA LETTER AQ;Lo;0;L;;;;;N;;;;; +16A77;TANGSA LETTER AX;Lo;0;L;;;;;N;;;;; +16A78;TANGSA LETTER VZ;Lo;0;L;;;;;N;;;;; +16A79;TANGSA LETTER VC;Lo;0;L;;;;;N;;;;; +16A7A;TANGSA LETTER VQ;Lo;0;L;;;;;N;;;;; +16A7B;TANGSA LETTER VX;Lo;0;L;;;;;N;;;;; +16A7C;TANGSA LETTER EZ;Lo;0;L;;;;;N;;;;; +16A7D;TANGSA LETTER EC;Lo;0;L;;;;;N;;;;; +16A7E;TANGSA LETTER EQ;Lo;0;L;;;;;N;;;;; +16A7F;TANGSA LETTER EX;Lo;0;L;;;;;N;;;;; +16A80;TANGSA LETTER IZ;Lo;0;L;;;;;N;;;;; +16A81;TANGSA LETTER IC;Lo;0;L;;;;;N;;;;; +16A82;TANGSA LETTER IQ;Lo;0;L;;;;;N;;;;; +16A83;TANGSA LETTER IX;Lo;0;L;;;;;N;;;;; +16A84;TANGSA LETTER UZ;Lo;0;L;;;;;N;;;;; +16A85;TANGSA LETTER UC;Lo;0;L;;;;;N;;;;; +16A86;TANGSA LETTER UQ;Lo;0;L;;;;;N;;;;; +16A87;TANGSA LETTER UX;Lo;0;L;;;;;N;;;;; +16A88;TANGSA LETTER AWZ;Lo;0;L;;;;;N;;;;; +16A89;TANGSA LETTER AWC;Lo;0;L;;;;;N;;;;; +16A8A;TANGSA LETTER AWQ;Lo;0;L;;;;;N;;;;; +16A8B;TANGSA LETTER AWX;Lo;0;L;;;;;N;;;;; +16A8C;TANGSA LETTER UIZ;Lo;0;L;;;;;N;;;;; +16A8D;TANGSA LETTER UIC;Lo;0;L;;;;;N;;;;; +16A8E;TANGSA LETTER UIQ;Lo;0;L;;;;;N;;;;; +16A8F;TANGSA LETTER UIX;Lo;0;L;;;;;N;;;;; +16A90;TANGSA LETTER FINAL NG;Lo;0;L;;;;;N;;;;; +16A91;TANGSA LETTER LONG UEX;Lo;0;L;;;;;N;;;;; +16A92;TANGSA LETTER SHORT UEZ;Lo;0;L;;;;;N;;;;; +16A93;TANGSA LETTER SHORT AWX;Lo;0;L;;;;;N;;;;; +16A94;TANGSA LETTER UEC;Lo;0;L;;;;;N;;;;; +16A95;TANGSA LETTER UEZ;Lo;0;L;;;;;N;;;;; +16A96;TANGSA LETTER UEQ;Lo;0;L;;;;;N;;;;; +16A97;TANGSA LETTER UEX;Lo;0;L;;;;;N;;;;; +16A98;TANGSA LETTER UIUZ;Lo;0;L;;;;;N;;;;; +16A99;TANGSA LETTER UIUC;Lo;0;L;;;;;N;;;;; +16A9A;TANGSA LETTER UIUQ;Lo;0;L;;;;;N;;;;; +16A9B;TANGSA LETTER UIUX;Lo;0;L;;;;;N;;;;; +16A9C;TANGSA LETTER MZ;Lo;0;L;;;;;N;;;;; +16A9D;TANGSA LETTER MC;Lo;0;L;;;;;N;;;;; +16A9E;TANGSA LETTER MQ;Lo;0;L;;;;;N;;;;; +16A9F;TANGSA LETTER MX;Lo;0;L;;;;;N;;;;; +16AA0;TANGSA LETTER KA;Lo;0;L;;;;;N;;;;; +16AA1;TANGSA LETTER KHA;Lo;0;L;;;;;N;;;;; +16AA2;TANGSA LETTER GA;Lo;0;L;;;;;N;;;;; +16AA3;TANGSA LETTER NGA;Lo;0;L;;;;;N;;;;; +16AA4;TANGSA LETTER SA;Lo;0;L;;;;;N;;;;; +16AA5;TANGSA LETTER YA;Lo;0;L;;;;;N;;;;; +16AA6;TANGSA LETTER WA;Lo;0;L;;;;;N;;;;; +16AA7;TANGSA LETTER PA;Lo;0;L;;;;;N;;;;; +16AA8;TANGSA LETTER NYA;Lo;0;L;;;;;N;;;;; +16AA9;TANGSA LETTER PHA;Lo;0;L;;;;;N;;;;; +16AAA;TANGSA LETTER BA;Lo;0;L;;;;;N;;;;; +16AAB;TANGSA LETTER MA;Lo;0;L;;;;;N;;;;; +16AAC;TANGSA LETTER NA;Lo;0;L;;;;;N;;;;; +16AAD;TANGSA LETTER HA;Lo;0;L;;;;;N;;;;; +16AAE;TANGSA LETTER LA;Lo;0;L;;;;;N;;;;; +16AAF;TANGSA LETTER HTA;Lo;0;L;;;;;N;;;;; +16AB0;TANGSA LETTER TA;Lo;0;L;;;;;N;;;;; +16AB1;TANGSA LETTER DA;Lo;0;L;;;;;N;;;;; +16AB2;TANGSA LETTER RA;Lo;0;L;;;;;N;;;;; +16AB3;TANGSA LETTER NHA;Lo;0;L;;;;;N;;;;; +16AB4;TANGSA LETTER SHA;Lo;0;L;;;;;N;;;;; +16AB5;TANGSA LETTER CA;Lo;0;L;;;;;N;;;;; +16AB6;TANGSA LETTER TSA;Lo;0;L;;;;;N;;;;; +16AB7;TANGSA LETTER GHA;Lo;0;L;;;;;N;;;;; +16AB8;TANGSA LETTER HTTA;Lo;0;L;;;;;N;;;;; +16AB9;TANGSA LETTER THA;Lo;0;L;;;;;N;;;;; +16ABA;TANGSA LETTER XA;Lo;0;L;;;;;N;;;;; +16ABB;TANGSA LETTER FA;Lo;0;L;;;;;N;;;;; +16ABC;TANGSA LETTER DHA;Lo;0;L;;;;;N;;;;; +16ABD;TANGSA LETTER CHA;Lo;0;L;;;;;N;;;;; +16ABE;TANGSA LETTER ZA;Lo;0;L;;;;;N;;;;; +16AC0;TANGSA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +16AC1;TANGSA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +16AC2;TANGSA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +16AC3;TANGSA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +16AC4;TANGSA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +16AC5;TANGSA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +16AC6;TANGSA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +16AC7;TANGSA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +16AC8;TANGSA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +16AC9;TANGSA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 16AD0;BASSA VAH LETTER ENNI;Lo;0;L;;;;;N;;;;; 16AD1;BASSA VAH LETTER KA;Lo;0;L;;;;;N;;;;; 16AD2;BASSA VAH LETTER SE;Lo;0;L;;;;;N;;;;; @@ -26487,6 +26985,19 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 18CD5;KHITAN SMALL SCRIPT CHARACTER-18CD5;Lo;0;L;;;;;N;;;;; 18D00;;Lo;0;L;;;;;N;;;;; 18D08;;Lo;0;L;;;;;N;;;;; +1AFF0;KATAKANA LETTER MINNAN TONE-2;Lm;0;L;;;;;N;;;;; +1AFF1;KATAKANA LETTER MINNAN TONE-3;Lm;0;L;;;;;N;;;;; +1AFF2;KATAKANA LETTER MINNAN TONE-4;Lm;0;L;;;;;N;;;;; +1AFF3;KATAKANA LETTER MINNAN TONE-5;Lm;0;L;;;;;N;;;;; +1AFF5;KATAKANA LETTER MINNAN TONE-7;Lm;0;L;;;;;N;;;;; +1AFF6;KATAKANA LETTER MINNAN TONE-8;Lm;0;L;;;;;N;;;;; +1AFF7;KATAKANA LETTER MINNAN NASALIZED TONE-1;Lm;0;L;;;;;N;;;;; +1AFF8;KATAKANA LETTER MINNAN NASALIZED TONE-2;Lm;0;L;;;;;N;;;;; +1AFF9;KATAKANA LETTER MINNAN NASALIZED TONE-3;Lm;0;L;;;;;N;;;;; +1AFFA;KATAKANA LETTER MINNAN NASALIZED TONE-4;Lm;0;L;;;;;N;;;;; +1AFFB;KATAKANA LETTER MINNAN NASALIZED TONE-5;Lm;0;L;;;;;N;;;;; +1AFFD;KATAKANA LETTER MINNAN NASALIZED TONE-7;Lm;0;L;;;;;N;;;;; +1AFFE;KATAKANA LETTER MINNAN NASALIZED TONE-8;Lm;0;L;;;;;N;;;;; 1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;; 1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;; 1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;; @@ -26774,6 +27285,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;; 1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;; 1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;; +1B11F;HIRAGANA LETTER ARCHAIC WU;Lo;0;L;;;;;N;;;;; +1B120;KATAKANA LETTER ARCHAIC YI;Lo;0;L;;;;;N;;;;; +1B121;KATAKANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;; +1B122;KATAKANA LETTER ARCHAIC WU;Lo;0;L;;;;;N;;;;; 1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; 1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; 1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; @@ -27324,6 +27839,191 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1BCA1;SHORTHAND FORMAT CONTINUING OVERLAP;Cf;0;BN;;;;;N;;;;; 1BCA2;SHORTHAND FORMAT DOWN STEP;Cf;0;BN;;;;;N;;;;; 1BCA3;SHORTHAND FORMAT UP STEP;Cf;0;BN;;;;;N;;;;; +1CF00;ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF01;ZNAMENNY COMBINING MARK NIZKO S KRYZHEM ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF02;ZNAMENNY COMBINING MARK TSATA ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF03;ZNAMENNY COMBINING MARK GORAZDO NIZKO ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF04;ZNAMENNY COMBINING MARK NIZKO ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF05;ZNAMENNY COMBINING MARK SREDNE ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF06;ZNAMENNY COMBINING MARK MALO POVYSHE ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF07;ZNAMENNY COMBINING MARK POVYSHE ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF08;ZNAMENNY COMBINING MARK VYSOKO ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF09;ZNAMENNY COMBINING MARK MALO POVYSHE S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF0A;ZNAMENNY COMBINING MARK POVYSHE S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF0B;ZNAMENNY COMBINING MARK VYSOKO S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF0C;ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF0D;ZNAMENNY COMBINING MARK NIZKO S KRYZHEM ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF0E;ZNAMENNY COMBINING MARK TSATA ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF0F;ZNAMENNY COMBINING MARK GORAZDO NIZKO ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF10;ZNAMENNY COMBINING MARK NIZKO ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF11;ZNAMENNY COMBINING MARK SREDNE ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF12;ZNAMENNY COMBINING MARK MALO POVYSHE ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF13;ZNAMENNY COMBINING MARK POVYSHE ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF14;ZNAMENNY COMBINING MARK VYSOKO ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF15;ZNAMENNY COMBINING MARK MALO POVYSHE S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF16;ZNAMENNY COMBINING MARK POVYSHE S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF17;ZNAMENNY COMBINING MARK VYSOKO S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;; +1CF18;ZNAMENNY COMBINING MARK TSATA S KRYZHEM;Mn;0;NSM;;;;;N;;;;; +1CF19;ZNAMENNY COMBINING MARK MALO POVYSHE S KRYZHEM;Mn;0;NSM;;;;;N;;;;; +1CF1A;ZNAMENNY COMBINING MARK STRANNO MALO POVYSHE;Mn;0;NSM;;;;;N;;;;; +1CF1B;ZNAMENNY COMBINING MARK POVYSHE S KRYZHEM;Mn;0;NSM;;;;;N;;;;; +1CF1C;ZNAMENNY COMBINING MARK POVYSHE STRANNO;Mn;0;NSM;;;;;N;;;;; +1CF1D;ZNAMENNY COMBINING MARK VYSOKO S KRYZHEM;Mn;0;NSM;;;;;N;;;;; +1CF1E;ZNAMENNY COMBINING MARK MALO POVYSHE STRANNO;Mn;0;NSM;;;;;N;;;;; +1CF1F;ZNAMENNY COMBINING MARK GORAZDO VYSOKO;Mn;0;NSM;;;;;N;;;;; +1CF20;ZNAMENNY COMBINING MARK ZELO;Mn;0;NSM;;;;;N;;;;; +1CF21;ZNAMENNY COMBINING MARK ON;Mn;0;NSM;;;;;N;;;;; +1CF22;ZNAMENNY COMBINING MARK RAVNO;Mn;0;NSM;;;;;N;;;;; +1CF23;ZNAMENNY COMBINING MARK TIKHAYA;Mn;0;NSM;;;;;N;;;;; +1CF24;ZNAMENNY COMBINING MARK BORZAYA;Mn;0;NSM;;;;;N;;;;; +1CF25;ZNAMENNY COMBINING MARK UDARKA;Mn;0;NSM;;;;;N;;;;; +1CF26;ZNAMENNY COMBINING MARK PODVERTKA;Mn;0;NSM;;;;;N;;;;; +1CF27;ZNAMENNY COMBINING MARK LOMKA;Mn;0;NSM;;;;;N;;;;; +1CF28;ZNAMENNY COMBINING MARK KUPNAYA;Mn;0;NSM;;;;;N;;;;; +1CF29;ZNAMENNY COMBINING MARK KACHKA;Mn;0;NSM;;;;;N;;;;; +1CF2A;ZNAMENNY COMBINING MARK ZEVOK;Mn;0;NSM;;;;;N;;;;; +1CF2B;ZNAMENNY COMBINING MARK SKOBA;Mn;0;NSM;;;;;N;;;;; +1CF2C;ZNAMENNY COMBINING MARK RAZSEKA;Mn;0;NSM;;;;;N;;;;; +1CF2D;ZNAMENNY COMBINING MARK KRYZH ON LEFT;Mn;0;NSM;;;;;N;;;;; +1CF30;ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO;Mn;0;NSM;;;;;N;;;;; +1CF31;ZNAMENNY COMBINING TONAL RANGE MARK SVETLO;Mn;0;NSM;;;;;N;;;;; +1CF32;ZNAMENNY COMBINING TONAL RANGE MARK TRESVETLO;Mn;0;NSM;;;;;N;;;;; +1CF33;ZNAMENNY COMBINING MARK ZADERZHKA;Mn;0;NSM;;;;;N;;;;; +1CF34;ZNAMENNY COMBINING MARK DEMESTVENNY ZADERZHKA;Mn;0;NSM;;;;;N;;;;; +1CF35;ZNAMENNY COMBINING MARK OTSECHKA;Mn;0;NSM;;;;;N;;;;; +1CF36;ZNAMENNY COMBINING MARK PODCHASHIE;Mn;0;NSM;;;;;N;;;;; +1CF37;ZNAMENNY COMBINING MARK PODCHASHIE WITH VERTICAL STROKE;Mn;0;NSM;;;;;N;;;;; +1CF38;ZNAMENNY COMBINING MARK CHASHKA;Mn;0;NSM;;;;;N;;;;; +1CF39;ZNAMENNY COMBINING MARK CHASHKA POLNAYA;Mn;0;NSM;;;;;N;;;;; +1CF3A;ZNAMENNY COMBINING MARK OBLACHKO;Mn;0;NSM;;;;;N;;;;; +1CF3B;ZNAMENNY COMBINING MARK SOROCHYA NOZHKA;Mn;0;NSM;;;;;N;;;;; +1CF3C;ZNAMENNY COMBINING MARK TOCHKA;Mn;0;NSM;;;;;N;;;;; +1CF3D;ZNAMENNY COMBINING MARK DVOETOCHIE;Mn;0;NSM;;;;;N;;;;; +1CF3E;ZNAMENNY COMBINING ATTACHING VERTICAL OMET;Mn;0;NSM;;;;;N;;;;; +1CF3F;ZNAMENNY COMBINING MARK CURVED OMET;Mn;0;NSM;;;;;N;;;;; +1CF40;ZNAMENNY COMBINING MARK KRYZH;Mn;0;NSM;;;;;N;;;;; +1CF41;ZNAMENNY COMBINING LOWER TONAL RANGE INDICATOR;Mn;0;NSM;;;;;N;;;;; +1CF42;ZNAMENNY PRIZNAK MODIFIER LEVEL-2;Mn;0;NSM;;;;;N;;;;; +1CF43;ZNAMENNY PRIZNAK MODIFIER LEVEL-3;Mn;0;NSM;;;;;N;;;;; +1CF44;ZNAMENNY PRIZNAK MODIFIER DIRECTION FLIP;Mn;0;NSM;;;;;N;;;;; +1CF45;ZNAMENNY PRIZNAK MODIFIER KRYZH;Mn;0;NSM;;;;;N;;;;; +1CF46;ZNAMENNY PRIZNAK MODIFIER ROG;Mn;0;NSM;;;;;N;;;;; +1CF50;ZNAMENNY NEUME KRYUK;So;0;L;;;;;N;;;;; +1CF51;ZNAMENNY NEUME KRYUK TIKHY;So;0;L;;;;;N;;;;; +1CF52;ZNAMENNY NEUME PARAKLIT;So;0;L;;;;;N;;;;; +1CF53;ZNAMENNY NEUME DVA V CHELNU;So;0;L;;;;;N;;;;; +1CF54;ZNAMENNY NEUME KLYUCH;So;0;L;;;;;N;;;;; +1CF55;ZNAMENNY NEUME ZANOZHEK;So;0;L;;;;;N;;;;; +1CF56;ZNAMENNY NEUME STOPITSA;So;0;L;;;;;N;;;;; +1CF57;ZNAMENNY NEUME STOPITSA S OCHKOM;So;0;L;;;;;N;;;;; +1CF58;ZNAMENNY NEUME PEREVODKA;So;0;L;;;;;N;;;;; +1CF59;ZNAMENNY NEUME PEREVODKA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;; +1CF5A;ZNAMENNY NEUME STOPITSA WITH SOROCHYA NOZHKA;So;0;L;;;;;N;;;;; +1CF5B;ZNAMENNY NEUME CHELYUSTKA;So;0;L;;;;;N;;;;; +1CF5C;ZNAMENNY NEUME PALKA;So;0;L;;;;;N;;;;; +1CF5D;ZNAMENNY NEUME ZAPYATAYA;So;0;L;;;;;N;;;;; +1CF5E;ZNAMENNY NEUME GOLUBCHIK BORZY;So;0;L;;;;;N;;;;; +1CF5F;ZNAMENNY NEUME GOLUBCHIK TIKHY;So;0;L;;;;;N;;;;; +1CF60;ZNAMENNY NEUME GOLUBCHIK MRACHNY;So;0;L;;;;;N;;;;; +1CF61;ZNAMENNY NEUME GOLUBCHIK SVETLY;So;0;L;;;;;N;;;;; +1CF62;ZNAMENNY NEUME GOLUBCHIK TRESVETLY;So;0;L;;;;;N;;;;; +1CF63;ZNAMENNY NEUME VRAKHIYA PROSTAYA;So;0;L;;;;;N;;;;; +1CF64;ZNAMENNY NEUME VRAKHIYA MRACHNAYA;So;0;L;;;;;N;;;;; +1CF65;ZNAMENNY NEUME VRAKHIYA SVETLAYA;So;0;L;;;;;N;;;;; +1CF66;ZNAMENNY NEUME VRAKHIYA TRESVETLAYA;So;0;L;;;;;N;;;;; +1CF67;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA PROSTAYA;So;0;L;;;;;N;;;;; +1CF68;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA MRACHNAYA;So;0;L;;;;;N;;;;; +1CF69;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;; +1CF6A;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA TRESVETLAYA;So;0;L;;;;;N;;;;; +1CF6B;ZNAMENNY NEUME DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;; +1CF6C;ZNAMENNY NEUME REVERSED CHELYUSTKA;So;0;L;;;;;N;;;;; +1CF6D;ZNAMENNY NEUME DERBITSA;So;0;L;;;;;N;;;;; +1CF6E;ZNAMENNY NEUME KHAMILO;So;0;L;;;;;N;;;;; +1CF6F;ZNAMENNY NEUME CHASHKA;So;0;L;;;;;N;;;;; +1CF70;ZNAMENNY NEUME PODCHASHIE;So;0;L;;;;;N;;;;; +1CF71;ZNAMENNY NEUME SKAMEYTSA MRACHNAYA;So;0;L;;;;;N;;;;; +1CF72;ZNAMENNY NEUME SKAMEYTSA SVETLAYA;So;0;L;;;;;N;;;;; +1CF73;ZNAMENNY NEUME SKAMEYTSA TRESVETLAYA;So;0;L;;;;;N;;;;; +1CF74;ZNAMENNY NEUME SKAMEYTSA TIKHAYA;So;0;L;;;;;N;;;;; +1CF75;ZNAMENNY NEUME DEMESTVENNY KLYUCH;So;0;L;;;;;N;;;;; +1CF76;ZNAMENNY NEUME SKAMEYTSA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;; +1CF77;ZNAMENNY NEUME SKAMEYTSA KLYUCHENEPOSTOYANNAYA;So;0;L;;;;;N;;;;; +1CF78;ZNAMENNY NEUME SKAMEYTSA KLYUCHEVAYA TIKHAYA;So;0;L;;;;;N;;;;; +1CF79;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA PROSTAYA;So;0;L;;;;;N;;;;; +1CF7A;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA SVETLAYA;So;0;L;;;;;N;;;;; +1CF7B;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;; +1CF7C;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;; +1CF7D;ZNAMENNY NEUME SLOZHITIE;So;0;L;;;;;N;;;;; +1CF7E;ZNAMENNY NEUME SLOZHITIE S ZAPYATOY;So;0;L;;;;;N;;;;; +1CF7F;ZNAMENNY NEUME SLOZHITIE ZAKRYTOE;So;0;L;;;;;N;;;;; +1CF80;ZNAMENNY NEUME SLOZHITIE S KRYZHEM;So;0;L;;;;;N;;;;; +1CF81;ZNAMENNY NEUME KRYZH;So;0;L;;;;;N;;;;; +1CF82;ZNAMENNY NEUME ROG;So;0;L;;;;;N;;;;; +1CF83;ZNAMENNY NEUME FITA;So;0;L;;;;;N;;;;; +1CF84;ZNAMENNY NEUME KOBYLA;So;0;L;;;;;N;;;;; +1CF85;ZNAMENNY NEUME ZMEYTSA;So;0;L;;;;;N;;;;; +1CF86;ZNAMENNY NEUME STATYA;So;0;L;;;;;N;;;;; +1CF87;ZNAMENNY NEUME STATYA S ZAPYATOY;So;0;L;;;;;N;;;;; +1CF88;ZNAMENNY NEUME STATYA S KRYZHEM;So;0;L;;;;;N;;;;; +1CF89;ZNAMENNY NEUME STATYA S ZAPYATOY I KRYZHEM;So;0;L;;;;;N;;;;; +1CF8A;ZNAMENNY NEUME STATYA S KRYZHEM I ZAPYATOY;So;0;L;;;;;N;;;;; +1CF8B;ZNAMENNY NEUME STATYA ZAKRYTAYA;So;0;L;;;;;N;;;;; +1CF8C;ZNAMENNY NEUME STATYA ZAKRYTAYA S ZAPYATOY;So;0;L;;;;;N;;;;; +1CF8D;ZNAMENNY NEUME STATYA S ROGOM;So;0;L;;;;;N;;;;; +1CF8E;ZNAMENNY NEUME STATYA S DVUMYA ZAPYATYMI;So;0;L;;;;;N;;;;; +1CF8F;ZNAMENNY NEUME STATYA S ZAPYATOY I PODCHASHIEM;So;0;L;;;;;N;;;;; +1CF90;ZNAMENNY NEUME POLKULIZMY;So;0;L;;;;;N;;;;; +1CF91;ZNAMENNY NEUME STATYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;; +1CF92;ZNAMENNY NEUME STRELA PROSTAYA;So;0;L;;;;;N;;;;; +1CF93;ZNAMENNY NEUME STRELA MRACHNOTIKHAYA;So;0;L;;;;;N;;;;; +1CF94;ZNAMENNY NEUME STRELA KRYZHEVAYA;So;0;L;;;;;N;;;;; +1CF95;ZNAMENNY NEUME STRELA POLUPOVODNAYA;So;0;L;;;;;N;;;;; +1CF96;ZNAMENNY NEUME STRELA POVODNAYA;So;0;L;;;;;N;;;;; +1CF97;ZNAMENNY NEUME STRELA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;; +1CF98;ZNAMENNY NEUME STRELA KLYUCHEPOVODNAYA;So;0;L;;;;;N;;;;; +1CF99;ZNAMENNY NEUME STRELA KLYUCHENEPOSTOYANNAYA;So;0;L;;;;;N;;;;; +1CF9A;ZNAMENNY NEUME STRELA TIKHAYA PUTNAYA;So;0;L;;;;;N;;;;; +1CF9B;ZNAMENNY NEUME STRELA DVOECHELNAYA;So;0;L;;;;;N;;;;; +1CF9C;ZNAMENNY NEUME STRELA DVOECHELNOKRYZHEVAYA;So;0;L;;;;;N;;;;; +1CF9D;ZNAMENNY NEUME STRELA DVOECHELNOPOVODNAYA;So;0;L;;;;;N;;;;; +1CF9E;ZNAMENNY NEUME STRELA DVOECHELNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;; +1CF9F;ZNAMENNY NEUME STRELA DVOECHELNOPOVODNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;; +1CFA0;ZNAMENNY NEUME STRELA GROMNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;; +1CFA1;ZNAMENNY NEUME STRELA GROMOPOVODNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;; +1CFA2;ZNAMENNY NEUME STRELA GROMNAYA;So;0;L;;;;;N;;;;; +1CFA3;ZNAMENNY NEUME STRELA GROMOPOVODNAYA;So;0;L;;;;;N;;;;; +1CFA4;ZNAMENNY NEUME STRELA GROMOPOVODNAYA WITH DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;; +1CFA5;ZNAMENNY NEUME STRELA GROMOKRYZHEVAYA;So;0;L;;;;;N;;;;; +1CFA6;ZNAMENNY NEUME STRELA GROMOKRYZHEVAYA POVODNAYA;So;0;L;;;;;N;;;;; +1CFA7;ZNAMENNY NEUME MECHIK;So;0;L;;;;;N;;;;; +1CFA8;ZNAMENNY NEUME MECHIK POVODNY;So;0;L;;;;;N;;;;; +1CFA9;ZNAMENNY NEUME MECHIK KLYUCHEVOY;So;0;L;;;;;N;;;;; +1CFAA;ZNAMENNY NEUME MECHIK KLYUCHEPOVODNY;So;0;L;;;;;N;;;;; +1CFAB;ZNAMENNY NEUME MECHIK KLYUCHENEPOSTOYANNY;So;0;L;;;;;N;;;;; +1CFAC;ZNAMENNY NEUME STRELA TRYASOGLASNAYA;So;0;L;;;;;N;;;;; +1CFAD;ZNAMENNY NEUME STRELA TRYASOPOVODNAYA;So;0;L;;;;;N;;;;; +1CFAE;ZNAMENNY NEUME STRELA TRYASOSTRELNAYA;So;0;L;;;;;N;;;;; +1CFAF;ZNAMENNY NEUME OSOKA;So;0;L;;;;;N;;;;; +1CFB0;ZNAMENNY NEUME OSOKA SVETLAYA;So;0;L;;;;;N;;;;; +1CFB1;ZNAMENNY NEUME OSOKA TRESVETLAYA;So;0;L;;;;;N;;;;; +1CFB2;ZNAMENNY NEUME OSOKA KRYUKOVAYA SVETLAYA;So;0;L;;;;;N;;;;; +1CFB3;ZNAMENNY NEUME OSOKA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;; +1CFB4;ZNAMENNY NEUME OSOKA KLYUCHEVAYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;; +1CFB5;ZNAMENNY NEUME STRELA KRYUKOVAYA;So;0;L;;;;;N;;;;; +1CFB6;ZNAMENNY NEUME STRELA KRYUKOVAYA POVODNAYA;So;0;L;;;;;N;;;;; +1CFB7;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;; +1CFB8;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;; +1CFB9;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMNAYA;So;0;L;;;;;N;;;;; +1CFBA;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA;So;0;L;;;;;N;;;;; +1CFBB;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA WITH DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;; +1CFBC;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOKRYZHEVAYA;So;0;L;;;;;N;;;;; +1CFBD;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOKRYZHEVAYA POVODNAYA;So;0;L;;;;;N;;;;; +1CFBE;ZNAMENNY NEUME STRELA KRYUKOVAYA TRYASKA;So;0;L;;;;;N;;;;; +1CFBF;ZNAMENNY NEUME KUFISMA;So;0;L;;;;;N;;;;; +1CFC0;ZNAMENNY NEUME OBLAKO;So;0;L;;;;;N;;;;; +1CFC1;ZNAMENNY NEUME DUDA;So;0;L;;;;;N;;;;; +1CFC2;ZNAMENNY NEUME NEMKA;So;0;L;;;;;N;;;;; +1CFC3;ZNAMENNY NEUME PAUK;So;0;L;;;;;N;;;;; 1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;; 1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;; 1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;; @@ -27801,6 +28501,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D1E6;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM DOWN;So;0;L;;;;;N;;;;; 1D1E7;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM UP;So;0;L;;;;;N;;;;; 1D1E8;MUSICAL SYMBOL KIEVAN FLAT SIGN;So;0;L;;;;;N;;;;; +1D1E9;MUSICAL SYMBOL SORI;So;0;ON;;;;;N;;;;; +1D1EA;MUSICAL SYMBOL KORON;So;0;ON;;;;;N;;;;; 1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;; 1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;; 1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;; @@ -29671,6 +30373,37 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1DAAD;SIGNWRITING ROTATION MODIFIER-14;Mn;0;NSM;;;;;N;;;;; 1DAAE;SIGNWRITING ROTATION MODIFIER-15;Mn;0;NSM;;;;;N;;;;; 1DAAF;SIGNWRITING ROTATION MODIFIER-16;Mn;0;NSM;;;;;N;;;;; +1DF00;LATIN SMALL LETTER FENG DIGRAPH WITH TRILL;Ll;0;L;;;;;N;;;;; +1DF01;LATIN SMALL LETTER REVERSED SCRIPT G;Ll;0;L;;;;;N;;;;; +1DF02;LATIN LETTER SMALL CAPITAL TURNED G;Ll;0;L;;;;;N;;;;; +1DF03;LATIN SMALL LETTER REVERSED K;Ll;0;L;;;;;N;;;;; +1DF04;LATIN LETTER SMALL CAPITAL L WITH BELT;Ll;0;L;;;;;N;;;;; +1DF05;LATIN SMALL LETTER LEZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1DF06;LATIN SMALL LETTER TURNED Y WITH BELT;Ll;0;L;;;;;N;;;;; +1DF07;LATIN SMALL LETTER REVERSED ENG;Ll;0;L;;;;;N;;;;; +1DF08;LATIN SMALL LETTER TURNED R WITH LONG LEG AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1DF09;LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1DF0A;LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK;Lo;0;L;;;;;N;;;;; +1DF0B;LATIN SMALL LETTER ESH WITH DOUBLE BAR;Ll;0;L;;;;;N;;;;; +1DF0C;LATIN SMALL LETTER ESH WITH DOUBLE BAR AND CURL;Ll;0;L;;;;;N;;;;; +1DF0D;LATIN SMALL LETTER TURNED T WITH CURL;Ll;0;L;;;;;N;;;;; +1DF0E;LATIN LETTER INVERTED GLOTTAL STOP WITH CURL;Ll;0;L;;;;;N;;;;; +1DF0F;LATIN LETTER STRETCHED C WITH CURL;Ll;0;L;;;;;N;;;;; +1DF10;LATIN LETTER SMALL CAPITAL TURNED K;Ll;0;L;;;;;N;;;;; +1DF11;LATIN SMALL LETTER L WITH FISHHOOK;Ll;0;L;;;;;N;;;;; +1DF12;LATIN SMALL LETTER DEZH DIGRAPH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1DF13;LATIN SMALL LETTER L WITH BELT AND PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1DF14;LATIN SMALL LETTER ENG WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1DF15;LATIN SMALL LETTER TURNED R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1DF16;LATIN SMALL LETTER R WITH FISHHOOK AND PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1DF17;LATIN SMALL LETTER TESH DIGRAPH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1DF18;LATIN SMALL LETTER EZH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1DF19;LATIN SMALL LETTER DEZH DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1DF1A;LATIN SMALL LETTER I WITH STROKE AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1DF1B;LATIN SMALL LETTER O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1DF1C;LATIN SMALL LETTER TESH DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1DF1D;LATIN SMALL LETTER C WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1DF1E;LATIN SMALL LETTER S WITH CURL;Ll;0;L;;;;;N;;;;; 1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;; 1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;; 1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;; @@ -29780,6 +30513,37 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E149;NYIAKENG PUACHUE HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 1E14E;NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ;Lo;0;L;;;;;N;;;;; 1E14F;NYIAKENG PUACHUE HMONG CIRCLED CA;So;0;L;;;;;N;;;;; +1E290;TOTO LETTER PA;Lo;0;L;;;;;N;;;;; +1E291;TOTO LETTER BA;Lo;0;L;;;;;N;;;;; +1E292;TOTO LETTER TA;Lo;0;L;;;;;N;;;;; +1E293;TOTO LETTER DA;Lo;0;L;;;;;N;;;;; +1E294;TOTO LETTER KA;Lo;0;L;;;;;N;;;;; +1E295;TOTO LETTER GA;Lo;0;L;;;;;N;;;;; +1E296;TOTO LETTER MA;Lo;0;L;;;;;N;;;;; +1E297;TOTO LETTER NA;Lo;0;L;;;;;N;;;;; +1E298;TOTO LETTER NGA;Lo;0;L;;;;;N;;;;; +1E299;TOTO LETTER SA;Lo;0;L;;;;;N;;;;; +1E29A;TOTO LETTER CHA;Lo;0;L;;;;;N;;;;; +1E29B;TOTO LETTER YA;Lo;0;L;;;;;N;;;;; +1E29C;TOTO LETTER WA;Lo;0;L;;;;;N;;;;; +1E29D;TOTO LETTER JA;Lo;0;L;;;;;N;;;;; +1E29E;TOTO LETTER HA;Lo;0;L;;;;;N;;;;; +1E29F;TOTO LETTER RA;Lo;0;L;;;;;N;;;;; +1E2A0;TOTO LETTER LA;Lo;0;L;;;;;N;;;;; +1E2A1;TOTO LETTER I;Lo;0;L;;;;;N;;;;; +1E2A2;TOTO LETTER BREATHY I;Lo;0;L;;;;;N;;;;; +1E2A3;TOTO LETTER IU;Lo;0;L;;;;;N;;;;; +1E2A4;TOTO LETTER BREATHY IU;Lo;0;L;;;;;N;;;;; +1E2A5;TOTO LETTER U;Lo;0;L;;;;;N;;;;; +1E2A6;TOTO LETTER E;Lo;0;L;;;;;N;;;;; +1E2A7;TOTO LETTER BREATHY E;Lo;0;L;;;;;N;;;;; +1E2A8;TOTO LETTER EO;Lo;0;L;;;;;N;;;;; +1E2A9;TOTO LETTER BREATHY EO;Lo;0;L;;;;;N;;;;; +1E2AA;TOTO LETTER O;Lo;0;L;;;;;N;;;;; +1E2AB;TOTO LETTER AE;Lo;0;L;;;;;N;;;;; +1E2AC;TOTO LETTER BREATHY AE;Lo;0;L;;;;;N;;;;; +1E2AD;TOTO LETTER A;Lo;0;L;;;;;N;;;;; +1E2AE;TOTO SIGN RISING TONE;Mn;230;NSM;;;;;N;;;;; 1E2C0;WANCHO LETTER AA;Lo;0;L;;;;;N;;;;; 1E2C1;WANCHO LETTER A;Lo;0;L;;;;;N;;;;; 1E2C2;WANCHO LETTER BA;Lo;0;L;;;;;N;;;;; @@ -29839,6 +30603,34 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;; +1E7E0;ETHIOPIC SYLLABLE HHYA;Lo;0;L;;;;;N;;;;; +1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;; +1E7E2;ETHIOPIC SYLLABLE HHYI;Lo;0;L;;;;;N;;;;; +1E7E3;ETHIOPIC SYLLABLE HHYAA;Lo;0;L;;;;;N;;;;; +1E7E4;ETHIOPIC SYLLABLE HHYEE;Lo;0;L;;;;;N;;;;; +1E7E5;ETHIOPIC SYLLABLE HHYE;Lo;0;L;;;;;N;;;;; +1E7E6;ETHIOPIC SYLLABLE HHYO;Lo;0;L;;;;;N;;;;; +1E7E8;ETHIOPIC SYLLABLE GURAGE HHWA;Lo;0;L;;;;;N;;;;; +1E7E9;ETHIOPIC SYLLABLE HHWI;Lo;0;L;;;;;N;;;;; +1E7EA;ETHIOPIC SYLLABLE HHWEE;Lo;0;L;;;;;N;;;;; +1E7EB;ETHIOPIC SYLLABLE HHWE;Lo;0;L;;;;;N;;;;; +1E7ED;ETHIOPIC SYLLABLE GURAGE MWI;Lo;0;L;;;;;N;;;;; +1E7EE;ETHIOPIC SYLLABLE GURAGE MWEE;Lo;0;L;;;;;N;;;;; +1E7F0;ETHIOPIC SYLLABLE GURAGE QWI;Lo;0;L;;;;;N;;;;; +1E7F1;ETHIOPIC SYLLABLE GURAGE QWEE;Lo;0;L;;;;;N;;;;; +1E7F2;ETHIOPIC SYLLABLE GURAGE QWE;Lo;0;L;;;;;N;;;;; +1E7F3;ETHIOPIC SYLLABLE GURAGE BWI;Lo;0;L;;;;;N;;;;; +1E7F4;ETHIOPIC SYLLABLE GURAGE BWEE;Lo;0;L;;;;;N;;;;; +1E7F5;ETHIOPIC SYLLABLE GURAGE KWI;Lo;0;L;;;;;N;;;;; +1E7F6;ETHIOPIC SYLLABLE GURAGE KWEE;Lo;0;L;;;;;N;;;;; +1E7F7;ETHIOPIC SYLLABLE GURAGE KWE;Lo;0;L;;;;;N;;;;; +1E7F8;ETHIOPIC SYLLABLE GURAGE GWI;Lo;0;L;;;;;N;;;;; +1E7F9;ETHIOPIC SYLLABLE GURAGE GWEE;Lo;0;L;;;;;N;;;;; +1E7FA;ETHIOPIC SYLLABLE GURAGE GWE;Lo;0;L;;;;;N;;;;; +1E7FB;ETHIOPIC SYLLABLE GURAGE FWI;Lo;0;L;;;;;N;;;;; +1E7FC;ETHIOPIC SYLLABLE GURAGE FWEE;Lo;0;L;;;;;N;;;;; +1E7FD;ETHIOPIC SYLLABLE GURAGE PWI;Lo;0;L;;;;;N;;;;; +1E7FE;ETHIOPIC SYLLABLE GURAGE PWEE;Lo;0;L;;;;;N;;;;; 1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;; 1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;; 1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;; @@ -31886,6 +32678,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;; 1F6D6;HUT;So;0;ON;;;;;N;;;;; 1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;; +1F6DD;PLAYGROUND SLIDE;So;0;ON;;;;;N;;;;; +1F6DE;WHEEL;So;0;ON;;;;;N;;;;; +1F6DF;RING BUOY;So;0;ON;;;;;N;;;;; 1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;; 1F6E1;SHIELD;So;0;ON;;;;;N;;;;; 1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;; @@ -32129,6 +32924,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F7E9;LARGE GREEN SQUARE;So;0;ON;;;;;N;;;;; 1F7EA;LARGE PURPLE SQUARE;So;0;ON;;;;;N;;;;; 1F7EB;LARGE BROWN SQUARE;So;0;ON;;;;;N;;;;; +1F7F0;HEAVY EQUALS SIGN;So;0;ON;;;;;N;;;;; 1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; 1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; 1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; @@ -32400,6 +33196,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F976;FREEZING FACE;So;0;ON;;;;;N;;;;; 1F977;NINJA;So;0;ON;;;;;N;;;;; 1F978;DISGUISED FACE;So;0;ON;;;;;N;;;;; +1F979;FACE HOLDING BACK TEARS;So;0;ON;;;;;N;;;;; 1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;; 1F97B;SARI;So;0;ON;;;;;N;;;;; 1F97C;LAB COAT;So;0;ON;;;;;N;;;;; @@ -32482,6 +33279,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;; 1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;; 1F9CB;BUBBLE TEA;So;0;ON;;;;;N;;;;; +1F9CC;TROLL;So;0;ON;;;;;N;;;;; 1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;; 1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;; 1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;; @@ -32639,6 +33437,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;; 1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;; 1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;; +1FA7B;X-RAY;So;0;ON;;;;;N;;;;; +1FA7C;CRUTCH;So;0;ON;;;;;N;;;;; 1FA80;YO-YO;So;0;ON;;;;;N;;;;; 1FA81;KITE;So;0;ON;;;;;N;;;;; 1FA82;PARACHUTE;So;0;ON;;;;;N;;;;; @@ -32671,6 +33471,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAA6;HEADSTONE;So;0;ON;;;;;N;;;;; 1FAA7;PLACARD;So;0;ON;;;;;N;;;;; 1FAA8;ROCK;So;0;ON;;;;;N;;;;; +1FAA9;MIRROR BALL;So;0;ON;;;;;N;;;;; +1FAAA;IDENTIFICATION CARD;So;0;ON;;;;;N;;;;; +1FAAB;LOW BATTERY;So;0;ON;;;;;N;;;;; +1FAAC;HAMSA;So;0;ON;;;;;N;;;;; 1FAB0;FLY;So;0;ON;;;;;N;;;;; 1FAB1;WORM;So;0;ON;;;;;N;;;;; 1FAB2;BEETLE;So;0;ON;;;;;N;;;;; @@ -32678,9 +33482,16 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAB4;POTTED PLANT;So;0;ON;;;;;N;;;;; 1FAB5;WOOD;So;0;ON;;;;;N;;;;; 1FAB6;FEATHER;So;0;ON;;;;;N;;;;; +1FAB7;LOTUS;So;0;ON;;;;;N;;;;; +1FAB8;CORAL;So;0;ON;;;;;N;;;;; +1FAB9;EMPTY NEST;So;0;ON;;;;;N;;;;; +1FABA;NEST WITH EGGS;So;0;ON;;;;;N;;;;; 1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;; 1FAC1;LUNGS;So;0;ON;;;;;N;;;;; 1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;; +1FAC3;PREGNANT MAN;So;0;ON;;;;;N;;;;; +1FAC4;PREGNANT PERSON;So;0;ON;;;;;N;;;;; +1FAC5;PERSON WITH CROWN;So;0;ON;;;;;N;;;;; 1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;; 1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;; 1FAD2;OLIVE;So;0;ON;;;;;N;;;;; @@ -32688,6 +33499,24 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAD4;TAMALE;So;0;ON;;;;;N;;;;; 1FAD5;FONDUE;So;0;ON;;;;;N;;;;; 1FAD6;TEAPOT;So;0;ON;;;;;N;;;;; +1FAD7;POURING LIQUID;So;0;ON;;;;;N;;;;; +1FAD8;BEANS;So;0;ON;;;;;N;;;;; +1FAD9;JAR;So;0;ON;;;;;N;;;;; +1FAE0;MELTING FACE;So;0;ON;;;;;N;;;;; +1FAE1;SALUTING FACE;So;0;ON;;;;;N;;;;; +1FAE2;FACE WITH OPEN EYES AND HAND OVER MOUTH;So;0;ON;;;;;N;;;;; +1FAE3;FACE WITH PEEKING EYE;So;0;ON;;;;;N;;;;; +1FAE4;FACE WITH DIAGONAL MOUTH;So;0;ON;;;;;N;;;;; +1FAE5;DOTTED LINE FACE;So;0;ON;;;;;N;;;;; +1FAE6;BITING LIP;So;0;ON;;;;;N;;;;; +1FAE7;BUBBLES;So;0;ON;;;;;N;;;;; +1FAF0;HAND WITH INDEX FINGER AND THUMB CROSSED;So;0;ON;;;;;N;;;;; +1FAF1;RIGHTWARDS HAND;So;0;ON;;;;;N;;;;; +1FAF2;LEFTWARDS HAND;So;0;ON;;;;;N;;;;; +1FAF3;PALM DOWN HAND;So;0;ON;;;;;N;;;;; +1FAF4;PALM UP HAND;So;0;ON;;;;;N;;;;; +1FAF5;INDEX POINTING AT THE VIEWER;So;0;ON;;;;;N;;;;; +1FAF6;HEART HANDS;So;0;ON;;;;;N;;;;; 1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;; 1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;; 1FB02;BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;; @@ -32901,9 +33730,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FBF8;SEGMENTED DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; 1FBF9;SEGMENTED DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; 20000;;Lo;0;L;;;;;N;;;;; -2A6DD;;Lo;0;L;;;;;N;;;;; +2A6DF;;Lo;0;L;;;;;N;;;;; 2A700;;Lo;0;L;;;;;N;;;;; -2B734;;Lo;0;L;;;;;N;;;;; +2B738;;Lo;0;L;;;;;N;;;;; 2B740;;Lo;0;L;;;;;N;;;;; 2B81D;;Lo;0;L;;;;;N;;;;; 2B820;;Lo;0;L;;;;;N;;;;; diff --git a/make/data/unicodedata/VERSION b/make/data/unicodedata/VERSION deleted file mode 100644 index 02161ca86e5e8ecad11b9b69fbb8b4564dae144f..0000000000000000000000000000000000000000 --- a/make/data/unicodedata/VERSION +++ /dev/null @@ -1 +0,0 @@ -13.0.0 diff --git a/make/data/unicodedata/auxiliary/GraphemeBreakProperty.txt b/make/data/unicodedata/auxiliary/GraphemeBreakProperty.txt index 504c708280200f701fe613035b2b42651f569362..15de396fdc12d20e8334559ce2550626badab6c8 100644 --- a/make/data/unicodedata/auxiliary/GraphemeBreakProperty.txt +++ b/make/data/unicodedata/auxiliary/GraphemeBreakProperty.txt @@ -1,6 +1,6 @@ -# GraphemeBreakProperty-13.0.0.txt -# Date: 2019-10-21, 14:30:35 GMT -# Copyright (c) 2019 Unicode, Inc. +# GraphemeBreakProperty-14.0.0.txt +# Date: 2021-08-12, 23:13:02 GMT +# Copyright (c) 2021 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -21,6 +21,7 @@ 0600..0605 ; Prepend # Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE 06DD ; Prepend # Cf ARABIC END OF AYAH 070F ; Prepend # Cf SYRIAC ABBREVIATION MARK +0890..0891 ; Prepend # Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE 08E2 ; Prepend # Cf ARABIC DISPUTED END OF AYAH 0D4E ; Prepend # Lo MALAYALAM LETTER DOT REPH 110BD ; Prepend # Cf KAITHI NUMBER SIGN @@ -32,7 +33,7 @@ 11A84..11A89 ; Prepend # Lo [6] SOYOMBO SIGN JIHVAMULIYA..SOYOMBO CLUSTER-INITIAL LETTER SA 11D46 ; Prepend # Lo MASARAM GONDI REPHA -# Total code points: 24 +# Total code points: 26 # ================================================ @@ -104,7 +105,8 @@ E01F0..E0FFF ; Control # Cn [3600] .. 0825..0827 ; Extend # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U 0829..082D ; Extend # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA 0859..085B ; Extend # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK -08D3..08E1 ; Extend # Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA +0898..089F ; Extend # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +08CA..08E1 ; Extend # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA 08E3..0902 ; Extend # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA 093A ; Extend # Mn DEVANAGARI VOWEL SIGN OE 093C ; Extend # Mn DEVANAGARI SIGN NUKTA @@ -151,6 +153,7 @@ E01F0..E0FFF ; Control # Cn [3600] .. 0BD7 ; Extend # Mc TAMIL AU LENGTH MARK 0C00 ; Extend # Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE 0C04 ; Extend # Mn TELUGU SIGN COMBINING ANUSVARA ABOVE +0C3C ; Extend # Mn TELUGU SIGN NUKTA 0C3E..0C40 ; Extend # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II 0C46..0C48 ; Extend # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI 0C4A..0C4D ; Extend # Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA @@ -206,7 +209,7 @@ E01F0..E0FFF ; Control # Cn [3600] .. 109D ; Extend # Mn MYANMAR VOWEL SIGN AITON AI 135D..135F ; Extend # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK 1712..1714 ; Extend # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA -1732..1734 ; Extend # Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD +1732..1733 ; Extend # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U 1752..1753 ; Extend # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U 1772..1773 ; Extend # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U 17B4..17B5 ; Extend # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA @@ -215,6 +218,7 @@ E01F0..E0FFF ; Control # Cn [3600] .. 17C9..17D3 ; Extend # Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT 17DD ; Extend # Mn KHMER SIGN ATTHACAN 180B..180D ; Extend # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE +180F ; Extend # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR 1885..1886 ; Extend # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA 18A9 ; Extend # Mn MONGOLIAN LETTER ALI GALI DAGALGA 1920..1922 ; Extend # Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U @@ -232,7 +236,7 @@ E01F0..E0FFF ; Control # Cn [3600] .. 1A7F ; Extend # Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT 1AB0..1ABD ; Extend # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW 1ABE ; Extend # Me COMBINING PARENTHESES OVERLAY -1ABF..1AC0 ; Extend # Mn [2] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER TURNED W BELOW +1ABF..1ACE ; Extend # Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T 1B00..1B03 ; Extend # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG 1B34 ; Extend # Mn BALINESE SIGN REREKAN 1B35 ; Extend # Mc BALINESE VOWEL SIGN TEDUNG @@ -256,8 +260,7 @@ E01F0..E0FFF ; Control # Cn [3600] .. 1CED ; Extend # Mn VEDIC SIGN TIRYAK 1CF4 ; Extend # Mn VEDIC TONE CANDRA ABOVE 1CF8..1CF9 ; Extend # Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE -1DC0..1DF9 ; Extend # Mn [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW -1DFB..1DFF ; Extend # Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW +1DC0..1DFF ; Extend # Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW 200C ; Extend # Cf ZERO WIDTH NON-JOINER 20D0..20DC ; Extend # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE 20DD..20E0 ; Extend # Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH @@ -322,11 +325,15 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 10D24..10D27 ; Extend # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI 10EAB..10EAC ; Extend # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK 10F46..10F50 ; Extend # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW +10F82..10F85 ; Extend # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW 11001 ; Extend # Mn BRAHMI SIGN ANUSVARA 11038..11046 ; Extend # Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA +11070 ; Extend # Mn BRAHMI SIGN OLD TAMIL VIRAMA +11073..11074 ; Extend # Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O 1107F..11081 ; Extend # Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA 110B3..110B6 ; Extend # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI 110B9..110BA ; Extend # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA +110C2 ; Extend # Mn KAITHI VOWEL SIGN VOCALIC R 11100..11102 ; Extend # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA 11127..1112B ; Extend # Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU 1112D..11134 ; Extend # Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA @@ -412,6 +419,8 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 16F8F..16F92 ; Extend # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW 16FE4 ; Extend # Mn KHITAN SMALL SCRIPT FILLER 1BC9D..1BC9E ; Extend # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK +1CF00..1CF2D ; Extend # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT +1CF30..1CF46 ; Extend # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG 1D165 ; Extend # Mc MUSICAL SYMBOL COMBINING STEM 1D167..1D169 ; Extend # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 1D16E..1D172 ; Extend # Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 @@ -431,6 +440,7 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 1E023..1E024 ; Extend # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS 1E026..1E02A ; Extend # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA 1E130..1E136 ; Extend # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D +1E2AE ; Extend # Mn TOTO SIGN RISING TONE 1E2EC..1E2EF ; Extend # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E8D0..1E8D6 ; Extend # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E94A ; Extend # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA @@ -438,7 +448,7 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT E0020..E007F ; Extend # Cf [96] TAG SPACE..CANCEL TAG E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 1984 +# Total code points: 2095 # ================================================ @@ -495,6 +505,8 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 103B..103C ; SpacingMark # Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA 1056..1057 ; SpacingMark # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR 1084 ; SpacingMark # Mc MYANMAR VOWEL SIGN SHAN E +1715 ; SpacingMark # Mc TAGALOG SIGN PAMUDPOD +1734 ; SpacingMark # Mc HANUNOO SIGN PAMUDPOD 17B6 ; SpacingMark # Mc KHMER VOWEL SIGN AA 17BE..17C5 ; SpacingMark # Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU 17C7..17C8 ; SpacingMark # Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU @@ -579,7 +591,6 @@ ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK 116AC ; SpacingMark # Mc TAKRI SIGN VISARGA 116AE..116AF ; SpacingMark # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II 116B6 ; SpacingMark # Mc TAKRI SIGN VIRAMA -11720..11721 ; SpacingMark # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA 11726 ; SpacingMark # Mc AHOM VOWEL SIGN E 1182C..1182E ; SpacingMark # Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II 11838 ; SpacingMark # Mc DOGRA SIGN VISARGA diff --git a/make/data/unicodedata/auxiliary/GraphemeBreakTest.txt b/make/data/unicodedata/auxiliary/GraphemeBreakTest.txt index e3cd8806ceb398fcc93b7ba149692d271dde7ca5..6bb1fe98b5adc43aca70b892eff402f14be75314 100644 --- a/make/data/unicodedata/auxiliary/GraphemeBreakTest.txt +++ b/make/data/unicodedata/auxiliary/GraphemeBreakTest.txt @@ -1,6 +1,6 @@ -# GraphemeBreakTest-13.0.0.txt -# Date: 2019-11-15, 19:49:10 GMT -# Copyright (c) 2019 Unicode, Inc. +# GraphemeBreakTest-14.0.0.txt +# Date: 2021-03-08, 06:22:32 GMT +# Copyright (c) 2021 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # diff --git a/make/data/unicodedata/emoji/emoji-data.txt b/make/data/unicodedata/emoji/emoji-data.txt index a01213299b71085835d7690e0d37f6c04e1ad1a3..a35d434df220dcd1f62415a79228b4d14e966b7c 100644 --- a/make/data/unicodedata/emoji/emoji-data.txt +++ b/make/data/unicodedata/emoji/emoji-data.txt @@ -1,11 +1,11 @@ -# emoji-data.txt -# Date: 2020-01-28, 20:52:38 GMT -# Copyright (c) 2020 Unicode, Inc. +# emoji-data-14.0.0.txt +# Date: 2021-08-26, 17:22:22 GMT +# Copyright (c) 2021 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # # Emoji Data for UTS #51 -# Version: 13.0 +# Used with Emoji Version 14.0 and subsequent minor revisions (if any) # # For documentation and usage, see http://www.unicode.org/reports/tr51 # @@ -22,7 +22,7 @@ # All omitted code points have Emoji=No # @missing: 0000..10FFFF ; Emoji ; No -0023 ; Emoji # E0.0 [1] (#️) number sign +0023 ; Emoji # E0.0 [1] (#️) hash sign 002A ; Emoji # E0.0 [1] (*️) asterisk 0030..0039 ; Emoji # E0.0 [10] (0️..9️) digit zero..digit nine 00A9 ; Emoji # E0.6 [1] (©️) copyright @@ -119,8 +119,8 @@ 2747 ; Emoji # E0.6 [1] (❇️) sparkle 274C ; Emoji # E0.6 [1] (❌) cross mark 274E ; Emoji # E0.6 [1] (❎) cross mark button -2753..2755 ; Emoji # E0.6 [3] (❓..❕) question mark..white exclamation mark -2757 ; Emoji # E0.6 [1] (❗) exclamation mark +2753..2755 ; Emoji # E0.6 [3] (❓..❕) red question mark..white exclamation mark +2757 ; Emoji # E0.6 [1] (❗) red exclamation mark 2763 ; Emoji # E1.0 [1] (❣️) heart exclamation 2764 ; Emoji # E0.6 [1] (❤️) red heart 2795..2797 ; Emoji # E0.6 [3] (➕..➗) plus..divide @@ -239,7 +239,7 @@ 1F509 ; Emoji # E1.0 [1] (🔉) speaker medium volume 1F50A..1F514 ; Emoji # E0.6 [11] (🔊..🔔) speaker high volume..bell 1F515 ; Emoji # E1.0 [1] (🔕) bell with slash -1F516..1F52B ; Emoji # E0.6 [22] (🔖..🔫) bookmark..pistol +1F516..1F52B ; Emoji # E0.6 [22] (🔖..🔫) bookmark..water pistol 1F52C..1F52D ; Emoji # E1.0 [2] (🔬..🔭) microscope..telescope 1F52E..1F53D ; Emoji # E0.6 [16] (🔮..🔽) crystal ball..downwards button 1F549..1F54A ; Emoji # E0.7 [2] (🕉️..🕊️) om..dove @@ -294,7 +294,7 @@ 1F62E..1F62F ; Emoji # E1.0 [2] (😮..😯) face with open mouth..hushed face 1F630..1F633 ; Emoji # E0.6 [4] (😰..😳) anxious face with sweat..flushed face 1F634 ; Emoji # E1.0 [1] (😴) sleeping face -1F635 ; Emoji # E0.6 [1] (😵) dizzy face +1F635 ; Emoji # E0.6 [1] (😵) face with crossed-out eyes 1F636 ; Emoji # E1.0 [1] (😶) face without mouth 1F637..1F640 ; Emoji # E0.6 [10] (😷..🙀) face with medical mask..weary cat 1F641..1F644 ; Emoji # E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes @@ -341,6 +341,7 @@ 1F6D1..1F6D2 ; Emoji # E3.0 [2] (🛑..🛒) stop sign..shopping cart 1F6D5 ; Emoji # E12.0 [1] (🛕) hindu temple 1F6D6..1F6D7 ; Emoji # E13.0 [2] (🛖..🛗) hut..elevator +1F6DD..1F6DF ; Emoji # E14.0 [3] (🛝..🛟) playground slide..ring buoy 1F6E0..1F6E5 ; Emoji # E0.7 [6] (🛠️..🛥️) hammer and wrench..motor boat 1F6E9 ; Emoji # E0.7 [1] (🛩️) small airplane 1F6EB..1F6EC ; Emoji # E1.0 [2] (🛫..🛬) airplane departure..airplane arrival @@ -352,6 +353,7 @@ 1F6FA ; Emoji # E12.0 [1] (🛺) auto rickshaw 1F6FB..1F6FC ; Emoji # E13.0 [2] (🛻..🛼) pickup truck..roller skate 1F7E0..1F7EB ; Emoji # E12.0 [12] (🟠..🟫) orange circle..brown square +1F7F0 ; Emoji # E14.0 [1] (🟰) heavy equals sign 1F90C ; Emoji # E13.0 [1] (🤌) pinched fingers 1F90D..1F90F ; Emoji # E12.0 [3] (🤍..🤏) white heart..pinching hand 1F910..1F918 ; Emoji # E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns @@ -375,6 +377,7 @@ 1F972 ; Emoji # E13.0 [1] (🥲) smiling face with tear 1F973..1F976 ; Emoji # E11.0 [4] (🥳..🥶) partying face..cold face 1F977..1F978 ; Emoji # E13.0 [2] (🥷..🥸) ninja..disguised face +1F979 ; Emoji # E14.0 [1] (🥹) face holding back tears 1F97A ; Emoji # E11.0 [1] (🥺) pleading face 1F97B ; Emoji # E12.0 [1] (🥻) sari 1F97C..1F97F ; Emoji # E11.0 [4] (🥼..🥿) lab coat..flat shoe @@ -392,21 +395,29 @@ 1F9C1..1F9C2 ; Emoji # E11.0 [2] (🧁..🧂) cupcake..salt 1F9C3..1F9CA ; Emoji # E12.0 [8] (🧃..🧊) beverage box..ice 1F9CB ; Emoji # E13.0 [1] (🧋) bubble tea +1F9CC ; Emoji # E14.0 [1] (🧌) troll 1F9CD..1F9CF ; Emoji # E12.0 [3] (🧍..🧏) person standing..deaf person 1F9D0..1F9E6 ; Emoji # E5.0 [23] (🧐..🧦) face with monocle..socks 1F9E7..1F9FF ; Emoji # E11.0 [25] (🧧..🧿) red envelope..nazar amulet 1FA70..1FA73 ; Emoji # E12.0 [4] (🩰..🩳) ballet shoes..shorts 1FA74 ; Emoji # E13.0 [1] (🩴) thong sandal 1FA78..1FA7A ; Emoji # E12.0 [3] (🩸..🩺) drop of blood..stethoscope +1FA7B..1FA7C ; Emoji # E14.0 [2] (🩻..🩼) x-ray..crutch 1FA80..1FA82 ; Emoji # E12.0 [3] (🪀..🪂) yo-yo..parachute 1FA83..1FA86 ; Emoji # E13.0 [4] (🪃..🪆) boomerang..nesting dolls 1FA90..1FA95 ; Emoji # E12.0 [6] (🪐..🪕) ringed planet..banjo 1FA96..1FAA8 ; Emoji # E13.0 [19] (🪖..🪨) military helmet..rock +1FAA9..1FAAC ; Emoji # E14.0 [4] (🪩..🪬) mirror ball..hamsa 1FAB0..1FAB6 ; Emoji # E13.0 [7] (🪰..🪶) fly..feather +1FAB7..1FABA ; Emoji # E14.0 [4] (🪷..🪺) lotus..nest with eggs 1FAC0..1FAC2 ; Emoji # E13.0 [3] (🫀..🫂) anatomical heart..people hugging +1FAC3..1FAC5 ; Emoji # E14.0 [3] (🫃..🫅) pregnant man..person with crown 1FAD0..1FAD6 ; Emoji # E13.0 [7] (🫐..🫖) blueberries..teapot +1FAD7..1FAD9 ; Emoji # E14.0 [3] (🫗..🫙) pouring liquid..jar +1FAE0..1FAE7 ; Emoji # E14.0 [8] (🫠..🫧) melting face..bubbles +1FAF0..1FAF6 ; Emoji # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands -# Total elements: 1367 +# Total elements: 1404 # ================================================ @@ -438,8 +449,8 @@ 2728 ; Emoji_Presentation # E0.6 [1] (✨) sparkles 274C ; Emoji_Presentation # E0.6 [1] (❌) cross mark 274E ; Emoji_Presentation # E0.6 [1] (❎) cross mark button -2753..2755 ; Emoji_Presentation # E0.6 [3] (❓..❕) question mark..white exclamation mark -2757 ; Emoji_Presentation # E0.6 [1] (❗) exclamation mark +2753..2755 ; Emoji_Presentation # E0.6 [3] (❓..❕) red question mark..white exclamation mark +2757 ; Emoji_Presentation # E0.6 [1] (❗) red exclamation mark 2795..2797 ; Emoji_Presentation # E0.6 [3] (➕..➗) plus..divide 27B0 ; Emoji_Presentation # E0.6 [1] (➰) curly loop 27BF ; Emoji_Presentation # E1.0 [1] (➿) double curly loop @@ -533,7 +544,7 @@ 1F509 ; Emoji_Presentation # E1.0 [1] (🔉) speaker medium volume 1F50A..1F514 ; Emoji_Presentation # E0.6 [11] (🔊..🔔) speaker high volume..bell 1F515 ; Emoji_Presentation # E1.0 [1] (🔕) bell with slash -1F516..1F52B ; Emoji_Presentation # E0.6 [22] (🔖..🔫) bookmark..pistol +1F516..1F52B ; Emoji_Presentation # E0.6 [22] (🔖..🔫) bookmark..water pistol 1F52C..1F52D ; Emoji_Presentation # E1.0 [2] (🔬..🔭) microscope..telescope 1F52E..1F53D ; Emoji_Presentation # E0.6 [16] (🔮..🔽) crystal ball..downwards button 1F54B..1F54E ; Emoji_Presentation # E1.0 [4] (🕋..🕎) kaaba..menorah @@ -569,7 +580,7 @@ 1F62E..1F62F ; Emoji_Presentation # E1.0 [2] (😮..😯) face with open mouth..hushed face 1F630..1F633 ; Emoji_Presentation # E0.6 [4] (😰..😳) anxious face with sweat..flushed face 1F634 ; Emoji_Presentation # E1.0 [1] (😴) sleeping face -1F635 ; Emoji_Presentation # E0.6 [1] (😵) dizzy face +1F635 ; Emoji_Presentation # E0.6 [1] (😵) face with crossed-out eyes 1F636 ; Emoji_Presentation # E1.0 [1] (😶) face without mouth 1F637..1F640 ; Emoji_Presentation # E0.6 [10] (😷..🙀) face with medical mask..weary cat 1F641..1F644 ; Emoji_Presentation # E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes @@ -614,6 +625,7 @@ 1F6D1..1F6D2 ; Emoji_Presentation # E3.0 [2] (🛑..🛒) stop sign..shopping cart 1F6D5 ; Emoji_Presentation # E12.0 [1] (🛕) hindu temple 1F6D6..1F6D7 ; Emoji_Presentation # E13.0 [2] (🛖..🛗) hut..elevator +1F6DD..1F6DF ; Emoji_Presentation # E14.0 [3] (🛝..🛟) playground slide..ring buoy 1F6EB..1F6EC ; Emoji_Presentation # E1.0 [2] (🛫..🛬) airplane departure..airplane arrival 1F6F4..1F6F6 ; Emoji_Presentation # E3.0 [3] (🛴..🛶) kick scooter..canoe 1F6F7..1F6F8 ; Emoji_Presentation # E5.0 [2] (🛷..🛸) sled..flying saucer @@ -621,6 +633,7 @@ 1F6FA ; Emoji_Presentation # E12.0 [1] (🛺) auto rickshaw 1F6FB..1F6FC ; Emoji_Presentation # E13.0 [2] (🛻..🛼) pickup truck..roller skate 1F7E0..1F7EB ; Emoji_Presentation # E12.0 [12] (🟠..🟫) orange circle..brown square +1F7F0 ; Emoji_Presentation # E14.0 [1] (🟰) heavy equals sign 1F90C ; Emoji_Presentation # E13.0 [1] (🤌) pinched fingers 1F90D..1F90F ; Emoji_Presentation # E12.0 [3] (🤍..🤏) white heart..pinching hand 1F910..1F918 ; Emoji_Presentation # E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns @@ -644,6 +657,7 @@ 1F972 ; Emoji_Presentation # E13.0 [1] (🥲) smiling face with tear 1F973..1F976 ; Emoji_Presentation # E11.0 [4] (🥳..🥶) partying face..cold face 1F977..1F978 ; Emoji_Presentation # E13.0 [2] (🥷..🥸) ninja..disguised face +1F979 ; Emoji_Presentation # E14.0 [1] (🥹) face holding back tears 1F97A ; Emoji_Presentation # E11.0 [1] (🥺) pleading face 1F97B ; Emoji_Presentation # E12.0 [1] (🥻) sari 1F97C..1F97F ; Emoji_Presentation # E11.0 [4] (🥼..🥿) lab coat..flat shoe @@ -661,21 +675,29 @@ 1F9C1..1F9C2 ; Emoji_Presentation # E11.0 [2] (🧁..🧂) cupcake..salt 1F9C3..1F9CA ; Emoji_Presentation # E12.0 [8] (🧃..🧊) beverage box..ice 1F9CB ; Emoji_Presentation # E13.0 [1] (🧋) bubble tea +1F9CC ; Emoji_Presentation # E14.0 [1] (🧌) troll 1F9CD..1F9CF ; Emoji_Presentation # E12.0 [3] (🧍..🧏) person standing..deaf person 1F9D0..1F9E6 ; Emoji_Presentation # E5.0 [23] (🧐..🧦) face with monocle..socks 1F9E7..1F9FF ; Emoji_Presentation # E11.0 [25] (🧧..🧿) red envelope..nazar amulet 1FA70..1FA73 ; Emoji_Presentation # E12.0 [4] (🩰..🩳) ballet shoes..shorts 1FA74 ; Emoji_Presentation # E13.0 [1] (🩴) thong sandal 1FA78..1FA7A ; Emoji_Presentation # E12.0 [3] (🩸..🩺) drop of blood..stethoscope +1FA7B..1FA7C ; Emoji_Presentation # E14.0 [2] (🩻..🩼) x-ray..crutch 1FA80..1FA82 ; Emoji_Presentation # E12.0 [3] (🪀..🪂) yo-yo..parachute 1FA83..1FA86 ; Emoji_Presentation # E13.0 [4] (🪃..🪆) boomerang..nesting dolls 1FA90..1FA95 ; Emoji_Presentation # E12.0 [6] (🪐..🪕) ringed planet..banjo 1FA96..1FAA8 ; Emoji_Presentation # E13.0 [19] (🪖..🪨) military helmet..rock +1FAA9..1FAAC ; Emoji_Presentation # E14.0 [4] (🪩..🪬) mirror ball..hamsa 1FAB0..1FAB6 ; Emoji_Presentation # E13.0 [7] (🪰..🪶) fly..feather +1FAB7..1FABA ; Emoji_Presentation # E14.0 [4] (🪷..🪺) lotus..nest with eggs 1FAC0..1FAC2 ; Emoji_Presentation # E13.0 [3] (🫀..🫂) anatomical heart..people hugging +1FAC3..1FAC5 ; Emoji_Presentation # E14.0 [3] (🫃..🫅) pregnant man..person with crown 1FAD0..1FAD6 ; Emoji_Presentation # E13.0 [7] (🫐..🫖) blueberries..teapot +1FAD7..1FAD9 ; Emoji_Presentation # E14.0 [3] (🫗..🫙) pouring liquid..jar +1FAE0..1FAE7 ; Emoji_Presentation # E14.0 [8] (🫠..🫧) melting face..bubbles +1FAF0..1FAF6 ; Emoji_Presentation # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands -# Total elements: 1148 +# Total elements: 1185 # ================================================ @@ -738,15 +760,17 @@ 1F9BB ; Emoji_Modifier_Base # E12.0 [1] (🦻) ear with hearing aid 1F9CD..1F9CF ; Emoji_Modifier_Base # E12.0 [3] (🧍..🧏) person standing..deaf person 1F9D1..1F9DD ; Emoji_Modifier_Base # E5.0 [13] (🧑..🧝) person..elf +1FAC3..1FAC5 ; Emoji_Modifier_Base # E14.0 [3] (🫃..🫅) pregnant man..person with crown +1FAF0..1FAF6 ; Emoji_Modifier_Base # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands -# Total elements: 122 +# Total elements: 132 # ================================================ # All omitted code points have Emoji_Component=No # @missing: 0000..10FFFF ; Emoji_Component ; No -0023 ; Emoji_Component # E0.0 [1] (#️) number sign +0023 ; Emoji_Component # E0.0 [1] (#️) hash sign 002A ; Emoji_Component # E0.0 [1] (*️) asterisk 0030..0039 ; Emoji_Component # E0.0 [10] (0️..9️) digit zero..digit nine 200D ; Emoji_Component # E0.0 [1] (‍) zero width joiner @@ -902,8 +926,8 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 2747 ; Extended_Pictographic# E0.6 [1] (❇️) sparkle 274C ; Extended_Pictographic# E0.6 [1] (❌) cross mark 274E ; Extended_Pictographic# E0.6 [1] (❎) cross mark button -2753..2755 ; Extended_Pictographic# E0.6 [3] (❓..❕) question mark..white exclamation mark -2757 ; Extended_Pictographic# E0.6 [1] (❗) exclamation mark +2753..2755 ; Extended_Pictographic# E0.6 [3] (❓..❕) red question mark..white exclamation mark +2757 ; Extended_Pictographic# E0.6 [1] (❗) red exclamation mark 2763 ; Extended_Pictographic# E1.0 [1] (❣️) heart exclamation 2764 ; Extended_Pictographic# E0.6 [1] (❤️) red heart 2765..2767 ; Extended_Pictographic# E0.0 [3] (❥..❧) ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET @@ -1041,7 +1065,7 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1F509 ; Extended_Pictographic# E1.0 [1] (🔉) speaker medium volume 1F50A..1F514 ; Extended_Pictographic# E0.6 [11] (🔊..🔔) speaker high volume..bell 1F515 ; Extended_Pictographic# E1.0 [1] (🔕) bell with slash -1F516..1F52B ; Extended_Pictographic# E0.6 [22] (🔖..🔫) bookmark..pistol +1F516..1F52B ; Extended_Pictographic# E0.6 [22] (🔖..🔫) bookmark..water pistol 1F52C..1F52D ; Extended_Pictographic# E1.0 [2] (🔬..🔭) microscope..telescope 1F52E..1F53D ; Extended_Pictographic# E0.6 [16] (🔮..🔽) crystal ball..downwards button 1F546..1F548 ; Extended_Pictographic# E0.0 [3] (🕆..🕈) WHITE LATIN CROSS..CELTIC CROSS @@ -1117,7 +1141,7 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1F62E..1F62F ; Extended_Pictographic# E1.0 [2] (😮..😯) face with open mouth..hushed face 1F630..1F633 ; Extended_Pictographic# E0.6 [4] (😰..😳) anxious face with sweat..flushed face 1F634 ; Extended_Pictographic# E1.0 [1] (😴) sleeping face -1F635 ; Extended_Pictographic# E0.6 [1] (😵) dizzy face +1F635 ; Extended_Pictographic# E0.6 [1] (😵) face with crossed-out eyes 1F636 ; Extended_Pictographic# E1.0 [1] (😶) face without mouth 1F637..1F640 ; Extended_Pictographic# E0.6 [10] (😷..🙀) face with medical mask..weary cat 1F641..1F644 ; Extended_Pictographic# E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes @@ -1166,7 +1190,8 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1F6D3..1F6D4 ; Extended_Pictographic# E0.0 [2] (🛓..🛔) STUPA..PAGODA 1F6D5 ; Extended_Pictographic# E12.0 [1] (🛕) hindu temple 1F6D6..1F6D7 ; Extended_Pictographic# E13.0 [2] (🛖..🛗) hut..elevator -1F6D8..1F6DF ; Extended_Pictographic# E0.0 [8] (🛘..🛟) .. +1F6D8..1F6DC ; Extended_Pictographic# E0.0 [5] (🛘..🛜) .. +1F6DD..1F6DF ; Extended_Pictographic# E14.0 [3] (🛝..🛟) playground slide..ring buoy 1F6E0..1F6E5 ; Extended_Pictographic# E0.7 [6] (🛠️..🛥️) hammer and wrench..motor boat 1F6E6..1F6E8 ; Extended_Pictographic# E0.0 [3] (🛦..🛨) UP-POINTING MILITARY AIRPLANE..UP-POINTING SMALL AIRPLANE 1F6E9 ; Extended_Pictographic# E0.7 [1] (🛩️) small airplane @@ -1185,7 +1210,9 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1F774..1F77F ; Extended_Pictographic# E0.0 [12] (🝴..🝿) .. 1F7D5..1F7DF ; Extended_Pictographic# E0.0 [11] (🟕..🟟) CIRCLED TRIANGLE.. 1F7E0..1F7EB ; Extended_Pictographic# E12.0 [12] (🟠..🟫) orange circle..brown square -1F7EC..1F7FF ; Extended_Pictographic# E0.0 [20] (🟬..🟿) .. +1F7EC..1F7EF ; Extended_Pictographic# E0.0 [4] (🟬..🟯) .. +1F7F0 ; Extended_Pictographic# E14.0 [1] (🟰) heavy equals sign +1F7F1..1F7FF ; Extended_Pictographic# E0.0 [15] (🟱..🟿) .. 1F80C..1F80F ; Extended_Pictographic# E0.0 [4] (🠌..🠏) .. 1F848..1F84F ; Extended_Pictographic# E0.0 [8] (🡈..🡏) .. 1F85A..1F85F ; Extended_Pictographic# E0.0 [6] (🡚..🡟) .. @@ -1214,7 +1241,7 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1F972 ; Extended_Pictographic# E13.0 [1] (🥲) smiling face with tear 1F973..1F976 ; Extended_Pictographic# E11.0 [4] (🥳..🥶) partying face..cold face 1F977..1F978 ; Extended_Pictographic# E13.0 [2] (🥷..🥸) ninja..disguised face -1F979 ; Extended_Pictographic# E0.0 [1] (🥹) +1F979 ; Extended_Pictographic# E14.0 [1] (🥹) face holding back tears 1F97A ; Extended_Pictographic# E11.0 [1] (🥺) pleading face 1F97B ; Extended_Pictographic# E12.0 [1] (🥻) sari 1F97C..1F97F ; Extended_Pictographic# E11.0 [4] (🥼..🥿) lab coat..flat shoe @@ -1232,7 +1259,7 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1F9C1..1F9C2 ; Extended_Pictographic# E11.0 [2] (🧁..🧂) cupcake..salt 1F9C3..1F9CA ; Extended_Pictographic# E12.0 [8] (🧃..🧊) beverage box..ice 1F9CB ; Extended_Pictographic# E13.0 [1] (🧋) bubble tea -1F9CC ; Extended_Pictographic# E0.0 [1] (🧌) +1F9CC ; Extended_Pictographic# E14.0 [1] (🧌) troll 1F9CD..1F9CF ; Extended_Pictographic# E12.0 [3] (🧍..🧏) person standing..deaf person 1F9D0..1F9E6 ; Extended_Pictographic# E5.0 [23] (🧐..🧦) face with monocle..socks 1F9E7..1F9FF ; Extended_Pictographic# E11.0 [25] (🧧..🧿) red envelope..nazar amulet @@ -1241,19 +1268,28 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1FA74 ; Extended_Pictographic# E13.0 [1] (🩴) thong sandal 1FA75..1FA77 ; Extended_Pictographic# E0.0 [3] (🩵..🩷) .. 1FA78..1FA7A ; Extended_Pictographic# E12.0 [3] (🩸..🩺) drop of blood..stethoscope -1FA7B..1FA7F ; Extended_Pictographic# E0.0 [5] (🩻..🩿) .. +1FA7B..1FA7C ; Extended_Pictographic# E14.0 [2] (🩻..🩼) x-ray..crutch +1FA7D..1FA7F ; Extended_Pictographic# E0.0 [3] (🩽..🩿) .. 1FA80..1FA82 ; Extended_Pictographic# E12.0 [3] (🪀..🪂) yo-yo..parachute 1FA83..1FA86 ; Extended_Pictographic# E13.0 [4] (🪃..🪆) boomerang..nesting dolls 1FA87..1FA8F ; Extended_Pictographic# E0.0 [9] (🪇..🪏) .. 1FA90..1FA95 ; Extended_Pictographic# E12.0 [6] (🪐..🪕) ringed planet..banjo 1FA96..1FAA8 ; Extended_Pictographic# E13.0 [19] (🪖..🪨) military helmet..rock -1FAA9..1FAAF ; Extended_Pictographic# E0.0 [7] (🪩..🪯) .. +1FAA9..1FAAC ; Extended_Pictographic# E14.0 [4] (🪩..🪬) mirror ball..hamsa +1FAAD..1FAAF ; Extended_Pictographic# E0.0 [3] (🪭..🪯) .. 1FAB0..1FAB6 ; Extended_Pictographic# E13.0 [7] (🪰..🪶) fly..feather -1FAB7..1FABF ; Extended_Pictographic# E0.0 [9] (🪷..🪿) .. +1FAB7..1FABA ; Extended_Pictographic# E14.0 [4] (🪷..🪺) lotus..nest with eggs +1FABB..1FABF ; Extended_Pictographic# E0.0 [5] (🪻..🪿) .. 1FAC0..1FAC2 ; Extended_Pictographic# E13.0 [3] (🫀..🫂) anatomical heart..people hugging -1FAC3..1FACF ; Extended_Pictographic# E0.0 [13] (🫃..🫏) .. +1FAC3..1FAC5 ; Extended_Pictographic# E14.0 [3] (🫃..🫅) pregnant man..person with crown +1FAC6..1FACF ; Extended_Pictographic# E0.0 [10] (🫆..🫏) .. 1FAD0..1FAD6 ; Extended_Pictographic# E13.0 [7] (🫐..🫖) blueberries..teapot -1FAD7..1FAFF ; Extended_Pictographic# E0.0 [41] (🫗..🫿) .. +1FAD7..1FAD9 ; Extended_Pictographic# E14.0 [3] (🫗..🫙) pouring liquid..jar +1FADA..1FADF ; Extended_Pictographic# E0.0 [6] (🫚..🫟) .. +1FAE0..1FAE7 ; Extended_Pictographic# E14.0 [8] (🫠..🫧) melting face..bubbles +1FAE8..1FAEF ; Extended_Pictographic# E0.0 [8] (🫨..🫯) .. +1FAF0..1FAF6 ; Extended_Pictographic# E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands +1FAF7..1FAFF ; Extended_Pictographic# E0.0 [9] (🫷..🫿) .. 1FC00..1FFFD ; Extended_Pictographic# E0.0[1022] (🰀..🿽) .. # Total elements: 3537 diff --git a/make/devkit/createJMHBundle.sh b/make/devkit/createJMHBundle.sh index d34c9939ff07b58d90dcd6f50dee1ef9d733c3fc..059fb7acb6fb9fdb5722b6b288bee40d8421169a 100644 --- a/make/devkit/createJMHBundle.sh +++ b/make/devkit/createJMHBundle.sh @@ -26,7 +26,7 @@ # Create a bundle in the build directory, containing what's needed to # build and run JMH microbenchmarks from the OpenJDK build. -JMH_VERSION=1.33 +JMH_VERSION=1.34 COMMONS_MATH3_VERSION=3.2 JOPT_SIMPLE_VERSION=4.6 diff --git a/make/hotspot/lib/JvmFeatures.gmk b/make/hotspot/lib/JvmFeatures.gmk index ab555f9d82d4e7cb01e271fa0807c7673a544293..07ce6feaf6f692cbfcc70c7a903f04b73e9b066a 100644 --- a/make/hotspot/lib/JvmFeatures.gmk +++ b/make/hotspot/lib/JvmFeatures.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -130,13 +130,6 @@ ifneq ($(call check-jvm-feature, cds), true) JVM_EXCLUDE_PATTERNS += cds/ endif -ifneq ($(call check-jvm-feature, nmt), true) - JVM_CFLAGS_FEATURES += -DINCLUDE_NMT=0 - JVM_EXCLUDE_FILES += \ - memBaseline.cpp memReporter.cpp mallocTracker.cpp virtualMemoryTracker.cpp nmtCommon.cpp \ - memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp threadStackTracker.cpp -endif - ifneq ($(call check-jvm-feature, g1gc), true) JVM_CFLAGS_FEATURES += -DINCLUDE_G1GC=0 JVM_EXCLUDE_PATTERNS += gc/g1 diff --git a/make/ide/vscode/hotspot/CreateVSCodeProject.gmk b/make/ide/vscode/hotspot/CreateVSCodeProject.gmk index 8b82c38a7518e2ef866e50cb81ce65d27d63a310..bc56e878de6f34add01103c1e0570d136fa85fba 100644 --- a/make/ide/vscode/hotspot/CreateVSCodeProject.gmk +++ b/make/ide/vscode/hotspot/CreateVSCodeProject.gmk @@ -29,6 +29,13 @@ default: all include $(SPEC) include MakeBase.gmk +################################################################################ +# SedEscape +# +# Escape special characters for use in SED replacement string +################################################################################ +SedEscape = $(subst !,\!,$(subst \,\\,$1)) + ################################################################################ # Return the full path to an indexer-specific file fragment. # @@ -78,15 +85,15 @@ define CreateFromTemplate $(SED) -e '/{{INDEXER_EXTENSIONS}}/r $(call GetIndexerFragment,extensions)' \ -e '/{{INDEXER_SETTINGS}}/r $(call GetIndexerFragment,settings)' \ -e '/{{EXTRA_WORKSPACE_ROOT}}/r $(call GetExtraWorkspaceRoot)' $1 | \ - $(SED) -e 's!{{TOPDIR}}!$(call FixPath,$(TOPDIR))!g' \ - -e 's!{{TOPDIR_RELATIVE}}!$(call FixPath,$(strip \ - $(call RelativePath,$(OUTPUTDIR),$(TOPDIR))))!g' \ - -e 's!{{WORKSPACE_ROOT}}!$(call FixPath,$(WORKSPACE_ROOT))!g' \ - -e 's!{{OUTPUTDIR}}!$(call FixPath,$(OUTPUTDIR))!g' \ + $(SED) -e 's!{{TOPDIR}}!$(call SedEscape,$(call FixPath,$(TOPDIR)))!g' \ + -e 's!{{TOPDIR_RELATIVE}}!$(call SedEscape,$(call FixPath,$(strip \ + $(call RelativePath,$(OUTPUTDIR),$(TOPDIR)))))!g' \ + -e 's!{{WORKSPACE_ROOT}}!$(call SedEscape,$(call FixPath,$(WORKSPACE_ROOT)))!g' \ + -e 's!{{OUTPUTDIR}}!$(call SedEscape,$(call FixPath,$(OUTPUTDIR)))!g' \ -e 's!{{CONF_NAME}}!$(CONF_NAME)!g' \ - -e 's!{{COMPILER}}!$(call FixPath,$(CXX)) $(SYSROOT_CFLAGS)!g' \ - -e 's!{{MAKE}}!$(call FixPath,$(MAKE))!g' \ - -e 's!{{PATH}}!$(call FixPath,$(PATH))!g' \ + -e 's!{{COMPILER}}!$(call SedEscape,$(call FixPath,$(CXX))) $(SYSROOT_CFLAGS)!g' \ + -e 's!{{MAKE}}!$(call SedEscape,$(call FixPath,$(MAKE)))!g' \ + -e 's!{{PATH}}!$(call SedEscape,$(call FixPath,$(PATH)))!g' \ -e 's!{{DEBUGENGINENAME}}!$(call DebugEngineName)!g' \ -e '/{{INDEXER_EXTENSIONS}}/d' \ -e '/{{INDEXER_SETTINGS}}/d' \ diff --git a/make/jdk/src/classes/build/tools/makezipreproducible/MakeZipReproducible.java b/make/jdk/src/classes/build/tools/makezipreproducible/MakeZipReproducible.java index 48f08541d6731253629ae550fd8eb5f88200ceb8..4ea976a8cc50df07b8e8026aa0db0c56f1f746f0 100644 --- a/make/jdk/src/classes/build/tools/makezipreproducible/MakeZipReproducible.java +++ b/make/jdk/src/classes/build/tools/makezipreproducible/MakeZipReproducible.java @@ -34,18 +34,22 @@ import java.util.zip.ZipException; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.LocalDateTime; /** * Generate a zip file in a "reproducible" manner from the input zip file. * Standard zip tools rely on OS file list querying whose ordering can vary * by platform architecture, this class ensures the zip entries are ordered - * and also supports SOURCE_DATE_EPOCH timestamps. + * and also supports SOURCE_DATE_EPOCH timestamps which will set the ZipEntry + * local time in UTC. */ public class MakeZipReproducible { String input_file = null; String fname = null; String zname = ""; - long timestamp = -1L; + LocalDateTime timestamp = null; boolean verbose = false; // Keep a sorted Set of ZipEntrys to be processed, so that the zip is reproducible @@ -117,7 +121,9 @@ public class MakeZipReproducible { break; case 't': // SOURCE_DATE_EPOCH timestamp specified - timestamp = Long.parseLong(args[++count]) * 1000; + long epochSeconds = Long.parseLong(args[++count]); + Instant instant = Instant.ofEpochSecond(epochSeconds); + timestamp = LocalDateTime.ofInstant(instant, ZoneOffset.UTC); break; case 'v': verbose = true; @@ -194,8 +200,8 @@ public class MakeZipReproducible { } // Set to specified timestamp if set otherwise leave as original lastModified time - if (timestamp != -1L) { - entry.setTime(timestamp); + if (timestamp != null) { + entry.setTimeLocal(timestamp); } zos.putNextEntry(entry); diff --git a/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java b/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java index 1f439e1c29e081bd23174c1a44f6cebb10c56841..ea700f0b660c6558c21e1dfd91d195d4eaaf0988 100644 --- a/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java +++ b/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java @@ -25,6 +25,7 @@ package build.tools.symbolgenerator; +import build.tools.symbolgenerator.CreateSymbols.ModuleHeaderDescription.ExportsDescription; import build.tools.symbolgenerator.CreateSymbols .ModuleHeaderDescription .ProvidesDescription; @@ -122,6 +123,7 @@ import com.sun.tools.classfile.Field; import com.sun.tools.classfile.InnerClasses_attribute; import com.sun.tools.classfile.InnerClasses_attribute.Info; import com.sun.tools.classfile.Method; +import com.sun.tools.classfile.ModulePackages_attribute; import com.sun.tools.classfile.MethodParameters_attribute; import com.sun.tools.classfile.ModuleMainClass_attribute; import com.sun.tools.classfile.ModuleResolution_attribute; @@ -244,7 +246,14 @@ public class CreateSymbols { md, mhd, versionsList); - mhd.exports.stream().forEach(pkg -> { + List packages = new ArrayList<>(); + mhd.exports.stream() + .map(ExportsDescription::packageName) + .forEach(packages::add); + if (mhd.extraModulePackages != null) { + packages.addAll(mhd.extraModulePackages); + } + packages.stream().forEach(pkg -> { for (char v : mhd.versions.toCharArray()) { package2Version2Module.computeIfAbsent(pkg, dummy -> new HashMap<>()).put(v, md.name); } @@ -974,13 +983,21 @@ public class CreateSymbols { return new RequiresEntry(idx, r.flags, r.version != null - ? addInt(cp, r.version) + ? addString(cp, r.version) : 0); } private static ExportsEntry createExportsEntry(List cp, - String e) { - return new ExportsEntry(addPackageName(cp, e), 0, new int[0]); + ExportsDescription export) { + int[] to; + if (export.isQualified()) { + to = export.to.stream() + .mapToInt(module -> addModuleName(cp, module)) + .toArray(); + } else { + to = new int[0]; + } + return new ExportsEntry(addPackageName(cp, export.packageName()), 0, to); } private static OpensEntry createOpensEntry(List cp, String e) { @@ -1405,7 +1422,7 @@ public class CreateSymbols { dumpDescriptions(classes, modules, platforms, Set.of(), descDest.resolve("symbols"), args); } //where: - private static final String DO_NO_MODIFY = + public static String DO_NOT_MODIFY = "#\n" + "# Copyright (c) {YEAR}, Oracle and/or its affiliates. All rights reserved.\n" + "# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n" + @@ -1477,14 +1494,19 @@ public class CreateSymbols { ExcludeIncludeList currentEIList = excludesIncludes; if (!currentVersionModules.isEmpty()) { + Set privateIncludes = + enhancedIncludesListBasedOnClassHeaders(classes, classData); Set includes = new HashSet<>(); for (ModuleDescription md : currentVersionModules.values()) { - md.header.get(0).exports.stream().map(e -> e + '/') + md.header.get(0).exports.stream() + .filter(e -> !e.isQualified()) + .map(e -> e.packageName + '/') .forEach(includes::add); } currentEIList = new ExcludeIncludeList(includes, + privateIncludes, Collections.emptySet()); } @@ -1507,7 +1529,9 @@ public class CreateSymbols { if (unsupported.header .get(0) .exports - .contains(cd.packge().replace('.', '/'))) { + .stream() + .map(ed -> ed.packageName) + .anyMatch(pack -> pack.equals(cd.packge().replace('.', '/')))) { ClassHeaderDescription ch = cd.header.get(0); if (ch.classAnnotations == null) { ch.classAnnotations = new ArrayList<>(); @@ -1529,7 +1553,7 @@ public class CreateSymbols { for (ClassDescription clazz : currentVersionClasses) { ClassHeaderDescription header = clazz.header.get(0); - if (includeEffectiveAccess(currentVersionClasses, clazz)) { + if (includeEffectiveAccess(currentVersionClasses, clazz) && currentEIList.accepts(clazz.name, false)) { modified |= include(includedClasses, currentVersionClasses, clazz.name); } @@ -1555,6 +1579,8 @@ public class CreateSymbols { } } while (modified); + Set allIncludedPackages = new HashSet<>(); + for (ClassDescription clazz : currentVersionClasses) { if (!includedClasses.contains(clazz.name)) { continue; @@ -1595,6 +1621,8 @@ public class CreateSymbols { } else { classes.add(clazz); } + + allIncludedPackages.add(clazz.packge().replace('.', '/')); } for (ModuleDescription module : currentVersionModules.values()) { @@ -1611,6 +1639,13 @@ public class CreateSymbols { } } + header.exports.removeIf(ed -> ed.isQualified() && + !allIncludedPackages.contains(ed.packageName())); + + if (header.extraModulePackages != null) { + header.extraModulePackages.retainAll(allIncludedPackages); + } + ModuleDescription existing = modules.get(module.name); if (existing != null) { @@ -1642,7 +1677,16 @@ public class CreateSymbols { md.header .stream() .filter(h -> h.versions.contains(v.version)) - .flatMap(h -> h.exports.stream()) + .flatMap(h -> { + List packages = new ArrayList<>(); + h.exports.stream() + .map(ExportsDescription::packageName) + .forEach(packages::add); + if (h.extraModulePackages != null) { + packages.addAll(h.extraModulePackages); + } + return packages.stream(); + }) .map(p -> p.replace('/', '.')) .forEach(p -> package2Modules.putIfAbsent(p, md.name)); } @@ -1718,11 +1762,11 @@ public class CreateSymbols { boolean hasChange = true; if (Files.isReadable(f)) { String oldContent = Files.readString(f, StandardCharsets.UTF_8); - int yearPos = DO_NO_MODIFY.indexOf("{YEAR}"); + int yearPos = DO_NOT_MODIFY.indexOf("{YEAR}"); String headerPattern = - Pattern.quote(DO_NO_MODIFY.substring(0, yearPos)) + + Pattern.quote(DO_NOT_MODIFY.substring(0, yearPos)) + "([0-9]+)(, [0-9]+)?" + - Pattern.quote(DO_NO_MODIFY.substring(yearPos + "{YEAR}".length())); + Pattern.quote(DO_NOT_MODIFY.substring(yearPos + "{YEAR}".length())); String pattern = headerPattern + Pattern.quote(dataString); Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(oldContent); @@ -1739,7 +1783,7 @@ public class CreateSymbols { try (Writer out = Files.newBufferedWriter(f, StandardCharsets.UTF_8)) { String currentYear = String.valueOf(year); String yearSpec = (existingYear != null && !currentYear.equals(existingYear) ? existingYear + ", " : "") + currentYear; - out.append(DO_NO_MODIFY.replace("{YEAR}", yearSpec)); + out.append(DO_NOT_MODIFY.replace("{YEAR}", yearSpec)); out.write(dataString); } } @@ -1750,7 +1794,7 @@ public class CreateSymbols { outputFiles.put(desc, files); } - symbolsOut.append(DO_NO_MODIFY.replace("{YEAR}", "2015, " + year)); + symbolsOut.append(DO_NOT_MODIFY.replace("{YEAR}", "2015, " + year)); symbolsOut.append("#command used to generate this file:\n"); symbolsOut.append("#") .append(CreateSymbols.class.getName()) @@ -1923,7 +1967,7 @@ public class CreateSymbols { return ; } - if (!excludesIncludes.accepts(cf.getName())) { + if (!excludesIncludes.accepts(cf.getName(), true)) { return ; } @@ -2019,6 +2063,45 @@ public class CreateSymbols { addModuleHeader(moduleDesc, headerDesc, version); } + private Set enhancedIncludesListBasedOnClassHeaders(ClassList classes, + Iterable classData) { + Set additionalIncludes = new HashSet<>(); + + for (byte[] classFileData : classData) { + try (InputStream in = new ByteArrayInputStream(classFileData)) { + ClassFile cf = ClassFile.read(in); + + if (cf.access_flags.is(AccessFlags.ACC_MODULE)) { + continue; + } + + Set additionalClasses = new HashSet<>(); + + if (cf.super_class != 0) { + additionalClasses.add(cf.getSuperclassName()); + } + for (int i = 0; i < cf.interfaces.length; i++) { + additionalClasses.add(cf.getInterfaceName(i)); + } + + for (String additional : additionalClasses) { + int dollar; + + additionalIncludes.add(additional); + + while ((dollar = additional.lastIndexOf('$')) != (-1)) { + additional = additional.substring(0, dollar); + additionalIncludes.add(additional); + } + } + } catch (IOException | ConstantPoolException ex) { + throw new IllegalStateException(ex); + } + } + + return additionalIncludes; + } + private void addModuleHeader(ModuleDescription moduleDesc, ModuleHeaderDescription headerDesc, String version) { @@ -2204,9 +2287,11 @@ public class CreateSymbols { header.exports = Arrays.stream(mod.exports) - .filter(ee -> ee.exports_to_count == 0) - .map(ee -> getPackageName(cf, ee.exports_index)) + .map(ee -> ExportsDescription.create(cf, ee)) .collect(Collectors.toList()); + if (header.extraModulePackages != null) { + header.exports.forEach(ed -> header.extraModulePackages.remove(ed.packageName())); + } header.requires = Arrays.stream(mod.requires) .map(r -> RequiresDescription.create(cf, r)) @@ -2242,6 +2327,20 @@ public class CreateSymbols { break; } case Attribute.ModulePackages: + assert feature instanceof ModuleHeaderDescription; + ModuleHeaderDescription header = + (ModuleHeaderDescription) feature; + ModulePackages_attribute mod = + (ModulePackages_attribute) attr; + header.extraModulePackages = new ArrayList<>(); + for (int i = 0; i < mod.packages_count; i++) { + String packageName = getPackageName(cf, mod.packages_index[i]); + if (header.exports == null || + header.exports.stream().noneMatch(ed -> ed.packageName().equals(packageName))) { + header.extraModulePackages.add(packageName); + } + } + break; case Attribute.ModuleHashes: break; case Attribute.NestHost: { @@ -2352,11 +2451,16 @@ public class CreateSymbols { } } - private static Integer getVersion(ClassFile cf, int idx) { + public static String INJECTED_VERSION = null; + + private static String getVersion(ClassFile cf, int idx) { + if (INJECTED_VERSION != null) { + return INJECTED_VERSION; + } if (idx == 0) return null; try { - return ((CONSTANT_Integer_info) cf.constant_pool.get(idx)).value; + return ((CONSTANT_Utf8_info) cf.constant_pool.get(idx)).value; } catch (InvalidIndex ex) { throw new IllegalStateException(ex); } @@ -2470,9 +2574,15 @@ public class CreateSymbols { if (clazzName == null) return false; + ClassDescription desc = classes.find(clazzName, true); + + if (desc == null) { + return false; + } + boolean modified = includedClasses.add(clazzName); - for (ClassDescription outer : classes.enclosingClasses(classes.find(clazzName, true))) { + for (ClassDescription outer : classes.enclosingClasses(desc)) { modified |= includedClasses.add(outer.name); } @@ -2514,10 +2624,17 @@ public class CreateSymbols { public static class ExcludeIncludeList { public final Set includeList; + public final Set privateIncludeList; public final Set excludeList; protected ExcludeIncludeList(Set includeList, Set excludeList) { + this(includeList, Set.of(), excludeList); + } + + protected ExcludeIncludeList(Set includeList, Set privateIncludeList, + Set excludeList) { this.includeList = includeList; + this.privateIncludeList = privateIncludeList; this.excludeList = excludeList; } @@ -2537,8 +2654,10 @@ public class CreateSymbols { return new ExcludeIncludeList(includeList, excludeList); } - public boolean accepts(String className) { - return matches(includeList, className) && !matches(excludeList, className); + public boolean accepts(String className, boolean includePrivateClasses) { + return (matches(includeList, className) || + (includePrivateClasses && matches(privateIncludeList, className))) && + !matches(excludeList, className); } private static boolean matches(Set list, String className) { @@ -2738,8 +2857,9 @@ public class CreateSymbols { static class ModuleHeaderDescription extends HeaderDescription { String name; - List exports = new ArrayList<>(); + List exports = new ArrayList<>(); List opens = new ArrayList<>(); + List extraModulePackages = new ArrayList<>(); List requires = new ArrayList<>(); List uses = new ArrayList<>(); List provides = new ArrayList<>(); @@ -2753,6 +2873,7 @@ public class CreateSymbols { hash = 83 * hash + Objects.hashCode(this.name); hash = 83 * hash + Objects.hashCode(this.exports); hash = 83 * hash + Objects.hashCode(this.opens); + hash = 83 * hash + Objects.hashCode(this.extraModulePackages); hash = 83 * hash + Objects.hashCode(this.requires); hash = 83 * hash + Objects.hashCode(this.uses); hash = 83 * hash + Objects.hashCode(this.provides); @@ -2781,6 +2902,9 @@ public class CreateSymbols { if (!listEquals(this.opens, other.opens)) { return false; } + if (!listEquals(this.extraModulePackages, other.extraModulePackages)) { + return false; + } if (!listEquals(this.requires, other.requires)) { return false; } @@ -2812,10 +2936,17 @@ public class CreateSymbols { && versions.contains(version))) return ; output.append("header"); - if (exports != null && !exports.isEmpty()) - output.append(" exports " + serializeList(exports)); + if (exports != null && !exports.isEmpty()) { + List exportsList = + exports.stream() + .map(exp -> exp.serialize()) + .collect(Collectors.toList()); + output.append(" exports " + serializeList(exportsList)); + } if (opens != null && !opens.isEmpty()) output.append(" opens " + serializeList(opens)); + if (extraModulePackages != null && !extraModulePackages.isEmpty()) + output.append(" extraModulePackages " + serializeList(extraModulePackages)); if (requires != null && !requires.isEmpty()) { List requiresList = requires.stream() @@ -2862,8 +2993,12 @@ public class CreateSymbols { if (!"header".equals(reader.lineKey)) return false; - exports = deserializeList(reader.attributes.get("exports")); + List exportsList = deserializeList(reader.attributes.get("exports"), false); + exports = exportsList.stream() + .map(ExportsDescription::deserialize) + .collect(Collectors.toList()); opens = deserializeList(reader.attributes.get("opens")); + extraModulePackages = deserializeList(reader.attributes.get("extraModulePackages")); List requiresList = deserializeList(reader.attributes.get("requires")); requires = requiresList.stream() @@ -2893,13 +3028,53 @@ public class CreateSymbols { return true; } + record ExportsDescription(String packageName, List to) { + public String serialize() { + return packageName + + (isQualified() ? "[" + quote(serializeList(to), true, true) + "]" + : ""); + } + + public static ExportsDescription deserialize(String data) { + int bracket = data.indexOf("["); + String packageName; + List to; + if (bracket != (-1)) { + packageName = data.substring(0, bracket); + to = deserializeList(unquote(data.substring(bracket + 1, data.length() - 1))); + } else { + packageName = data; + to = null; + } + + return new ExportsDescription(packageName, to); + } + + public static ExportsDescription create(ClassFile cf, + ExportsEntry ee) { + String packageName = getPackageName(cf, ee.exports_index); + List to = null; + if (ee.exports_to_count > 0) { + to = new ArrayList<>(); + for (int moduleIndex : ee.exports_to_index) { + to.add(getModuleName(cf, moduleIndex)); + } + } + return new ExportsDescription(packageName, to); + } + + public boolean isQualified() { + return to != null && !to.isEmpty(); + } + } + static class RequiresDescription { final String moduleName; final int flags; - final Integer version; + final String version; public RequiresDescription(String moduleName, int flags, - Integer version) { + String version) { this.moduleName = moduleName; this.flags = flags; this.version = version; @@ -2907,7 +3082,7 @@ public class CreateSymbols { public String serialize() { String versionKeyValue = version != null - ? " version " + quote(String.valueOf(version), true) + ? " version " + quote(version, true) : ""; return "name " + quote(moduleName, true) + " flags " + quote(Integer.toHexString(flags), true) + @@ -2917,8 +3092,8 @@ public class CreateSymbols { public static RequiresDescription deserialize(String data) { Map attributes = splitAttributes(data); - Integer ver = attributes.containsKey("version") - ? Integer.parseInt(attributes.get("version")) + String ver = attributes.containsKey("version") + ? attributes.get("version") : null; int flags = Integer.parseInt(attributes.get("flags"), 16); return new RequiresDescription(attributes.get("name"), @@ -2929,7 +3104,7 @@ public class CreateSymbols { public static RequiresDescription create(ClassFile cf, RequiresEntry req) { String mod = getModuleName(cf, req.requires_index); - Integer ver = getVersion(cf, req.requires_version_index); + String ver = getVersion(cf, req.requires_version_index); return new RequiresDescription(mod, req.requires_flags, ver); @@ -3071,10 +3246,24 @@ public class CreateSymbols { header.write(output, baselineVersion, version); } for (FieldDescription field : fields) { - field.write(output, baselineVersion, version); + if (!field.versions.contains(version)) { + field.write(output, baselineVersion, version); + } + } + for (MethodDescription method : methods) { + if (!method.versions.contains(version)) { + method.write(output, baselineVersion, version); + } + } + for (FieldDescription field : fields) { + if (field.versions.contains(version)) { + field.write(output, baselineVersion, version); + } } for (MethodDescription method : methods) { - method.write(output, baselineVersion, version); + if (method.versions.contains(version)) { + method.write(output, baselineVersion, version); + } } output.append("\n"); } @@ -3157,6 +3346,12 @@ public class CreateSymbols { return pack; } + + @Override + public String toString() { + return name; + } + } static class ClassHeaderDescription extends HeaderDescription { @@ -3265,12 +3460,12 @@ public class CreateSymbols { readRecordComponents(reader); } readInnerClasses(reader); + isSealed = reader.attributes.containsKey("permittedSubclasses"); if (isSealed) { String subclassesList = reader.attributes.get("permittedSubclasses"); permittedSubclasses = deserializeList(subclassesList); } - return true; } @@ -4120,8 +4315,11 @@ public class CreateSymbols { } w.write("module:" + module.name); w.write("\n"); - for (String pack : header.get().exports) { - w.write(pack.replace('/', '.')); + for (ExportsDescription export : header.get().exports) { + if (export.isQualified()) { + continue; + } + w.write(export.packageName.replace('/', '.')); w.write("\n"); } } diff --git a/make/langtools/tools/compileproperties/CompileProperties.java b/make/langtools/tools/compileproperties/CompileProperties.java index 49cfc8a4a4b1445cd15a32d784c8204fe95587e0..7d69f9b47b2e9d37e06f2424054d85385d1571f7 100644 --- a/make/langtools/tools/compileproperties/CompileProperties.java +++ b/make/langtools/tools/compileproperties/CompileProperties.java @@ -183,7 +183,8 @@ public class CompileProperties { log.error("cannot close " + filename, e); } } - if ( ok = true && contents != null ) { + ok = true; + if ( contents != null ) { String tokens[] = (new String(contents)).split("\\s+"); if ( tokens.length > 0 ) { ok = parseOptions(tokens); diff --git a/make/modules/java.base/Java.gmk b/make/modules/java.base/Java.gmk index 58d707e6148c55de800dd90b67d106de40ad6257..25c14d2b1d265cc93268275b9e22690f30a18f2c 100644 --- a/make/modules/java.base/Java.gmk +++ b/make/modules/java.base/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # 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 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-reference,-accessibility \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' JAVAC_FLAGS += -XDstringConcat=inline COPY += .icu .dat .spp .nrm content-types.properties \ diff --git a/make/modules/java.compiler/Java.gmk b/make/modules/java.compiler/Java.gmk index e124e8844d3b39179d97b509f66430fd05c9029f..e2d5ac264b8b6406cf5c928d40d9c018cf103d9e 100644 --- a/make/modules/java.compiler/Java.gmk +++ b/make/modules/java.compiler/Java.gmk @@ -25,3 +25,5 @@ DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' + +EXCLUDES += javax/tools/snippet-files diff --git a/make/modules/java.datatransfer/Java.gmk b/make/modules/java.datatransfer/Java.gmk index a9f7c8f4f0af9aee4b8f5decbc2af7e42c9d7c59..29feb6df9f55283dce03fa03f4ab659a3c6b56f5 100644 --- a/make/modules/java.datatransfer/Java.gmk +++ b/make/modules/java.datatransfer/Java.gmk @@ -23,6 +23,6 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-reference \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' COPY += flavormap.properties diff --git a/make/modules/java.instrument/Java.gmk b/make/modules/java.instrument/Java.gmk index 5f46b155e0cc22c61f8f9f898e81a8c681af14ee..f49e425718e7fc45c52e1f55c81e221145a781cf 100644 --- a/make/modules/java.instrument/Java.gmk +++ b/make/modules/java.instrument/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # 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,5 +23,5 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-accessibility \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' diff --git a/make/modules/java.logging/Java.gmk b/make/modules/java.logging/Java.gmk index 40da53d432b1692f18278d1895fcdb705b38e30e..f49e425718e7fc45c52e1f55c81e221145a781cf 100644 --- a/make/modules/java.logging/Java.gmk +++ b/make/modules/java.logging/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # 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,5 +23,5 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-reference,-accessibility \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' diff --git a/make/modules/java.management/Java.gmk b/make/modules/java.management/Java.gmk index 40da53d432b1692f18278d1895fcdb705b38e30e..f49e425718e7fc45c52e1f55c81e221145a781cf 100644 --- a/make/modules/java.management/Java.gmk +++ b/make/modules/java.management/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # 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,5 +23,5 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-reference,-accessibility \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' diff --git a/make/modules/java.rmi/Launcher.gmk b/make/modules/java.rmi/Launcher.gmk index 8a540da898b953e9b267f2eed4de9bf5da355531..001bc204c942db623bcdaee1bde03f99fbd7a199 100644 --- a/make/modules/java.rmi/Launcher.gmk +++ b/make/modules/java.rmi/Launcher.gmk @@ -27,4 +27,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, rmiregistry, \ MAIN_CLASS := sun.rmi.registry.RegistryImpl, \ + JAVA_ARGS := -Djava.security.manager=allow, \ )) diff --git a/make/modules/java.smartcardio/Java.gmk b/make/modules/java.smartcardio/Java.gmk index 5f46b155e0cc22c61f8f9f898e81a8c681af14ee..f49e425718e7fc45c52e1f55c81e221145a781cf 100644 --- a/make/modules/java.smartcardio/Java.gmk +++ b/make/modules/java.smartcardio/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # 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,5 +23,5 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-accessibility \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' diff --git a/make/modules/java.sql.rowset/Java.gmk b/make/modules/java.sql.rowset/Java.gmk index 2ea5be28ed17dece0db11134a408d0cd8ddb68ff..63437c6113f5ea153c6d599ed8467b75040aa1ee 100644 --- a/make/modules/java.sql.rowset/Java.gmk +++ b/make/modules/java.sql.rowset/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # 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 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-accessibility \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' CLEAN_FILES += $(wildcard \ $(TOPDIR)/src/java.sql.rowset/share/classes/com/sun/rowset/*.properties \ diff --git a/make/modules/java.xml/Java.gmk b/make/modules/java.xml/Java.gmk index b7bf8b701650124702baf8e85d38ea2517a4e3aa..aa4b786020fea5a4c39bdba74e63636042a6eda9 100644 --- a/make/modules/java.xml/Java.gmk +++ b/make/modules/java.xml/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # 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 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-accessibility \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:$(call CommaList, javax.xml.catalog javax.xml.datatype \ javax.xml.transform javax.xml.validation javax.xml.xpath)' CLEAN += .properties diff --git a/make/modules/jdk.jstatd/Launcher.gmk b/make/modules/jdk.jstatd/Launcher.gmk index de481b78b6c71e687f03544df59195984a336284..2137fddd9a01011215b73bd8fc6b6cb577f334a7 100644 --- a/make/modules/jdk.jstatd/Launcher.gmk +++ b/make/modules/jdk.jstatd/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/scripts/update_copyright_year.sh b/make/scripts/update_copyright_year.sh index 0f9ba80fc5af9f9d66ac23895135c9515d85f769..a825486a94179e1ddc10e8f4ecf53d0b893f1e2f 100644 --- a/make/scripts/update_copyright_year.sh +++ b/make/scripts/update_copyright_year.sh @@ -1,7 +1,7 @@ #!/bin/bash -f # -# Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. # 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,27 +23,87 @@ # questions. # -# Script to update the Copyright YEAR range in Mercurial sources. +# Script to update the Copyright YEAR range in Mercurial & Git sources. # (Originally from xdono, Thanks!) -awk=awk +#------------------------------------------------------------ +copyright="Copyright (c)" +company="Oracle" +#------------------------------------------------------------ + +awk="awk" # Stop on any error set -e +# To allow total changes counting +shopt -s lastpipe + +# Get an absolute path to this script, since that determines the top-level directory. +this_script_dir=`dirname $0` +this_script_dir=`cd $this_script_dir > /dev/null && pwd` + # Temp area tmp=/tmp/`basename $0`.${USER}.$$ rm -f -r ${tmp} mkdir -p ${tmp} total=0 +# Default or supplied company name +if [ "$3" != "" ] ; then + company="$3" +fi + # This year or supplied year -if [ "$1" != "" ] ; then - year="$1" +if [ "$2" != "" ] ; then + year="$2" else year=`date +%Y` fi +# VCS select +vcs="$1" + +if [ -z "$vcs" ] ; then + git_found=false + hg_found=false + + [ -d "${this_script_dir}/../../.git" ] && git_found=true + [ -d "${this_script_dir}/../../.hg" ] && hg_found=true + + if [ "$git_found" == "true" ] && [ "$hg_found" == "false" ] ; then + vcs="git" + elif [ "$hg_found" == "true" ] && [ "$git_found" == "false" ] ; then + vcs="hg" + else + echo "Error: could not auto-detect version control system" + vcs="" + fi +fi + +case "$vcs" in + "git") + echo "Using Git version control system" + vcs_status=(git ls-files -m) + vcs_list_changesets=(git log --no-merges --since="${year}-01-01T00:00:00Z" --until="${year}-12-31T23:59:59Z" --pretty=tformat:"%H") + vcs_changeset_message=(git log -1 --pretty=tformat:"%B") # followed by ${changeset} + vcs_changeset_files=(git diff-tree --no-commit-id --name-only -r) # followed by ${changeset} + ;; + + "hg") + echo "Using Mercurial version control system" + vcs_status=(hg status) + vcs_list_changesets=(hg log --no-merges -v -d "${year}-01-01 to ${year}-12-31" --template '{node}\n') + vcs_changeset_message=(hg log -l1 --template '{desc}\n' --rev) # followed by ${changeset} + vcs_changeset_files=(hg log -l1 -v --template '{files}\n' --rev) # followed by ${changeset} + ;; + + *) + echo "Usage: `basename "$0"` [year [company]]" + exit 1 + ;; +esac + # Return true if it makes sense to edit this file saneFileToCheck() { @@ -68,8 +128,6 @@ updateFile() # file { changed="false" if [ `saneFileToCheck "$1"` = "true" ] ; then - copyright="Copyright (c)" - company="Oracle" rm -f $1.OLD mv $1 $1.OLD cat $1.OLD | \ @@ -94,12 +152,10 @@ updateChangesetFiles() # changeset count=0 files=${tmp}/files.$1 rm -f ${files} - hg log -l1 --rev $1 -v --template '{files}\n' | expand \ + "${vcs_changeset_files[@]}" "$1" | expand \ | ${awk} -F' ' '{for(i=1;i<=NF;i++)print $i}' \ > ${files} if [ -f "${files}" -a -s "${files}" ] ; then - copyright="Copyright (c)" - company="Oracle" fcount=`cat ${files}| wc -l` for i in `cat ${files}` ; do if [ `updateFile "${i}"` = "true" ] ; then @@ -116,8 +172,8 @@ updateChangesetFiles() # changeset printf " ERROR: No files changed in the changeset? Must be a mistake.\n" set -x ls -al ${files} - hg log -l1 --rev $1 -v --template '{files}\n' - hg log -l1 --rev $1 -v --template '{files}\n' | expand \ + "${vcs_changeset_files[@]}" "$1" + "${vcs_changeset_files[@]}" "$1" | expand \ | ${awk} -F' ' '{for(i=1;i<=NF;i++)print $i}' set +x exit 1 @@ -126,16 +182,16 @@ updateChangesetFiles() # changeset } # Check if repository is clean -previous=`hg status|wc -l` +previous=`"${vcs_status[@]}"|wc -l` if [ ${previous} -ne 0 ] ; then echo "WARNING: This repository contains previously edited working set files." - echo " hg status | wc -l = `hg status | wc -l`" + echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`" fi # Get all changesets this year all_changesets=${tmp}/all_changesets rm -f ${all_changesets} -hg log --no-merges -v -d "${year}-01-01 to ${year}-12-31" --template '{node}\n' > ${all_changesets} +"${vcs_list_changesets[@]}" > ${all_changesets} # Check changeset to see if it is Copyright only changes, filter changesets if [ -s ${all_changesets} ] ; then @@ -146,7 +202,7 @@ if [ -s ${all_changesets} ] ; then desc=${tmp}/desc.${changeset} rm -f ${desc} echo "------------------------------------------------" - hg log -l1 --rev ${changeset} --template '{desc}\n' > ${desc} + "${vcs_changeset_message[@]}" "${changeset}" > ${desc} printf "%d: %s\n%s\n" ${index} "${changeset}" "`cat ${desc}|head -1`" if [ "${year}" = "2010" ] ; then if cat ${desc} | fgrep -i "Added tag" > /dev/null ; then @@ -175,18 +231,18 @@ if [ ${total} -gt 0 ] ; then echo "---------------------------------------------" echo "Updated the copyright year on a total of ${total} files." if [ ${previous} -eq 0 ] ; then - echo "This count should match the count of modified files in the repository: hg status -m" + echo "This count should match the count of modified files in the repository: ${vcs_status[*]}" else echo "WARNING: This repository contained previously edited working set files." fi - echo " hg status -m | wc -l = `hg status -m | wc -l`" + echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`" else echo "---------------------------------------------" echo "No files were changed" if [ ${previous} -ne 0 ] ; then echo "WARNING: This repository contained previously edited working set files." fi - echo " hg status -m | wc -l = `hg status -m | wc -l`" + echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`" fi # Cleanup diff --git a/make/src/classes/build/tools/jfr/GenerateJfrFiles.java b/make/src/classes/build/tools/jfr/GenerateJfrFiles.java index dbaa8db7f653df27eef191994f3e81d3e73972ac..a3b17cf8c3f5a8b76ccec07a5feda31624cea0b7 100644 --- a/make/src/classes/build/tools/jfr/GenerateJfrFiles.java +++ b/make/src/classes/build/tools/jfr/GenerateJfrFiles.java @@ -174,6 +174,7 @@ public class GenerateJfrFiles { boolean cutoff; boolean throttle; boolean experimental; + boolean internal; long id; boolean isEvent; boolean isRelation; @@ -197,6 +198,7 @@ public class GenerateJfrFiles { pos.writeBoolean(cutoff); pos.writeBoolean(throttle); pos.writeBoolean(experimental); + pos.writeBoolean(internal); pos.writeLong(id); pos.writeBoolean(isEvent); pos.writeBoolean(isRelation); @@ -487,6 +489,7 @@ public class GenerateJfrFiles { currentType.description = getString(attributes, "description"); currentType.category = getString(attributes, "category"); currentType.experimental = getBoolean(attributes, "experimental", false); + currentType.internal = getBoolean(attributes, "internal", false); currentType.thread = getBoolean(attributes, "thread", false); currentType.stackTrace = getBoolean(attributes, "stackTrace", false); currentType.startTime = getBoolean(attributes, "startTime", true); @@ -863,6 +866,9 @@ public class GenerateJfrFiles { private static void printWriteData(Printer out, TypeElement type) { out.write(" template "); out.write(" void writeData(Writer& w) {"); + if (type.isEvent && type.internal) { + out.write(" JfrEventSetting::unhide_internal_types();"); + } if (("_thread_in_native").equals(type.commitState)) { out.write(" // explicit epoch synchronization check"); out.write(" JfrEpochSynchronization sync;"); diff --git a/src/demo/share/jfc/SwingSet2/TableDemo.java b/src/demo/share/jfc/SwingSet2/TableDemo.java index 350fb6efd675e2221eec0fa97a6cbab5cc89b9e4..f136de28df962bf535a4b538fb5f08c77e8b455f 100644 --- a/src/demo/share/jfc/SwingSet2/TableDemo.java +++ b/src/demo/share/jfc/SwingSet2/TableDemo.java @@ -768,4 +768,13 @@ public class TableDemo extends DemoModule { footerTextField.setDragEnabled(dragEnabled); } + @Override + public ImageIcon createImageIcon(String filename, String description) { + ImageIcon imageIcon = super.createImageIcon(filename, description); + AccessibleContext context = imageIcon.getAccessibleContext(); + if (context!= null) { + context.setAccessibleName(description); + } + return imageIcon; + } } diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 1f1a21729345b52c88050a0f14a205b54fa41afa..3e1a6cd0a54cc1daa87d138cb20e3a4e503691e2 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -1,5 +1,5 @@ // -// Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. // Copyright (c) 2014, 2021, Red Hat, Inc. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // @@ -2481,7 +2481,7 @@ const RegMask* Matcher::predicate_reg_mask(void) { return &_PR_REG_mask; } -const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { +const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { return new TypeVectMask(elemTy, length); } @@ -2732,11 +2732,8 @@ bool is_vector_arith_imm_pattern(Node* n, Node* m) { // Should the matcher clone input 'm' of node 'n'? bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { // ShiftV src (ShiftCntV con) - // StoreVector (VectorStoreMask src) // Binary src (Replicate con) - if (is_vshift_con_pattern(n, m) || - (UseSVE > 0 && m->Opcode() == Op_VectorStoreMask && n->Opcode() == Op_StoreVector) || - is_vector_arith_imm_pattern(n, m)) { + if (is_vshift_con_pattern(n, m) || is_vector_arith_imm_pattern(n, m)) { mstack.push(m, Visit); return true; } @@ -3906,37 +3903,40 @@ encode %{ // Check for existing monitor __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); - // Set tmp to be (markWord of object | UNLOCK_VALUE). - __ orr(tmp, disp_hdr, markWord::unlocked_value); - - // Initialize the box. (Must happen before we update the object mark!) - __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); - - // Compare object markWord with an unlocked value (tmp) and if - // equal exchange the stack address of our box with object markWord. - // On failure disp_hdr contains the possibly locked markWord. - __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, - /*release*/ true, /*weak*/ false, disp_hdr); - __ br(Assembler::EQ, cont); - - assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); - - // If the compare-and-exchange succeeded, then we found an unlocked - // object, will have now locked it will continue at label cont - - __ bind(cas_failed); - // We did not see an unlocked object so try the fast recursive case. - - // Check if the owner is self by comparing the value in the - // markWord of object (disp_hdr) with the stack pointer. - __ mov(rscratch1, sp); - __ sub(disp_hdr, disp_hdr, rscratch1); - __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); - // If condition is true we are cont and hence we can store 0 as the - // displaced header in the box, which indicates that it is a recursive lock. - __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result - __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); - + if (!UseHeavyMonitors) { + // Set tmp to be (markWord of object | UNLOCK_VALUE). + __ orr(tmp, disp_hdr, markWord::unlocked_value); + + // Initialize the box. (Must happen before we update the object mark!) + __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); + + // Compare object markWord with an unlocked value (tmp) and if + // equal exchange the stack address of our box with object markWord. + // On failure disp_hdr contains the possibly locked markWord. + __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, + /*release*/ true, /*weak*/ false, disp_hdr); + __ br(Assembler::EQ, cont); + + assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + + // If the compare-and-exchange succeeded, then we found an unlocked + // object, will have now locked it will continue at label cont + + __ bind(cas_failed); + // We did not see an unlocked object so try the fast recursive case. + + // Check if the owner is self by comparing the value in the + // markWord of object (disp_hdr) with the stack pointer. + __ mov(rscratch1, sp); + __ sub(disp_hdr, disp_hdr, rscratch1); + __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); + // If condition is true we are cont and hence we can store 0 as the + // displaced header in the box, which indicates that it is a recursive lock. + __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result + __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); + } else { + __ tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0. + } __ b(cont); // Handle existing monitor. @@ -3982,23 +3982,29 @@ encode %{ assert_different_registers(oop, box, tmp, disp_hdr); - // Find the lock address and load the displaced header from the stack. - __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); + if (!UseHeavyMonitors) { + // Find the lock address and load the displaced header from the stack. + __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); - // If the displaced header is 0, we have a recursive unlock. - __ cmp(disp_hdr, zr); - __ br(Assembler::EQ, cont); + // If the displaced header is 0, we have a recursive unlock. + __ cmp(disp_hdr, zr); + __ br(Assembler::EQ, cont); + } // Handle existing monitor. __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); - // Check if it is still a light weight lock, this is is true if we - // see the stack address of the basicLock in the markWord of the - // object. + if (!UseHeavyMonitors) { + // Check if it is still a light weight lock, this is is true if we + // see the stack address of the basicLock in the markWord of the + // object. - __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, - /*release*/ true, /*weak*/ false, tmp); + __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, + /*release*/ true, /*weak*/ false, tmp); + } else { + __ tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0. + } __ b(cont); assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); @@ -8556,10 +8562,10 @@ instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ "mov $dst, $tmp\t# vector (1D)" %} ins_encode %{ __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 - __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); + __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); - __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); + __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); %} ins_pipe(pipe_class_default); @@ -8581,7 +8587,7 @@ instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); - __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); + __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); %} ins_pipe(pipe_class_default); @@ -8599,10 +8605,10 @@ instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ "addv $tmp, $tmp\t# vector (8B)\n\t" "mov $dst, $tmp\t# vector (1D)" %} ins_encode %{ - __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); + __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); - __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); + __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); %} ins_pipe(pipe_class_default); @@ -8624,7 +8630,7 @@ instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); - __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); + __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); %} ins_pipe(pipe_class_default); @@ -17009,16 +17015,17 @@ instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, iRegI_R0 result, rFlagsReg cr) %{ match(Set result (StrCompressedCopy src (Binary dst len))); - effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); + effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, + USE_KILL src, USE_KILL dst, USE len, KILL cr); - format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} + format %{ "String Compress $src,$dst,$len -> $result // KILL $src,$dst" %} ins_encode %{ __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, + $result$$Register, $tmp1$$FloatRegister, $tmp2$$FloatRegister, - $tmp3$$FloatRegister, $tmp4$$FloatRegister, - $result$$Register); + $tmp3$$FloatRegister, $tmp4$$FloatRegister); %} - ins_pipe( pipe_slow ); + ins_pipe(pipe_slow); %} // fast byte[] to char[] inflation @@ -17043,22 +17050,43 @@ instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len // encode char[] to byte[] in ISO_8859_1 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, - vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, - vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, + vRegD_V2 vtmp2, vRegD_V3 vtmp3, iRegI_R0 result, rFlagsReg cr) %{ predicate(!((EncodeISOArrayNode*)n)->is_ascii()); match(Set result (EncodeISOArray src (Binary dst len))); - effect(USE_KILL src, USE_KILL dst, USE_KILL len, - KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); + effect(USE_KILL src, USE_KILL dst, USE len, + KILL vtmp0, KILL vtmp1, KILL vtmp2, KILL vtmp3, KILL cr); - format %{ "Encode array $src,$dst,$len -> $result" %} + format %{ "Encode ISO array $src,$dst,$len -> $result" %} ins_encode %{ __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, - $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, - $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); + $result$$Register, false, + $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, + $vtmp2$$FloatRegister, $vtmp3$$FloatRegister); %} - ins_pipe( pipe_class_memory ); + ins_pipe(pipe_class_memory); +%} + +instruct encode_ascii_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, + vRegD_V2 vtmp2, vRegD_V3 vtmp3, + iRegI_R0 result, rFlagsReg cr) +%{ + predicate(((EncodeISOArrayNode*)n)->is_ascii()); + match(Set result (EncodeISOArray src (Binary dst len))); + effect(USE_KILL src, USE_KILL dst, USE len, + KILL vtmp0, KILL vtmp1, KILL vtmp2, KILL vtmp3, KILL cr); + + format %{ "Encode ASCII array $src,$dst,$len -> $result" %} + ins_encode %{ + __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, + $result$$Register, true, + $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, + $vtmp2$$FloatRegister, $vtmp3$$FloatRegister); + %} + ins_pipe(pipe_class_memory); %} // ============================================================================ diff --git a/src/hotspot/cpu/aarch64/aarch64_neon.ad b/src/hotspot/cpu/aarch64/aarch64_neon.ad index b3cb6f5f25516bfbcf6db920ce603b7df6baab69..7c84a93583b10a8e9ff5c4526c84970f3e02419f 100644 --- a/src/hotspot/cpu/aarch64/aarch64_neon.ad +++ b/src/hotspot/cpu/aarch64/aarch64_neon.ad @@ -511,7 +511,7 @@ instruct vcvt2Dto2I(vecD dst, vecX src) "fcvtzdw rscratch1, $src\n\t" "fcvtzdw rscratch2, $dst\n\t" "fmovs $dst, rscratch1\n\t" - "mov $dst, T2S, 1, rscratch2\t#convert 2D to 2I vector" + "mov $dst, S, 1, rscratch2\t#convert 2D to 2I vector" %} ins_encode %{ __ ins(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), 0, 1); @@ -520,7 +520,7 @@ instruct vcvt2Dto2I(vecD dst, vecX src) __ fcvtzdw(rscratch1, as_FloatRegister($src$$reg)); __ fcvtzdw(rscratch2, as_FloatRegister($dst$$reg)); __ fmovs(as_FloatRegister($dst$$reg), rscratch1); - __ mov(as_FloatRegister($dst$$reg), __ T2S, 1, rscratch2); + __ mov(as_FloatRegister($dst$$reg), __ S, 1, rscratch2); %} ins_pipe(pipe_slow); %} @@ -1703,13 +1703,13 @@ instruct insert8B(vecD dst, vecD src, iRegIorL2I val, immI idx) match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T8B, $src, $src\n\t" - "mov $dst, T8B, $idx, $val\t# insert into vector(8B)" %} + "mov $dst, B, $idx, $val\t# insert into vector(8B)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } - __ mov(as_FloatRegister($dst$$reg), __ T8B, $idx$$constant, $val$$Register); + __ mov(as_FloatRegister($dst$$reg), __ B, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} @@ -1720,13 +1720,13 @@ instruct insert16B(vecX dst, vecX src, iRegIorL2I val, immI idx) match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T16B, $src, $src\n\t" - "mov $dst, T16B, $idx, $val\t# insert into vector(16B)" %} + "mov $dst, B, $idx, $val\t# insert into vector(16B)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } - __ mov(as_FloatRegister($dst$$reg), __ T16B, $idx$$constant, $val$$Register); + __ mov(as_FloatRegister($dst$$reg), __ B, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} @@ -1737,13 +1737,13 @@ instruct insert4S(vecD dst, vecD src, iRegIorL2I val, immI idx) match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T8B, $src, $src\n\t" - "mov $dst, T4H, $idx, $val\t# insert into vector(4S)" %} + "mov $dst, H, $idx, $val\t# insert into vector(4S)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } - __ mov(as_FloatRegister($dst$$reg), __ T4H, $idx$$constant, $val$$Register); + __ mov(as_FloatRegister($dst$$reg), __ H, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} @@ -1754,13 +1754,13 @@ instruct insert8S(vecX dst, vecX src, iRegIorL2I val, immI idx) match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T16B, $src, $src\n\t" - "mov $dst, T8H, $idx, $val\t# insert into vector(8S)" %} + "mov $dst, H, $idx, $val\t# insert into vector(8S)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } - __ mov(as_FloatRegister($dst$$reg), __ T8H, $idx$$constant, $val$$Register); + __ mov(as_FloatRegister($dst$$reg), __ H, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} @@ -1771,13 +1771,13 @@ instruct insert2I(vecD dst, vecD src, iRegIorL2I val, immI idx) match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T8B, $src, $src\n\t" - "mov $dst, T2S, $idx, $val\t# insert into vector(2I)" %} + "mov $dst, S, $idx, $val\t# insert into vector(2I)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } - __ mov(as_FloatRegister($dst$$reg), __ T2S, $idx$$constant, $val$$Register); + __ mov(as_FloatRegister($dst$$reg), __ S, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} @@ -1788,13 +1788,13 @@ instruct insert4I(vecX dst, vecX src, iRegIorL2I val, immI idx) match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T16B, $src, $src\n\t" - "mov $dst, T4S, $idx, $val\t# insert into vector(4I)" %} + "mov $dst, S, $idx, $val\t# insert into vector(4I)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } - __ mov(as_FloatRegister($dst$$reg), __ T4S, $idx$$constant, $val$$Register); + __ mov(as_FloatRegister($dst$$reg), __ S, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} @@ -1805,13 +1805,13 @@ instruct insert2L(vecX dst, vecX src, iRegL val, immI idx) match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T16B, $src, $src\n\t" - "mov $dst, T2D, $idx, $val\t# insert into vector(2L)" %} + "mov $dst, D, $idx, $val\t# insert into vector(2L)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } - __ mov(as_FloatRegister($dst$$reg), __ T2D, $idx$$constant, $val$$Register); + __ mov(as_FloatRegister($dst$$reg), __ D, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} @@ -2044,11 +2044,11 @@ instruct vmul2L(vecX dst, vecX src1, vecX src2, iRegLNoSp tmp1, iRegLNoSp tmp2) __ umov($tmp1$$Register, as_FloatRegister($src1$$reg), __ D, 0); __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ D, 0); __ mul(as_Register($tmp2$$reg), as_Register($tmp2$$reg), as_Register($tmp1$$reg)); - __ mov(as_FloatRegister($dst$$reg), __ T2D, 0, $tmp2$$Register); + __ mov(as_FloatRegister($dst$$reg), __ D, 0, $tmp2$$Register); __ umov($tmp1$$Register, as_FloatRegister($src1$$reg), __ D, 1); __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ D, 1); __ mul(as_Register($tmp2$$reg), as_Register($tmp2$$reg), as_Register($tmp1$$reg)); - __ mov(as_FloatRegister($dst$$reg), __ T2D, 1, $tmp2$$Register); + __ mov(as_FloatRegister($dst$$reg), __ D, 1, $tmp2$$Register); %} ins_pipe(pipe_slow); %} @@ -5617,3 +5617,35 @@ instruct vmask_lasttrue16B(iRegINoSp dst, vecX src) %{ %} ins_pipe(pipe_slow); %} + +instruct vmask_tolong8B(iRegLNoSp dst, vecD src) %{ + match(Set dst (VectorMaskToLong src)); + ins_cost(5 * INSN_COST); + format %{ "vmask_tolong $dst, $src\t# convert mask to long (8B)" %} + ins_encode %{ + // Input "src" is a vector of boolean represented as + // bytes with 0x00/0x01 as element values. + + __ fmovd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); + __ bytemask_compress(as_Register($dst$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmask_tolong16B(iRegLNoSp dst, vecX src) %{ + match(Set dst (VectorMaskToLong src)); + ins_cost(11 * INSN_COST); + format %{ "vmask_tolong $dst, $src\t# convert mask to long (16B)" %} + ins_encode %{ + // Input "src" is a vector of boolean represented as + // bytes with 0x00/0x01 as element values. + + __ umov(as_Register($dst$$reg), as_FloatRegister($src$$reg), __ D, 0); + __ umov(rscratch1, as_FloatRegister($src$$reg), __ D, 1); + __ bytemask_compress(as_Register($dst$$reg)); + __ bytemask_compress(rscratch1); + __ orr(as_Register($dst$$reg), as_Register($dst$$reg), + rscratch1, Assembler::LSL, 8); + %} + ins_pipe(pipe_slow); +%} diff --git a/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 b/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 index ded6d0fd6d2eb961c88579e204d9cf2abec4d1b1..ff94bb002fafc0d6c831a9fea239a289dcec482d 100644 --- a/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 +++ b/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 @@ -296,7 +296,7 @@ instruct vcvt2Dto2I(vecD dst, vecX src) "fcvtzdw rscratch1, $src\n\t" "fcvtzdw rscratch2, $dst\n\t" "fmovs $dst, rscratch1\n\t" - "mov $dst, T2S, 1, rscratch2\t#convert 2D to 2I vector" + "mov $dst, S, 1, rscratch2\t#convert 2D to 2I vector" %} ins_encode %{ __ ins(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), 0, 1); @@ -305,7 +305,7 @@ instruct vcvt2Dto2I(vecD dst, vecX src) __ fcvtzdw(rscratch1, as_FloatRegister($src$$reg)); __ fcvtzdw(rscratch2, as_FloatRegister($dst$$reg)); __ fmovs(as_FloatRegister($dst$$reg), rscratch1); - __ mov(as_FloatRegister($dst$$reg), __ T2S, 1, rscratch2); + __ mov(as_FloatRegister($dst$$reg), __ S, 1, rscratch2); %} ins_pipe(pipe_slow); %} @@ -868,13 +868,13 @@ instruct insert$1$2`'(vec$3 dst, vec$3 src, iReg$4`'ORL2I($4) val, immI idx) match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T$5, $src, $src\n\t" - "mov $dst, T$1`'iTYPE2SIMD($2), $idx, $val\t# insert into vector($1$2)" %} + "mov $dst, iTYPE2SIMD($2), $idx, $val\t# insert into vector($1$2)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T$5, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } - __ mov(as_FloatRegister($dst$$reg), __ T$1`'iTYPE2SIMD($2), $idx$$constant, $val$$Register); + __ mov(as_FloatRegister($dst$$reg), __ iTYPE2SIMD($2), $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %}')dnl @@ -1003,11 +1003,11 @@ instruct vmul2L(vecX dst, vecX src1, vecX src2, iRegLNoSp tmp1, iRegLNoSp tmp2) __ umov($tmp1$$Register, as_FloatRegister($src1$$reg), __ D, 0); __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ D, 0); __ mul(as_Register($tmp2$$reg), as_Register($tmp2$$reg), as_Register($tmp1$$reg)); - __ mov(as_FloatRegister($dst$$reg), __ T2D, 0, $tmp2$$Register); + __ mov(as_FloatRegister($dst$$reg), __ D, 0, $tmp2$$Register); __ umov($tmp1$$Register, as_FloatRegister($src1$$reg), __ D, 1); __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ D, 1); __ mul(as_Register($tmp2$$reg), as_Register($tmp2$$reg), as_Register($tmp1$$reg)); - __ mov(as_FloatRegister($dst$$reg), __ T2D, 1, $tmp2$$Register); + __ mov(as_FloatRegister($dst$$reg), __ D, 1, $tmp2$$Register); %} ins_pipe(pipe_slow); %} @@ -2481,3 +2481,35 @@ instruct vmask_lasttrue16B(iRegINoSp dst, vecX src) %{ %} ins_pipe(pipe_slow); %} + +instruct vmask_tolong8B(iRegLNoSp dst, vecD src) %{ + match(Set dst (VectorMaskToLong src)); + ins_cost(5 * INSN_COST); + format %{ "vmask_tolong $dst, $src\t# convert mask to long (8B)" %} + ins_encode %{ + // Input "src" is a vector of boolean represented as + // bytes with 0x00/0x01 as element values. + + __ fmovd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); + __ bytemask_compress(as_Register($dst$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmask_tolong16B(iRegLNoSp dst, vecX src) %{ + match(Set dst (VectorMaskToLong src)); + ins_cost(11 * INSN_COST); + format %{ "vmask_tolong $dst, $src\t# convert mask to long (16B)" %} + ins_encode %{ + // Input "src" is a vector of boolean represented as + // bytes with 0x00/0x01 as element values. + + __ umov(as_Register($dst$$reg), as_FloatRegister($src$$reg), __ D, 0); + __ umov(rscratch1, as_FloatRegister($src$$reg), __ D, 1); + __ bytemask_compress(as_Register($dst$$reg)); + __ bytemask_compress(rscratch1); + __ orr(as_Register($dst$$reg), as_Register($dst$$reg), + rscratch1, Assembler::LSL, 8); + %} + ins_pipe(pipe_slow); +%} diff --git a/src/hotspot/cpu/aarch64/aarch64_sve.ad b/src/hotspot/cpu/aarch64/aarch64_sve.ad index 6ad2d68526c8e175f4aad69a9fd7cbfc4dcf3184..19c59afaca261969ffd30f10b43541cf574a1b7f 100644 --- a/src/hotspot/cpu/aarch64/aarch64_sve.ad +++ b/src/hotspot/cpu/aarch64/aarch64_sve.ad @@ -411,13 +411,13 @@ instruct storeV_masked_partial(vReg src, vmemA mem, pRegGov pg, pRegGov pgtmp, r ins_pipe(pipe_slow); %} -// maskAll +// maskAll (full or partial predicate size) instruct vmaskAll_immI(pRegGov dst, immI src) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); ins_cost(SVE_COST); - format %{ "sve_ptrue/sve_pfalse $dst\t# mask all (sve) (B/H/S)" %} + format %{ "sve_ptrue_lanecnt/sve_pfalse $dst\t# mask all (sve) (B/H/S)" %} ins_encode %{ int con = (int)$src$$constant; if (con == 0) { @@ -425,7 +425,8 @@ instruct vmaskAll_immI(pRegGov dst, immI src) %{ } else { assert(con == -1, "invalid constant value for mask"); BasicType bt = Matcher::vector_element_basic_type(this); - __ sve_ptrue(as_PRegister($dst$$reg), __ elemType_to_regVariant(bt)); + __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), __ elemType_to_regVariant(bt), + Matcher::vector_length(this)); } %} ins_pipe(pipe_slow); @@ -435,14 +436,22 @@ instruct vmaskAllI(pRegGov dst, iRegIorL2I src, vReg tmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); effect(TEMP tmp, KILL cr); - ins_cost(2 * SVE_COST); + ins_cost(3 * SVE_COST); format %{ "sve_dup $tmp, $src\n\t" - "sve_cmpne $dst, $tmp, 0\t# mask all (sve) (B/H/S)" %} + "sve_ptrue_lanecnt $dst\n\t" + "sve_cmpne $dst, $dst, $tmp, 0\t# mask all (sve) (B/H/S)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); __ sve_dup(as_FloatRegister($tmp$$reg), size, as_Register($src$$reg)); - __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); + if (length_in_bytes < MaxVectorSize) { + __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), size, Matcher::vector_length(this)); + __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, + as_PRegister($dst$$reg), as_FloatRegister($tmp$$reg), 0); + } else { + __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); + } %} ins_pipe(pipe_slow); %} @@ -451,7 +460,7 @@ instruct vmaskAll_immL(pRegGov dst, immL src) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); ins_cost(SVE_COST); - format %{ "sve_ptrue/sve_pfalse $dst\t# mask all (sve) (D)" %} + format %{ "sve_ptrue_lanecnt/sve_pfalse $dst\t# mask all (sve) (D)" %} ins_encode %{ long con = (long)$src$$constant; if (con == 0) { @@ -459,7 +468,8 @@ instruct vmaskAll_immL(pRegGov dst, immL src) %{ } else { assert(con == -1, "invalid constant value for mask"); BasicType bt = Matcher::vector_element_basic_type(this); - __ sve_ptrue(as_PRegister($dst$$reg), __ elemType_to_regVariant(bt)); + __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), __ elemType_to_regVariant(bt), + Matcher::vector_length(this)); } %} ins_pipe(pipe_slow); @@ -469,14 +479,22 @@ instruct vmaskAllL(pRegGov dst, iRegL src, vReg tmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); effect(TEMP tmp, KILL cr); - ins_cost(2 * SVE_COST); + ins_cost(3 * SVE_COST); format %{ "sve_dup $tmp, $src\n\t" - "sve_cmpne $dst, $tmp, 0\t# mask all (sve) (D)" %} + "sve_ptrue_lanecnt $dst\n\t" + "sve_cmpne $dst, $dst, $tmp, 0\t# mask all (sve) (D)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); __ sve_dup(as_FloatRegister($tmp$$reg), size, as_Register($src$$reg)); - __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); + if (length_in_bytes < MaxVectorSize) { + __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), size, Matcher::vector_length(this)); + __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, + as_PRegister($dst$$reg), as_FloatRegister($tmp$$reg), 0); + } else { + __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); + } %} ins_pipe(pipe_slow); %} @@ -3084,6 +3102,7 @@ instruct reduce_maxF_masked(vRegF dst, vRegF src1, vReg src2, pRegGov pg) %{ n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MaxReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); + effect(TEMP_DEF dst); format %{ "sve_reduce_maxF $dst, $src1, $pg, $src2\t# maxF reduction predicated (sve)" %} ins_encode %{ __ sve_fmaxv(as_FloatRegister($dst$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); @@ -3098,6 +3117,7 @@ instruct reduce_maxD_masked(vRegD dst, vRegD src1, vReg src2, pRegGov pg) %{ n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MaxReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); + effect(TEMP_DEF dst); format %{ "sve_reduce_maxD $dst, $src1, $pg, $src2\t# maxD reduction predicated (sve)" %} ins_encode %{ __ sve_fmaxv(as_FloatRegister($dst$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); @@ -3380,6 +3400,7 @@ instruct reduce_minF_masked(vRegF dst, vRegF src1, vReg src2, pRegGov pg) %{ n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MinReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); + effect(TEMP_DEF dst); format %{ "sve_reduce_minF $dst, $src1, $pg, $src2\t# minF reduction predicated (sve)" %} ins_encode %{ __ sve_fminv(as_FloatRegister($dst$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); @@ -3394,6 +3415,7 @@ instruct reduce_minD_masked(vRegD dst, vRegD src1, vReg src2, pRegGov pg) %{ n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MinReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); + effect(TEMP_DEF dst); format %{ "sve_reduce_minD $dst, $src1, $pg, $src2\t# minD reduction predicated (sve)" %} ins_encode %{ __ sve_fminv(as_FloatRegister($dst$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); @@ -5744,4 +5766,35 @@ instruct vmask_lasttrue_partial(iRegINoSp dst, pReg src, pReg ptmp, rFlagsReg cr __ sve_vmask_lasttrue($dst$$Register, bt, as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg)); %} ins_pipe(pipe_slow); -%} \ No newline at end of file +%} + +instruct vmask_tolong(iRegLNoSp dst, pReg src, vReg vtmp1, vReg vtmp2, pRegGov pgtmp, rFlagsReg cr) %{ + predicate(UseSVE > 0 && + n->in(1)->bottom_type()->is_vect()->length() <= 64); + match(Set dst (VectorMaskToLong src)); + effect(TEMP vtmp1, TEMP vtmp2, TEMP pgtmp, KILL cr); + ins_cost(13 * SVE_COST); + format %{ "vmask_tolong $dst, $src\t# vector mask tolong (sve)" %} + ins_encode %{ + __ sve_vmask_tolong(as_Register($dst$$reg), as_PRegister($src$$reg), + Matcher::vector_element_basic_type(this, $src), + Matcher::vector_length(this, $src), + as_FloatRegister($vtmp1$$reg), as_FloatRegister($vtmp2$$reg), + as_PRegister($pgtmp$$reg)); + %} + ins_pipe(pipe_slow); +%} +// ---------------------------- Vector mask generation --------------------------- +instruct vmask_gen(pRegGov pg, iRegL len, rFlagsReg cr) %{ + predicate(UseSVE > 0); + match(Set pg (VectorMaskGen len)); + effect(KILL cr); + ins_cost(SVE_COST); + format %{ "sve_whilelo $pg, zr, $len\t # sve" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + __ sve_whilelo(as_PRegister($pg$$reg), size, zr, as_Register($len$$reg)); + %} + ins_pipe(pipe_slow); +%} diff --git a/src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 b/src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 index 65de321a6e121407ae875b65482fe054cec2bfb6..a6a26ca97f5d524e8ef77d543f0ac8b2878ec827 100644 --- a/src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 +++ b/src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 @@ -356,7 +356,7 @@ instruct vmaskAll_imm$1(pRegGov dst, imm$1 src) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); ins_cost(SVE_COST); - format %{ "sve_ptrue/sve_pfalse $dst\t# mask all (sve) ($2)" %} + format %{ "sve_ptrue_lanecnt/sve_pfalse $dst\t# mask all (sve) ($2)" %} ins_encode %{ ifelse($1, `I', int, long) con = (ifelse($1, `I', int, long))$src$$constant; if (con == 0) { @@ -364,7 +364,8 @@ instruct vmaskAll_imm$1(pRegGov dst, imm$1 src) %{ } else { assert(con == -1, "invalid constant value for mask"); BasicType bt = Matcher::vector_element_basic_type(this); - __ sve_ptrue(as_PRegister($dst$$reg), __ elemType_to_regVariant(bt)); + __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), __ elemType_to_regVariant(bt), + Matcher::vector_length(this)); } %} ins_pipe(pipe_slow); @@ -377,19 +378,27 @@ instruct vmaskAll$1(pRegGov dst, ifelse($1, `I', iRegIorL2I, iRegL) src, vReg tm predicate(UseSVE > 0); match(Set dst (MaskAll src)); effect(TEMP tmp, KILL cr); - ins_cost(2 * SVE_COST); + ins_cost(3 * SVE_COST); format %{ "sve_dup $tmp, $src\n\t" - "sve_cmpne $dst, $tmp, 0\t# mask all (sve) ($2)" %} + "sve_ptrue_lanecnt $dst\n\t" + "sve_cmpne $dst, $dst, $tmp, 0\t# mask all (sve) ($2)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); __ sve_dup(as_FloatRegister($tmp$$reg), size, as_Register($src$$reg)); - __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); + if (length_in_bytes < MaxVectorSize) { + __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), size, Matcher::vector_length(this)); + __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, + as_PRegister($dst$$reg), as_FloatRegister($tmp$$reg), 0); + } else { + __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); + } %} ins_pipe(pipe_slow); %}')dnl dnl -// maskAll +// maskAll (full or partial predicate size) MASKALL_IMM(I, B/H/S) MASKALL(I, B/H/S) MASKALL_IMM(L, D) @@ -1807,6 +1816,7 @@ instruct reduce_$1$2_masked($5 dst, $5 src1, vReg src2, pRegGov pg) %{ n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (translit($1, `m', `M')ReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); + effect(TEMP_DEF dst); format %{ "sve_reduce_$1$2 $dst, $src1, $pg, $src2\t# $1$2 reduction predicated (sve)" %} ins_encode %{ __ sve_f$1v(as_FloatRegister($dst$$reg), __ $4, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); @@ -3174,4 +3184,36 @@ instruct vmask_lasttrue_partial(iRegINoSp dst, pReg src, pReg ptmp, rFlagsReg cr __ sve_vmask_lasttrue($dst$$Register, bt, as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg)); %} ins_pipe(pipe_slow); +%} + +instruct vmask_tolong(iRegLNoSp dst, pReg src, vReg vtmp1, vReg vtmp2, pRegGov pgtmp, rFlagsReg cr) %{ + predicate(UseSVE > 0 && + n->in(1)->bottom_type()->is_vect()->length() <= 64); + match(Set dst (VectorMaskToLong src)); + effect(TEMP vtmp1, TEMP vtmp2, TEMP pgtmp, KILL cr); + ins_cost(13 * SVE_COST); + format %{ "vmask_tolong $dst, $src\t# vector mask tolong (sve)" %} + ins_encode %{ + __ sve_vmask_tolong(as_Register($dst$$reg), as_PRegister($src$$reg), + Matcher::vector_element_basic_type(this, $src), + Matcher::vector_length(this, $src), + as_FloatRegister($vtmp1$$reg), as_FloatRegister($vtmp2$$reg), + as_PRegister($pgtmp$$reg)); + %} + ins_pipe(pipe_slow); %}dnl + +// ---------------------------- Vector mask generation --------------------------- +instruct vmask_gen(pRegGov pg, iRegL len, rFlagsReg cr) %{ + predicate(UseSVE > 0); + match(Set pg (VectorMaskGen len)); + effect(KILL cr); + ins_cost(SVE_COST); + format %{ "sve_whilelo $pg, zr, $len\t # sve" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + __ sve_whilelo(as_PRegister($pg$$reg), size, zr, as_Register($len$$reg)); + %} + ins_pipe(pipe_slow); +%} diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index 1bf593b4524a598fd7e5ba1506adb9aa44dd5e56..3717756d9d95b1425e3fdf55fac9a986f10f1a29 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,6 +27,7 @@ #define CPU_AARCH64_ASSEMBLER_AARCH64_HPP #include "asm/register.hpp" +#include "metaprogramming/enableIf.hpp" #ifdef __GNUC__ @@ -404,18 +405,11 @@ class Address { : _mode(no_mode) { } Address(Register r) : _base(r), _index(noreg), _offset(0), _mode(base_plus_offset), _target(0) { } - Address(Register r, int o) - : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } - Address(Register r, long o) - : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } - Address(Register r, long long o) - : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } - Address(Register r, unsigned int o) - : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } - Address(Register r, unsigned long o) - : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } - Address(Register r, unsigned long long o) - : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } + + template::value)> + Address(Register r, T o) + : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) {} + Address(Register r, ByteSize disp) : Address(r, in_bytes(disp)) { } Address(Register r, Register r1, extend ext = lsl()) @@ -1726,7 +1720,7 @@ void mvnw(Register Rd, Register Rm, #define INSN(NAME, op) \ void NAME(Register Rn, Register Rm, int imm, Condition cond) { \ - int regNumber = (Rm == zr ? 31 : (uintptr_t)Rm); \ + int regNumber = (Rm == zr ? 31 : Rm->encoding()); \ conditional_compare(op, 0, 0, 0, Rn, regNumber, imm, cond); \ } \ \ @@ -2424,6 +2418,12 @@ public: INSN(cnt, 0, 0b100000010110, 0); // accepted arrangements: T8B, T16B INSN(uaddlp, 1, 0b100000001010, 2); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S INSN(uaddlv, 1, 0b110000001110, 1); // accepted arrangements: T8B, T16B, T4H, T8H, T4S + // Zero compare. + INSN(cmeq, 0, 0b100000100110, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D + INSN(cmge, 1, 0b100000100010, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D + INSN(cmgt, 0, 0b100000100010, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D + INSN(cmle, 1, 0b100000100110, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D + INSN(cmlt, 0, 0b100000101010, 3); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D #undef INSN @@ -2756,20 +2756,18 @@ public: // Move from general purpose register // mov Vd.T[index], Rn - void mov(FloatRegister Vd, SIMD_Arrangement T, int index, Register Xn) { + void mov(FloatRegister Vd, SIMD_RegVariant T, int index, Register Xn) { + guarantee(T != Q, "invalid register variant"); starti; - f(0b01001110000, 31, 21), f(((1 << (T >> 1)) | (index << ((T >> 1) + 1))), 20, 16); + f(0b01001110000, 31, 21), f(((1 << T) | (index << (T + 1))), 20, 16); f(0b000111, 15, 10), zrf(Xn, 5), rf(Vd, 0); } // Move to general purpose register // mov Rd, Vn.T[index] - void mov(Register Xd, FloatRegister Vn, SIMD_Arrangement T, int index) { - guarantee(T >= T2S && T < T1Q, "only D and S arrangements are supported"); - starti; - f(0, 31), f((T >= T1D) ? 1:0, 30), f(0b001110000, 29, 21); - f(((1 << (T >> 1)) | (index << ((T >> 1) + 1))), 20, 16); - f(0b001111, 15, 10), rf(Vn, 5), rf(Xd, 0); + void mov(Register Xd, FloatRegister Vn, SIMD_RegVariant T, int index) { + guarantee(T == S || T == D, "invalid register variant"); + umov(Xd, Vn, T, index); } private: diff --git a/src/hotspot/cpu/aarch64/bytes_aarch64.hpp b/src/hotspot/cpu/aarch64/bytes_aarch64.hpp index acb2e493a9a6bfcdccfccae5e4d043b2da85e7ba..672f03b93a961ccdecffbe31f8b9bc925adec141 100644 --- a/src/hotspot/cpu/aarch64/bytes_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/bytes_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ #ifndef CPU_AARCH64_BYTES_AARCH64_HPP #define CPU_AARCH64_BYTES_AARCH64_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Bytes: AllStatic { public: diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp index fead8af7d1bbd06c073226749caf16b4dd3ff4d5..6f91b1539a6df7e336f455970a23db93db446711 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp @@ -438,7 +438,11 @@ int LIR_Assembler::emit_unwind_handler() { if (method()->is_synchronized()) { monitor_address(0, FrameMap::r0_opr); stub = new MonitorExitStub(FrameMap::r0_opr, true, 0); - __ unlock_object(r5, r4, r0, *stub->entry()); + if (UseHeavyMonitors) { + __ b(*stub->entry()); + } else { + __ unlock_object(r5, r4, r0, *stub->entry()); + } __ bind(*stub->continuation()); } @@ -2562,7 +2566,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) { Register obj = op->obj_opr()->as_register(); // may not be an oop Register hdr = op->hdr_opr()->as_register(); Register lock = op->lock_opr()->as_register(); - if (!UseFastLocking) { + if (UseHeavyMonitors) { __ b(*op->stub()->entry()); } else if (op->code() == lir_lock) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); diff --git a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp index 0a97872900e8940e33d80f7ce23fffcb0e8ee0f1..9f60e493d6acfe2c37a8d8abb96708f815342a26 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp @@ -148,7 +148,7 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, if (index->is_constant()) { LIR_Const *constant = index->as_constant_ptr(); if (constant->type() == T_INT) { - large_disp += index->as_jint() << shift; + large_disp += ((intx)index->as_jint()) << shift; } else { assert(constant->type() == T_LONG, "should be"); jlong c = index->as_jlong() << shift; @@ -194,7 +194,7 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, if (large_disp == 0 && index->is_register()) { return new LIR_Address(base, index, type); } else { - assert(Address::offset_ok_for_immed(large_disp, 0), "must be"); + assert(Address::offset_ok_for_immed(large_disp, shift), "failed for large_disp: " INTPTR_FORMAT " and shift %d", large_disp, shift); return new LIR_Address(base, large_disp, type); } } @@ -204,24 +204,7 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type); int elem_size = type2aelembytes(type); int shift = exact_log2(elem_size); - - LIR_Address* addr; - if (index_opr->is_constant()) { - addr = new LIR_Address(array_opr, - offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); - } else { - if (offset_in_bytes) { - LIR_Opr tmp = new_pointer_register(); - __ add(array_opr, LIR_OprFact::intConst(offset_in_bytes), tmp); - array_opr = tmp; - offset_in_bytes = 0; - } - addr = new LIR_Address(array_opr, - index_opr, - LIR_Address::scale(type), - offset_in_bytes, type); - } - return addr; + return generate_address(array_opr, index_opr, shift, offset_in_bytes, type); } LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { diff --git a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp index 661fad89e47edf1289274d09d6929915b60d7b53..54821ea4b0a9184c73fac1a7f618d24aea7dd644 100644 --- a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp @@ -304,7 +304,7 @@ void C1_MacroAssembler::remove_frame(int framesize) { } -void C1_MacroAssembler::verified_entry() { +void C1_MacroAssembler::verified_entry(bool breakAtEntry) { // If we have to make this method not-entrant we'll overwrite its // first instruction with a jump. For this action to be legal we // must ensure that this first instruction is a B, BL, NOP, BKPT, diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index f8289a4bda54615535e655158c1639d01f3ca7ca..ad170ddea2a12fa7e98925ed248c2345a3993f23 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -946,6 +946,48 @@ void C2_MacroAssembler::neon_compare(FloatRegister dst, BasicType bt, FloatRegis } } +// Compress the least significant bit of each byte to the rightmost and clear +// the higher garbage bits. +void C2_MacroAssembler::bytemask_compress(Register dst) { + // Example input, dst = 0x01 00 00 00 01 01 00 01 + // The "??" bytes are garbage. + orr(dst, dst, dst, Assembler::LSR, 7); // dst = 0x?? 02 ?? 00 ?? 03 ?? 01 + orr(dst, dst, dst, Assembler::LSR, 14); // dst = 0x????????08 ??????0D + orr(dst, dst, dst, Assembler::LSR, 28); // dst = 0x????????????????8D + andr(dst, dst, 0xff); // dst = 0x8D +} + +// Pack the lowest-numbered bit of each mask element in src into a long value +// in dst, at most the first 64 lane elements. +// Clobbers: rscratch1 +void C2_MacroAssembler::sve_vmask_tolong(Register dst, PRegister src, BasicType bt, int lane_cnt, + FloatRegister vtmp1, FloatRegister vtmp2, PRegister pgtmp) { + assert(pgtmp->is_governing(), "This register has to be a governing predicate register."); + assert(lane_cnt <= 64 && is_power_of_2(lane_cnt), "Unsupported lane count"); + assert_different_registers(dst, rscratch1); + + Assembler::SIMD_RegVariant size = elemType_to_regVariant(bt); + + // Pack the mask into vector with sequential bytes. + sve_cpy(vtmp1, size, src, 1, false); + if (bt != T_BYTE) { + sve_vector_narrow(vtmp1, B, vtmp1, size, vtmp2); + } + + // Compress the lowest 8 bytes. + fmovd(dst, vtmp1); + bytemask_compress(dst); + if (lane_cnt <= 8) return; + + // Repeat on higher bytes and join the results. + // Compress 8 bytes in each iteration. + for (int idx = 1; idx < (lane_cnt / 8); idx++) { + idx == 1 ? fmovhid(rscratch1, vtmp1) : sve_extract(rscratch1, D, pgtmp, vtmp1, idx); + bytemask_compress(rscratch1); + orr(dst, dst, rscratch1, Assembler::LSL, idx << 3); + } +} + void C2_MacroAssembler::sve_compare(PRegister pd, BasicType bt, PRegister pg, FloatRegister zn, FloatRegister zm, int cond) { assert(pg->is_governing(), "This register has to be a governing predicate register"); @@ -1021,6 +1063,7 @@ void C2_MacroAssembler::sve_vector_narrow(FloatRegister dst, SIMD_RegVariant dst FloatRegister src, SIMD_RegVariant src_size, FloatRegister tmp) { assert(dst_size < src_size && dst_size <= S && src_size <= D, "invalid element size"); + assert_different_registers(src, tmp); sve_dup(tmp, src_size, 0); if (src_size == D) { switch (dst_size) { @@ -1189,3 +1232,39 @@ void C2_MacroAssembler::sve_reduce_integral(int opc, Register dst, BasicType bt, } } } + +// Set elements of the dst predicate to true if the element number is +// in the range of [0, lane_cnt), or to false otherwise. +void C2_MacroAssembler::sve_ptrue_lanecnt(PRegister dst, SIMD_RegVariant size, int lane_cnt) { + assert(size != Q, "invalid size"); + switch(lane_cnt) { + case 1: /* VL1 */ + case 2: /* VL2 */ + case 3: /* VL3 */ + case 4: /* VL4 */ + case 5: /* VL5 */ + case 6: /* VL6 */ + case 7: /* VL7 */ + case 8: /* VL8 */ + sve_ptrue(dst, size, lane_cnt); + break; + case 16: + sve_ptrue(dst, size, /* VL16 */ 0b01001); + break; + case 32: + sve_ptrue(dst, size, /* VL32 */ 0b01010); + break; + case 64: + sve_ptrue(dst, size, /* VL64 */ 0b01011); + break; + case 128: + sve_ptrue(dst, size, /* VL128 */ 0b01100); + break; + case 256: + sve_ptrue(dst, size, /* VL256 */ 0b01101); + break; + default: + assert(false, "unsupported"); + ShouldNotReachHere(); + } +} diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp index 2c9d4b59ecee6da32b3121f65cc475a4a23759e6..d7af599dd28dac3c04777d9c33fc2a305957390f 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp @@ -55,6 +55,15 @@ FloatRegister ztmp1, FloatRegister ztmp2, PRegister pgtmp, PRegister ptmp, bool isL); + // Compress the least significant bit of each byte to the rightmost and clear + // the higher garbage bits. + void bytemask_compress(Register dst); + + // Pack the lowest-numbered bit of each mask element in src into a long value + // in dst, at most the first 64 lane elements. + void sve_vmask_tolong(Register dst, PRegister src, BasicType bt, int lane_cnt, + FloatRegister vtmp1, FloatRegister vtmp2, PRegister pgtmp); + // SIMD&FP comparison void neon_compare(FloatRegister dst, BasicType bt, FloatRegister src1, FloatRegister src2, int cond, bool isQ); @@ -79,6 +88,10 @@ void sve_reduce_integral(int opc, Register dst, BasicType bt, Register src1, FloatRegister src2, PRegister pg, FloatRegister tmp); + // Set elements of the dst predicate to true if the element number is + // in the range of [0, lane_cnt), or to false otherwise. + void sve_ptrue_lanecnt(PRegister dst, SIMD_RegVariant size, int lane_cnt); + // Generate predicate through whilelo, by comparing ZR with an unsigned // immediate. rscratch1 will be clobbered. inline void sve_whilelo_zr_imm(PRegister pd, SIMD_RegVariant size, uint imm) { diff --git a/src/hotspot/cpu/aarch64/copy_aarch64.hpp b/src/hotspot/cpu/aarch64/copy_aarch64.hpp index 3912ee086cf0c4a093094f59da801c8863fb6736..0ff9ace59cc2f3761c7aed3f433dc77b32d7e2e3 100644 --- a/src/hotspot/cpu/aarch64/copy_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/copy_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -52,4 +52,166 @@ static void pd_zero_to_bytes(void* to, size_t count) { (void)memset(to, 0, count); } +#ifndef _WINDOWS + +#define COPY_SMALL(from, to, count) \ +{ \ + long tmp0, tmp1, tmp2, tmp3; \ + long tmp4, tmp5, tmp6, tmp7; \ + __asm volatile( \ +" adr %[t0], 0f;\n" \ +" add %[t0], %[t0], %[cnt], lsl #5;\n" \ +" br %[t0];\n" \ +" .align 5;\n" \ +"0:" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldr %[t0], [%[s], #0];\n" \ +" str %[t0], [%[d], #0];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldr %[t2], [%[s], #16];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" str %[t2], [%[d], #16];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldp %[t2], %[t3], [%[s], #16];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" stp %[t2], %[t3], [%[d], #16];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldp %[t2], %[t3], [%[s], #16];\n" \ +" ldr %[t4], [%[s], #32];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" stp %[t2], %[t3], [%[d], #16];\n" \ +" str %[t4], [%[d], #32];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldp %[t2], %[t3], [%[s], #16];\n" \ +" ldp %[t4], %[t5], [%[s], #32];\n" \ +"2:" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" stp %[t2], %[t3], [%[d], #16];\n" \ +" stp %[t4], %[t5], [%[d], #32];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldr %[t6], [%[s], #0];\n" \ +" ldp %[t0], %[t1], [%[s], #8];\n" \ +" ldp %[t2], %[t3], [%[s], #24];\n" \ +" ldp %[t4], %[t5], [%[s], #40];\n" \ +" str %[t6], [%[d]], #8;\n" \ +" b 2b;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldp %[t2], %[t3], [%[s], #16];\n" \ +" ldp %[t4], %[t5], [%[s], #32];\n" \ +" ldp %[t6], %[t7], [%[s], #48];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" stp %[t2], %[t3], [%[d], #16];\n" \ +" stp %[t4], %[t5], [%[d], #32];\n" \ +" stp %[t6], %[t7], [%[d], #48];\n" \ +"1:" \ + \ + : [s]"+r"(from), [d]"+r"(to), [cnt]"+r"(count), \ + [t0]"=&r"(tmp0), [t1]"=&r"(tmp1), [t2]"=&r"(tmp2), [t3]"=&r"(tmp3), \ + [t4]"=&r"(tmp4), [t5]"=&r"(tmp5), [t6]"=&r"(tmp6), [t7]"=&r"(tmp7) \ + : \ + : "memory", "cc"); \ +} + +static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); + if (__builtin_expect(count <= 8, 1)) { + COPY_SMALL(from, to, count); + return; + } + _Copy_conjoint_words(from, to, count); +} + +static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + if (__builtin_constant_p(count)) { + memcpy(to, from, count * sizeof(HeapWord)); + return; + } + __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); + if (__builtin_expect(count <= 8, 1)) { + COPY_SMALL(from, to, count); + return; + } + _Copy_disjoint_words(from, to, count); +} + +static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { + __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); + if (__builtin_expect(count <= 8, 1)) { + COPY_SMALL(from, to, count); + return; + } + _Copy_disjoint_words(from, to, count); +} + +static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_words(from, to, count); +} + +static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + pd_disjoint_words(from, to, count); +} + +static void pd_conjoint_bytes(const void* from, void* to, size_t count) { + (void)memmove(to, from, count); +} + +static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { + pd_conjoint_bytes(from, to, count); +} + +static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { + _Copy_conjoint_jshorts_atomic(from, to, count); +} + +static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { + _Copy_conjoint_jints_atomic(from, to, count); +} + +static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { + _Copy_conjoint_jlongs_atomic(from, to, count); +} + +static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); +} + +static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_bytes(from, to, count); +} + +static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jshorts(from, to, count); +} + +static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jints(from, to, count); +} + +static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jlongs(from, to, count); +} + +static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { + assert(!UseCompressedOops, "foo!"); + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_arrayof_conjoint_jlongs(from, to, count); +} +#endif // _WINDOWS + #endif // CPU_AARCH64_COPY_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp b/src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp index d08afc79a52451ed082ce5dafb7e2c24e8c4ec20..4334a395571a0b215ded547cbdd9d0e114b2d7ea 100644 --- a/src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/foreign_globals_aarch64.cpp @@ -45,7 +45,7 @@ bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const { const ABIDescriptor ForeignGlobals::parse_abi_descriptor_impl(jobject jabi) const { oop abi_oop = JNIHandles::resolve_non_null(jabi); ABIDescriptor abi; - const Register (*to_Register)(int) = as_Register; + constexpr Register (*to_Register)(int) = as_Register; objArrayOop inputStorage = cast(abi_oop->obj_field(ABI.inputStorage_offset)); loadArray(inputStorage, INTEGER_TYPE, abi._integer_argument_registers, to_Register); diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.cpp b/src/hotspot/cpu/aarch64/frame_aarch64.cpp index 35cc1ee1f8402e4c52ed8dfe3af2a9686aa9db5e..cb59e8b12afc79f32b5e3793d216ed49b4beb000 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -358,6 +358,7 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const { assert(map->include_argument_oops(), "should be set by clear"); vmassert(jfa->last_Java_pc() != NULL, "not walkable"); frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc()); + fr.set_sp_is_trusted(); return fr; } @@ -463,12 +464,21 @@ frame frame::sender_for_interpreter_frame(RegisterMap* map) const { //------------------------------------------------------------------------------ // frame::sender_for_compiled_frame frame frame::sender_for_compiled_frame(RegisterMap* map) const { - // we cannot rely upon the last fp having been saved to the thread - // in C2 code but it will have been pushed onto the stack. so we - // have to find it relative to the unextended sp + // When the sp of a compiled frame is correct, we can get the correct sender sp + // by unextended sp + frame size. + // For the following two scenarios, the sp of a compiled frame is correct: + // a) This compiled frame is built from the anchor. + // b) This compiled frame is built from a callee frame, and the callee frame can + // calculate its sp correctly. + // + // For b), if the callee frame is a native code frame (such as leaf call), the sp of + // the compiled frame cannot be calculated correctly. There is currently no suitable + // solution to solve this problem perfectly. But when PreserveFramePointer is enabled, + // we can get the correct sender sp by fp + 2 (that is sender_sp()). assert(_cb->frame_size() >= 0, "must have non-zero frame size"); - intptr_t* l_sender_sp = unextended_sp() + _cb->frame_size(); + intptr_t* l_sender_sp = (!PreserveFramePointer || _sp_is_trusted) ? unextended_sp() + _cb->frame_size() + : sender_sp(); intptr_t* unextended_sp = l_sender_sp; // the return_address is always the word on the stack diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.hpp b/src/hotspot/cpu/aarch64/frame_aarch64.hpp index 716c0ff9f1a59ee88bb2f045fc82d6589c96e021..95f470befa021ab433baf524045ece4c55d17786 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -124,6 +124,11 @@ intptr_t* _unextended_sp; void adjust_unextended_sp(); + // true means _sp value is correct and we can use it to get the sender's sp + // of the compiled frame, otherwise, _sp value may be invalid and we can use + // _fp to get the sender's sp if PreserveFramePointer is enabled. + bool _sp_is_trusted; + intptr_t* ptr_at_addr(int offset) const { return (intptr_t*) addr_at(offset); } @@ -165,4 +170,6 @@ // returns the sending frame, without applying any barriers frame sender_raw(RegisterMap* map) const; + void set_sp_is_trusted() { _sp_is_trusted = true; } + #endif // CPU_AARCH64_FRAME_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp index 5be02aa57e7a3c8c56c21c19fe79c46060b08f92..b0fe436ca59609a5475c4503b755675a0c55bd58 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,6 +41,7 @@ inline frame::frame() { _fp = NULL; _cb = NULL; _deopt_state = unknown; + _sp_is_trusted = false; } static int spin; @@ -64,6 +65,7 @@ inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) { } else { _deopt_state = not_deoptimized; } + _sp_is_trusted = false; } inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) { @@ -91,6 +93,7 @@ inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address } else { _deopt_state = not_deoptimized; } + _sp_is_trusted = false; } inline frame::frame(intptr_t* sp, intptr_t* fp) { @@ -122,6 +125,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) { } else { _deopt_state = not_deoptimized; } + _sp_is_trusted = false; } // Accessors diff --git a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp index 77a6dc8b7396ff06d5524435c7a9c3c0b217f5e9..cd689b008e05ee143542d98e48c225600785892b 100644 --- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp @@ -222,7 +222,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, const Register card_addr = tmp; - __ lsr(card_addr, store_addr, CardTable::card_shift); + __ lsr(card_addr, store_addr, CardTable::card_shift()); // get the address of the card __ load_byte_map_base(tmp2); @@ -444,7 +444,7 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* assert_different_registers(card_offset, byte_map_base, rscratch1); __ load_parameter(0, card_offset); - __ lsr(card_offset, card_offset, CardTable::card_shift); + __ lsr(card_offset, card_offset, CardTable::card_shift()); __ load_byte_map_base(byte_map_base); __ ldrb(rscratch1, Address(byte_map_base, card_offset)); __ cmpw(rscratch1, (int)G1CardTable::g1_young_card_val()); diff --git a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp index fb677828e20e640df27cc874e6183f7a59036eed..f94f2b9c902a018c583f0fe79e68ba988d3ec448 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp @@ -38,7 +38,7 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob BarrierSet* bs = BarrierSet::barrier_set(); assert(bs->kind() == BarrierSet::CardTableBarrierSet, "Wrong barrier set kind"); - __ lsr(obj, obj, CardTable::card_shift); + __ lsr(obj, obj, CardTable::card_shift()); assert(CardTable::dirty_card_val() == 0, "must be"); @@ -64,8 +64,8 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ lea(end, Address(start, count, Address::lsl(LogBytesPerHeapOop))); // end = start + count << LogBytesPerHeapOop __ sub(end, end, BytesPerHeapOop); // last element address to make inclusive - __ lsr(start, start, CardTable::card_shift); - __ lsr(end, end, CardTable::card_shift); + __ lsr(start, start, CardTable::card_shift()); + __ lsr(end, end, CardTable::card_shift()); __ sub(count, end, start); // number of bytes to copy __ load_byte_map_base(scratch); diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp index 3c779bb11b15cfe961ccad89c6d4d78abe586269..fe88f7b887c1958e1368ed5eb6e0da74729feb39 100644 --- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp @@ -67,4 +67,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false; #define NOT_R18_RESERVED(code) code #endif +#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY + #endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp b/src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp index 4254cdf4cfd575a0c57756ae6ca8f4cb59cbccc3..8d20a6a170152042c346d148347907b1c115c4f1 100644 --- a/src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,7 +27,7 @@ #define CPU_AARCH64_JNITYPES_AARCH64_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive jni diff --git a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp index 17b9780129db00d13f169645e305c7ffba0c52a0..aacca26a36c8843b80244dc4c9cdf00651767ca4 100644 --- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp @@ -186,7 +186,7 @@ VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) { if (jvmci_reg < RegisterImpl::number_of_registers) { return as_Register(jvmci_reg)->as_VMReg(); } else { - jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers_for_jvmci; + jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_declared_registers; if (floatRegisterNumber >= 0 && floatRegisterNumber < FloatRegisterImpl::number_of_registers) { return as_FloatRegister(floatRegisterNumber)->as_VMReg(); } diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 07e3fdad17b16ac2c7b0614358884651e92a2386..69124c299c15145aef0debd8e49596f396dd35d6 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,6 +29,7 @@ #include "jvm.h" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" +#include "ci/ciEnv.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/cardTableBarrierSet.hpp" @@ -159,8 +160,7 @@ int MacroAssembler::pd_patch_instruction_size(address branch, address target) { Instruction_aarch64::patch(branch+8, 20, 5, (dest >>= 16) & 0xffff); assert(target_addr_for_insn(branch) == target, "should be"); instructions = 3; - } else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 && - Instruction_aarch64::extract(insn, 4, 0) == 0b11111) { + } else if (NativeInstruction::is_ldrw_to_zr(address(&insn))) { // nothing to do assert(target == 0, "did not expect to relocate target for polling page load"); } else { @@ -283,15 +283,19 @@ address MacroAssembler::target_addr_for_insn(address insn_addr, unsigned insn) { return address(uint64_t(Instruction_aarch64::extract(insns[0], 20, 5)) + (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16) + (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32)); - } else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 && - Instruction_aarch64::extract(insn, 4, 0) == 0b11111) { - return 0; } else { ShouldNotReachHere(); } return address(((uint64_t)insn_addr + (offset << 2))); } +address MacroAssembler::target_addr_for_insn_or_null(address insn_addr, unsigned insn) { + if (NativeInstruction::is_ldrw_to_zr(address(&insn))) { + return 0; + } + return MacroAssembler::target_addr_for_insn(insn_addr, insn); +} + void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod) { if (acquire) { lea(rscratch1, Address(rthread, JavaThread::polling_word_offset())); @@ -3367,7 +3371,7 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, ld1r(v5, T2D, post(tmp, 8)); ld1r(v6, T2D, post(tmp, 8)); ld1r(v7, T2D, post(tmp, 8)); - mov(v16, T4S, 0, crc); + mov(v16, S, 0, crc); eor(v0, T16B, v0, v16); sub(len, len, 64); @@ -3471,16 +3475,16 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, br(Assembler::GE, L_fold); mov(crc, 0); - mov(tmp, v0, T1D, 0); + mov(tmp, v0, D, 0); update_word_crc32(crc, tmp, tmp2, table0, table1, table2, table3, false); update_word_crc32(crc, tmp, tmp2, table0, table1, table2, table3, true); - mov(tmp, v0, T1D, 1); + mov(tmp, v0, D, 1); update_word_crc32(crc, tmp, tmp2, table0, table1, table2, table3, false); update_word_crc32(crc, tmp, tmp2, table0, table1, table2, table3, true); - mov(tmp, v1, T1D, 0); + mov(tmp, v1, D, 0); update_word_crc32(crc, tmp, tmp2, table0, table1, table2, table3, false); update_word_crc32(crc, tmp, tmp2, table0, table1, table2, table3, true); - mov(tmp, v1, T1D, 1); + mov(tmp, v1, D, 1); update_word_crc32(crc, tmp, tmp2, table0, table1, table2, table3, false); update_word_crc32(crc, tmp, tmp2, table0, table1, table2, table3, true); @@ -4923,111 +4927,118 @@ void MacroAssembler::fill_words(Register base, Register cnt, Register value) bind(fini); } -// Intrinsic for sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray and -// java/lang/StringUTF16.compress. +// Intrinsic for +// +// - sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray +// return the number of characters copied. +// - java/lang/StringUTF16.compress +// return zero (0) if copy fails, otherwise 'len'. +// +// This version always returns the number of characters copied, and does not +// clobber the 'len' register. A successful copy will complete with the post- +// condition: 'res' == 'len', while an unsuccessful copy will exit with the +// post-condition: 0 <= 'res' < 'len'. +// +// NOTE: Attempts to use 'ld2' (and 'umaxv' in the ISO part) has proven to +// degrade performance (on Ampere Altra - Neoverse N1), to an extent +// beyond the acceptable, even though the footprint would be smaller. +// Using 'umaxv' in the ASCII-case comes with a small penalty but does +// avoid additional bloat. +// void MacroAssembler::encode_iso_array(Register src, Register dst, - Register len, Register result, - FloatRegister Vtmp1, FloatRegister Vtmp2, - FloatRegister Vtmp3, FloatRegister Vtmp4) + Register len, Register res, bool ascii, + FloatRegister vtmp0, FloatRegister vtmp1, + FloatRegister vtmp2, FloatRegister vtmp3) { - Label DONE, SET_RESULT, NEXT_32, NEXT_32_PRFM, LOOP_8, NEXT_8, LOOP_1, NEXT_1, - NEXT_32_START, NEXT_32_PRFM_START; - Register tmp1 = rscratch1, tmp2 = rscratch2; - - mov(result, len); // Save initial len - - cmp(len, (u1)8); // handle shortest strings first - br(LT, LOOP_1); - cmp(len, (u1)32); - br(LT, NEXT_8); - // The following code uses the SIMD 'uzp1' and 'uzp2' instructions - // to convert chars to bytes - if (SoftwarePrefetchHintDistance >= 0) { - ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); - subs(tmp2, len, SoftwarePrefetchHintDistance/2 + 16); - br(LE, NEXT_32_START); - b(NEXT_32_PRFM_START); - BIND(NEXT_32_PRFM); - ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); - BIND(NEXT_32_PRFM_START); - prfm(Address(src, SoftwarePrefetchHintDistance)); - orr(v4, T16B, Vtmp1, Vtmp2); - orr(v5, T16B, Vtmp3, Vtmp4); - uzp1(Vtmp1, T16B, Vtmp1, Vtmp2); - uzp1(Vtmp3, T16B, Vtmp3, Vtmp4); - uzp2(v5, T16B, v4, v5); // high bytes - umov(tmp2, v5, D, 1); - fmovd(tmp1, v5); - orr(tmp1, tmp1, tmp2); - cbnz(tmp1, LOOP_8); - stpq(Vtmp1, Vtmp3, dst); - sub(len, len, 32); - add(dst, dst, 32); - add(src, src, 64); - subs(tmp2, len, SoftwarePrefetchHintDistance/2 + 16); - br(GE, NEXT_32_PRFM); - cmp(len, (u1)32); - br(LT, LOOP_8); - BIND(NEXT_32); - ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); - BIND(NEXT_32_START); - } else { - BIND(NEXT_32); - ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); - } - prfm(Address(src, SoftwarePrefetchHintDistance)); - uzp1(v4, T16B, Vtmp1, Vtmp2); - uzp1(v5, T16B, Vtmp3, Vtmp4); - orr(Vtmp1, T16B, Vtmp1, Vtmp2); - orr(Vtmp3, T16B, Vtmp3, Vtmp4); - uzp2(Vtmp1, T16B, Vtmp1, Vtmp3); // high bytes - umov(tmp2, Vtmp1, D, 1); - fmovd(tmp1, Vtmp1); - orr(tmp1, tmp1, tmp2); - cbnz(tmp1, LOOP_8); - stpq(v4, v5, dst); - sub(len, len, 32); - add(dst, dst, 32); - add(src, src, 64); - cmp(len, (u1)32); - br(GE, NEXT_32); - cbz(len, DONE); - - BIND(LOOP_8); - cmp(len, (u1)8); - br(LT, LOOP_1); - BIND(NEXT_8); - ld1(Vtmp1, T8H, src); - uzp1(Vtmp2, T16B, Vtmp1, Vtmp1); // low bytes - uzp2(Vtmp3, T16B, Vtmp1, Vtmp1); // high bytes - fmovd(tmp1, Vtmp3); - cbnz(tmp1, NEXT_1); - strd(Vtmp2, dst); - - sub(len, len, 8); - add(dst, dst, 8); - add(src, src, 16); - cmp(len, (u1)8); - br(GE, NEXT_8); - - BIND(LOOP_1); - - cbz(len, DONE); - BIND(NEXT_1); - ldrh(tmp1, Address(post(src, 2))); - tst(tmp1, 0xff00); - br(NE, SET_RESULT); - strb(tmp1, Address(post(dst, 1))); - subs(len, len, 1); - br(GT, NEXT_1); - - BIND(SET_RESULT); - sub(result, result, len); // Return index where we stopped - // Return len == 0 if we processed all - // characters - BIND(DONE); -} + Register cnt = res; + Register max = rscratch1; + Register chk = rscratch2; + prfm(Address(src), PLDL1STRM); + movw(cnt, len); + +#define ASCII(insn) do { if (ascii) { insn; } } while (0) + + Label LOOP_32, DONE_32, FAIL_32; + + BIND(LOOP_32); + { + cmpw(cnt, 32); + br(LT, DONE_32); + ld1(vtmp0, vtmp1, vtmp2, vtmp3, T8H, Address(post(src, 64))); + // Extract lower bytes. + FloatRegister vlo0 = v4; + FloatRegister vlo1 = v5; + uzp1(vlo0, T16B, vtmp0, vtmp1); + uzp1(vlo1, T16B, vtmp2, vtmp3); + // Merge bits... + orr(vtmp0, T16B, vtmp0, vtmp1); + orr(vtmp2, T16B, vtmp2, vtmp3); + // Extract merged upper bytes. + FloatRegister vhix = vtmp0; + uzp2(vhix, T16B, vtmp0, vtmp2); + // ISO-check on hi-parts (all zero). + // ASCII-check on lo-parts (no sign). + FloatRegister vlox = vtmp1; // Merge lower bytes. + ASCII(orr(vlox, T16B, vlo0, vlo1)); + umov(chk, vhix, D, 1); ASCII(cmlt(vlox, T16B, vlox)); + fmovd(max, vhix); ASCII(umaxv(vlox, T16B, vlox)); + orr(chk, chk, max); ASCII(umov(max, vlox, B, 0)); + ASCII(orr(chk, chk, max)); + cbnz(chk, FAIL_32); + subw(cnt, cnt, 32); + st1(vlo0, vlo1, T16B, Address(post(dst, 32))); + b(LOOP_32); + } + BIND(FAIL_32); + sub(src, src, 64); + BIND(DONE_32); + + Label LOOP_8, SKIP_8; + + BIND(LOOP_8); + { + cmpw(cnt, 8); + br(LT, SKIP_8); + FloatRegister vhi = vtmp0; + FloatRegister vlo = vtmp1; + ld1(vtmp3, T8H, src); + uzp1(vlo, T16B, vtmp3, vtmp3); + uzp2(vhi, T16B, vtmp3, vtmp3); + // ISO-check on hi-parts (all zero). + // ASCII-check on lo-parts (no sign). + ASCII(cmlt(vtmp2, T16B, vlo)); + fmovd(chk, vhi); ASCII(umaxv(vtmp2, T16B, vtmp2)); + ASCII(umov(max, vtmp2, B, 0)); + ASCII(orr(chk, chk, max)); + cbnz(chk, SKIP_8); + + strd(vlo, Address(post(dst, 8))); + subw(cnt, cnt, 8); + add(src, src, 16); + b(LOOP_8); + } + BIND(SKIP_8); + +#undef ASCII + + Label LOOP, DONE; + + cbz(cnt, DONE); + BIND(LOOP); + { + Register chr = rscratch1; + ldrh(chr, Address(post(src, 2))); + tst(chr, ascii ? 0xff80 : 0xff00); + br(NE, DONE); + strb(chr, Address(post(dst, 1))); + subs(cnt, cnt, 1); + br(GT, LOOP); + } + BIND(DONE); + // Return index where we stopped. + subw(res, len, cnt); +} // Inflate byte[] array to char[]. address MacroAssembler::byte_array_inflate(Register src, Register dst, Register len, @@ -5136,13 +5147,13 @@ address MacroAssembler::byte_array_inflate(Register src, Register dst, Register // Compress char[] array to byte[]. void MacroAssembler::char_array_compress(Register src, Register dst, Register len, - FloatRegister tmp1Reg, FloatRegister tmp2Reg, - FloatRegister tmp3Reg, FloatRegister tmp4Reg, - Register result) { - encode_iso_array(src, dst, len, result, - tmp1Reg, tmp2Reg, tmp3Reg, tmp4Reg); - cmp(len, zr); - csel(result, result, zr, EQ); + Register res, + FloatRegister tmp0, FloatRegister tmp1, + FloatRegister tmp2, FloatRegister tmp3) { + encode_iso_array(src, dst, len, res, false, tmp0, tmp1, tmp2, tmp3); + // Adjust result: res == len ? len : 0 + cmp(len, res); + csel(res, res, zr, EQ); } // get_thread() can be called anywhere inside generated code so we diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index a9ebc8bdc69196fe97229633737f99992c20701f..16f9790bde42c20cb808f6c2321b7135c1279452 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,6 +27,7 @@ #define CPU_AARCH64_MACROASSEMBLER_AARCH64_HPP #include "asm/assembler.inline.hpp" +#include "metaprogramming/enableIf.hpp" #include "oops/compressedOops.hpp" #include "runtime/vm_version.hpp" #include "utilities/powerOfTwo.hpp" @@ -493,17 +494,10 @@ public: inline void mov(Register dst, address addr) { mov_immediate64(dst, (uint64_t)addr); } - inline void mov(Register dst, int imm64) { mov_immediate64(dst, (uint64_t)imm64); } - inline void mov(Register dst, long imm64) { mov_immediate64(dst, (uint64_t)imm64); } - inline void mov(Register dst, long long imm64) { mov_immediate64(dst, (uint64_t)imm64); } - inline void mov(Register dst, unsigned int imm64) { mov_immediate64(dst, (uint64_t)imm64); } - inline void mov(Register dst, unsigned long imm64) { mov_immediate64(dst, (uint64_t)imm64); } - inline void mov(Register dst, unsigned long long imm64) { mov_immediate64(dst, (uint64_t)imm64); } + template::value)> + inline void mov(Register dst, T o) { mov_immediate64(dst, (uint64_t)o); } - inline void movw(Register dst, uint32_t imm32) - { - mov_immediate32(dst, imm32); - } + inline void movw(Register dst, uint32_t imm32) { mov_immediate32(dst, imm32); } void mov(Register dst, RegisterOrConstant src) { if (src.is_register()) @@ -606,10 +600,15 @@ public: static bool uses_implicit_null_check(void* address); static address target_addr_for_insn(address insn_addr, unsigned insn); + static address target_addr_for_insn_or_null(address insn_addr, unsigned insn); static address target_addr_for_insn(address insn_addr) { unsigned insn = *(unsigned*)insn_addr; return target_addr_for_insn(insn_addr, insn); } + static address target_addr_for_insn_or_null(address insn_addr) { + unsigned insn = *(unsigned*)insn_addr; + return target_addr_for_insn_or_null(insn_addr, insn); + } // Required platform-specific helpers for Label::patch_instructions. // They _shadow_ the declarations in AbstractAssembler, which are undefined. @@ -1255,14 +1254,15 @@ public: FloatRegister vtmp3, Register tmp4); void char_array_compress(Register src, Register dst, Register len, - FloatRegister tmp1Reg, FloatRegister tmp2Reg, - FloatRegister tmp3Reg, FloatRegister tmp4Reg, - Register result); + Register res, + FloatRegister vtmp0, FloatRegister vtmp1, + FloatRegister vtmp2, FloatRegister vtmp3); void encode_iso_array(Register src, Register dst, - Register len, Register result, - FloatRegister Vtmp1, FloatRegister Vtmp2, - FloatRegister Vtmp3, FloatRegister Vtmp4); + Register len, Register res, bool ascii, + FloatRegister vtmp0, FloatRegister vtmp1, + FloatRegister vtmp2, FloatRegister vtmp3); + void fast_log(FloatRegister vtmp0, FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, FloatRegister vtmp4, FloatRegister vtmp5, FloatRegister tmpC1, FloatRegister tmpC2, FloatRegister tmpC3, diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_log.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_log.cpp index d65c3df226d7d4270d33bc03eb21778f8ce6cdc7..45772ff1afd63a2d1f14482bf05bbc9f8f536055 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_log.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_log.cpp @@ -297,7 +297,8 @@ void MacroAssembler::fast_log(FloatRegister vtmp0, FloatRegister vtmp1, bind(MAIN); fmovs(tmp3, vtmp5); // int intB0 = AS_INT_BITS(B); mov(tmp5, 0x3FE0); - mov(rscratch1, 0xffffe00000000000); + uint64_t mask = UCONST64(0xffffe00000000000); + mov(rscratch1, mask); andr(tmp2, tmp2, tmp1, LSR, 48); // hiWord & 0x7FF0 sub(tmp2, tmp2, tmp5); // tmp2 = hiWord & 0x7FF0 - 0x3FE0 scvtfwd(vtmp5, tmp2); // vtmp5 = (double)tmp2; diff --git a/src/hotspot/cpu/aarch64/matcher_aarch64.hpp b/src/hotspot/cpu/aarch64/matcher_aarch64.hpp index e0bb39f9e5ffcf61690572f368aa84dc39796cff..aca82240a5731fb10d8734bbce8411763b8744de 100644 --- a/src/hotspot/cpu/aarch64/matcher_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/matcher_aarch64.hpp @@ -55,9 +55,6 @@ // No support for generic vector operands. static const bool supports_generic_vector_operands = false; - // No support for 48 extra htbl entries in aes-gcm intrinsic - static const int htbl_entries = 0; - static constexpr bool isSimpleConstant64(jlong value) { // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. // Probably always true, even if a temp register is required. @@ -164,6 +161,6 @@ } // Implements a variant of EncodeISOArrayNode that encode ASCII only - static const bool supports_encode_ascii_array = false; + static const bool supports_encode_ascii_array = true; #endif // CPU_AARCH64_MATCHER_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp index d808e4b5b53de9eb13da164cca7dc24871a72dbd..7599c21c2fcaa88e107b457f5963e19ba9f6d48d 100644 --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -315,7 +315,7 @@ void NativeMovRegMem::set_offset(int x) { void NativeMovRegMem::verify() { #ifdef ASSERT - address dest = MacroAssembler::target_addr_for_insn(instruction_address()); + address dest = MacroAssembler::target_addr_for_insn_or_null(instruction_address()); #endif } @@ -329,7 +329,7 @@ void NativeJump::check_verified_entry_alignment(address entry, address verified_ address NativeJump::jump_destination() const { - address dest = MacroAssembler::target_addr_for_insn(instruction_address()); + address dest = MacroAssembler::target_addr_for_insn_or_null(instruction_address()); // We use jump to self as the unresolved address which the inline // cache code (and relocs) know about diff --git a/src/hotspot/cpu/aarch64/register_aarch64.cpp b/src/hotspot/cpu/aarch64/register_aarch64.cpp index b785457ae29ccdc206d839ca0121912366af5a3e..096e480a824cc21c6e250aa057e7bba2497fca4d 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.cpp @@ -26,6 +26,10 @@ #include "precompiled.hpp" #include "register_aarch64.hpp" +REGISTER_IMPL_DEFINITION(Register, RegisterImpl, RegisterImpl::number_of_declared_registers); +REGISTER_IMPL_DEFINITION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers); +REGISTER_IMPL_DEFINITION(PRegister, PRegisterImpl, PRegisterImpl::number_of_registers); + const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers * RegisterImpl::max_slots_per_register; @@ -38,7 +42,7 @@ const int ConcreteRegisterImpl::max_pr PRegisterImpl::number_of_registers * PRegisterImpl::max_slots_per_register; const char* RegisterImpl::name() const { - const char* names[number_of_registers] = { + static const char *const names[number_of_registers] = { "c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7", "rscratch1", "rscratch2", "r10", "r11", "r12", "r13", "r14", "r15", "r16", @@ -50,7 +54,7 @@ const char* RegisterImpl::name() const { } const char* FloatRegisterImpl::name() const { - const char* names[number_of_registers] = { + static const char *const names[number_of_registers] = { "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", @@ -60,7 +64,7 @@ const char* FloatRegisterImpl::name() const { } const char* PRegisterImpl::name() const { - const char* names[number_of_registers] = { + static const char *const names[number_of_registers] = { "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15" }; diff --git a/src/hotspot/cpu/aarch64/register_aarch64.hpp b/src/hotspot/cpu/aarch64/register_aarch64.hpp index 7b472856dc442a7a0a0654f45ffcb477d77ce445..7e531710c1d1fe2ce0cc925de324d361d27aab6f 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.hpp @@ -34,42 +34,42 @@ typedef VMRegImpl* VMReg; // Use Register as shortcut class RegisterImpl; -typedef RegisterImpl* Register; +typedef const RegisterImpl* Register; -inline const Register as_Register(int encoding) { - return (Register)(intptr_t) encoding; -} +inline constexpr Register as_Register(int encoding); class RegisterImpl: public AbstractRegisterImpl { - public: + static constexpr Register first(); + +public: enum { number_of_registers = 32, - number_of_byte_registers = 32, - number_of_registers_for_jvmci = 34, // Including SP and ZR. + number_of_declared_registers = 34, // Including SP and ZR. max_slots_per_register = 2 }; // derived registers, offsets, and addresses - Register successor() const { return as_Register(encoding() + 1); } + const Register successor() const { return this + 1; } // construction - inline friend const Register as_Register(int encoding); + inline friend constexpr Register as_Register(int encoding); - VMReg as_VMReg(); + VMReg as_VMReg() const; // accessors - int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; } - bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } - bool has_byte_register() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_byte_registers; } + int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); } + bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; } const char* name() const; - int encoding_nocheck() const { return (intptr_t)this; } + int encoding_nocheck() const { return this - first(); } }; + +REGISTER_IMPL_DECLARATION(Register, RegisterImpl, RegisterImpl::number_of_declared_registers); + // The integer registers of the aarch64 architecture CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); - CONSTANT_REGISTER_DECLARATION(Register, r0, (0)); CONSTANT_REGISTER_DECLARATION(Register, r1, (1)); CONSTANT_REGISTER_DECLARATION(Register, r2, (2)); @@ -126,15 +126,15 @@ const Register dummy_reg = r31_sp; // Use FloatRegister as shortcut class FloatRegisterImpl; -typedef FloatRegisterImpl* FloatRegister; +typedef const FloatRegisterImpl* FloatRegister; -inline FloatRegister as_FloatRegister(int encoding) { - return (FloatRegister)(intptr_t) encoding; -} +inline constexpr FloatRegister as_FloatRegister(int encoding); // The implementation of floating point registers for the architecture class FloatRegisterImpl: public AbstractRegisterImpl { - public: + static constexpr FloatRegister first(); + +public: enum { number_of_registers = 32, max_slots_per_register = 8, @@ -144,21 +144,25 @@ class FloatRegisterImpl: public AbstractRegisterImpl { }; // construction - inline friend FloatRegister as_FloatRegister(int encoding); + inline friend constexpr FloatRegister as_FloatRegister(int encoding); - VMReg as_VMReg(); + VMReg as_VMReg() const; // derived registers, offsets, and addresses - FloatRegister successor() const { return as_FloatRegister((encoding() + 1) % 32); } + FloatRegister successor() const { + return as_FloatRegister((encoding() + 1) % (unsigned)number_of_registers); + } // accessors - int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; } - int encoding_nocheck() const { return (intptr_t)this; } - bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } + int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); } + bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; } const char* name() const; - + int encoding_nocheck() const { return this - first(); } }; +REGISTER_IMPL_DECLARATION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers); + + // The float registers of the AARCH64 architecture CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg , (-1)); @@ -232,13 +236,13 @@ CONSTANT_REGISTER_DECLARATION(FloatRegister, z31 , (31)); class PRegisterImpl; -typedef PRegisterImpl* PRegister; -inline PRegister as_PRegister(int encoding) { - return (PRegister)(intptr_t)encoding; -} +typedef const PRegisterImpl* PRegister; +inline constexpr PRegister as_PRegister(int encoding); // The implementation of predicate registers for the architecture class PRegisterImpl: public AbstractRegisterImpl { + static constexpr PRegister first(); + public: enum { number_of_registers = 16, @@ -252,21 +256,24 @@ class PRegisterImpl: public AbstractRegisterImpl { }; // construction - inline friend PRegister as_PRegister(int encoding); + inline friend constexpr PRegister as_PRegister(int encoding); - VMReg as_VMReg(); + VMReg as_VMReg() const; // derived registers, offsets, and addresses - PRegister successor() const { return as_PRegister(encoding() + 1); } + PRegister successor() const { return this + 1; } // accessors - int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; } - int encoding_nocheck() const { return (intptr_t)this; } - bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } - bool is_governing() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_governing_registers; } + int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); } + int encoding_nocheck() const { return this - first(); } + bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; } + bool is_governing() const { return first() <= this && this - first() < number_of_governing_registers; } const char* name() const; }; + +REGISTER_IMPL_DECLARATION(PRegister, PRegisterImpl, PRegisterImpl::number_of_registers); + // The predicate registers of SVE. CONSTANT_REGISTER_DECLARATION(PRegister, pnoreg, (-1)); diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 5c80566aeadd7d3425a82cde23b7c51d558bfc10..08cc2b20a61e2ad6d33f09446d29942057009db9 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1642,39 +1642,42 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, // Load the oop from the handle __ ldr(obj_reg, Address(oop_handle_reg, 0)); - // Load (object->mark() | 1) into swap_reg %r0 - __ ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ orr(swap_reg, rscratch1, 1); + if (!UseHeavyMonitors) { + // Load (object->mark() | 1) into swap_reg %r0 + __ ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + __ orr(swap_reg, rscratch1, 1); - // Save (object->mark() | 1) into BasicLock's displaced header - __ str(swap_reg, Address(lock_reg, mark_word_offset)); + // Save (object->mark() | 1) into BasicLock's displaced header + __ str(swap_reg, Address(lock_reg, mark_word_offset)); - // src -> dest iff dest == r0 else r0 <- dest - { Label here; - __ cmpxchg_obj_header(r0, lock_reg, obj_reg, rscratch1, lock_done, /*fallthrough*/NULL); - } + // src -> dest iff dest == r0 else r0 <- dest + { Label here; + __ cmpxchg_obj_header(r0, lock_reg, obj_reg, rscratch1, lock_done, /*fallthrough*/NULL); + } - // Hmm should this move to the slow path code area??? + // Hmm should this move to the slow path code area??? - // Test if the oopMark is an obvious stack pointer, i.e., - // 1) (mark & 3) == 0, and - // 2) sp <= mark < mark + os::pagesize() - // These 3 tests can be done by evaluating the following - // expression: ((mark - sp) & (3 - os::vm_page_size())), - // assuming both stack pointer and pagesize have their - // least significant 2 bits clear. - // NOTE: the oopMark is in swap_reg %r0 as the result of cmpxchg + // Test if the oopMark is an obvious stack pointer, i.e., + // 1) (mark & 3) == 0, and + // 2) sp <= mark < mark + os::pagesize() + // These 3 tests can be done by evaluating the following + // expression: ((mark - sp) & (3 - os::vm_page_size())), + // assuming both stack pointer and pagesize have their + // least significant 2 bits clear. + // NOTE: the oopMark is in swap_reg %r0 as the result of cmpxchg - __ sub(swap_reg, sp, swap_reg); - __ neg(swap_reg, swap_reg); - __ ands(swap_reg, swap_reg, 3 - os::vm_page_size()); + __ sub(swap_reg, sp, swap_reg); + __ neg(swap_reg, swap_reg); + __ ands(swap_reg, swap_reg, 3 - os::vm_page_size()); - // Save the test result, for recursive case, the result is zero - __ str(swap_reg, Address(lock_reg, mark_word_offset)); - __ br(Assembler::NE, slow_path_lock); + // Save the test result, for recursive case, the result is zero + __ str(swap_reg, Address(lock_reg, mark_word_offset)); + __ br(Assembler::NE, slow_path_lock); + } else { + __ b(slow_path_lock); + } // Slow path will re-enter here - __ bind(lock_done); } @@ -1775,26 +1778,31 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ ldr(obj_reg, Address(oop_handle_reg, 0)); Label done; - // Simple recursive lock? - __ ldr(rscratch1, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size)); - __ cbz(rscratch1, done); + if (!UseHeavyMonitors) { + // Simple recursive lock? + __ ldr(rscratch1, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size)); + __ cbz(rscratch1, done); + } // Must save r0 if if it is live now because cmpxchg must use it if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { save_native_result(masm, ret_type, stack_slots); } + if (!UseHeavyMonitors) { + // get address of the stack lock + __ lea(r0, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size)); + // get old displaced header + __ ldr(old_hdr, Address(r0, 0)); - // get address of the stack lock - __ lea(r0, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size)); - // get old displaced header - __ ldr(old_hdr, Address(r0, 0)); - - // Atomic swap old header if oop still contains the stack lock - Label succeed; - __ cmpxchg_obj_header(r0, old_hdr, obj_reg, rscratch1, succeed, &slow_path_unlock); - __ bind(succeed); + // Atomic swap old header if oop still contains the stack lock + Label succeed; + __ cmpxchg_obj_header(r0, old_hdr, obj_reg, rscratch1, succeed, &slow_path_unlock); + __ bind(succeed); + } else { + __ b(slow_path_unlock); + } // slow path re-enters here __ bind(unlock_done); diff --git a/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp b/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp index 4edce2642e9ff3e48eee910e7b9bc8f84cb52005..28ffeafda487755d8c0126b0a58277d0d7027a89 100644 --- a/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon.com Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index fdf874b2e0d8e290641122304c8b4d0308760c10..7d7f9b57e8c35446d28660a716ed7e3540baa30f 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3094,8 +3094,7 @@ class StubGenerator: public StubCodeGenerator { // key = c_rarg4 // state = c_rarg5 - GHASH.state // subkeyHtbl = c_rarg6 - powers of H - // subkeyHtbl_48_entries = c_rarg7 (not used) - // counter = [sp, #0] pointer to 16 bytes of CTR + // counter = c_rarg7 - 16 bytes of CTR // return - number of processed bytes address generate_galoisCounterMode_AESCrypt() { address ghash_polynomial = __ pc(); @@ -3121,10 +3120,7 @@ class StubGenerator: public StubCodeGenerator { const Register subkeyHtbl = c_rarg6; - // Pointer to CTR is passed on the stack before the (fp, lr) pair. - const Address counter_mem(sp, 2 * wordSize); const Register counter = c_rarg7; - __ ldr(counter, counter_mem); const Register keylen = r10; // Save state before entering routine @@ -5341,11 +5337,11 @@ class StubGenerator: public StubCodeGenerator { __ add(str1, str1, wordSize); __ add(str2, str2, wordSize); if (SoftwarePrefetchHintDistance >= 0) { + __ align(OptoLoopAlignment); __ bind(LARGE_LOOP_PREFETCH); __ prfm(Address(str1, SoftwarePrefetchHintDistance)); __ prfm(Address(str2, SoftwarePrefetchHintDistance)); - __ align(OptoLoopAlignment); for (int i = 0; i < 4; i++) { __ ldp(tmp1, tmp1h, Address(str1, i * 16)); __ ldp(tmp2, tmp2h, Address(str2, i * 16)); @@ -6397,6 +6393,18 @@ class StubGenerator: public StubCodeGenerator { return start; } + // Support for spin waits. + address generate_spin_wait() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "spin_wait"); + address start = __ pc(); + + __ spin_wait(); + __ ret(lr); + + return start; + } + #ifdef LINUX // ARMv8.1 LSE versions of the atomic stubs used by Atomic::PlatformXX. @@ -7715,6 +7723,8 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32(); } + StubRoutines::aarch64::_spin_wait = generate_spin_wait(); + #ifdef LINUX generate_atomic_entry_points(); diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp index 1cbc3ed21d16f29037d4a2e0ec391f06a148e5e3..9e16a1f9f8812268779be2caad8e459c123816ae 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp @@ -57,6 +57,10 @@ address StubRoutines::aarch64::_string_indexof_linear_uu = NULL; address StubRoutines::aarch64::_string_indexof_linear_ul = NULL; address StubRoutines::aarch64::_large_byte_array_inflate = NULL; address StubRoutines::aarch64::_method_entry_barrier = NULL; + +static void empty_spin_wait() { } +address StubRoutines::aarch64::_spin_wait = CAST_FROM_FN_PTR(address, empty_spin_wait); + bool StubRoutines::aarch64::_completed = false; /** diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp index 67536dc1d2b123ffaa768109f3c316350265868c..295264b7aaf22067503fcbc7fb3db2cab7222870 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp @@ -72,6 +72,8 @@ class aarch64 { static address _method_entry_barrier; + static address _spin_wait; + static bool _completed; public: @@ -177,6 +179,10 @@ class aarch64 { return _method_entry_barrier; } + static address spin_wait() { + return _spin_wait; + } + static bool complete() { return _completed; } diff --git a/src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp b/src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp index 41bb34e40abe5f2b84db77c9f10ed2b5a986198a..e3287652891a40b2642c87167feee49999504fa0 100644 --- a/src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp @@ -71,7 +71,8 @@ address ProgrammableUpcallHandler::generate_upcall_stub(jobject rec, jobject jab // Capture prev stack pointer (stack arguments base) __ add(rscratch1, rfp, 16); // Skip saved FP and LR - __ str(rscratch1, Address(sp, layout.stack_args)); + Address slot = __ legitimize_address(Address(sp, layout.stack_args), wordSize, rscratch2); + __ str(rscratch1, slot); // Call upcall helper __ ldr(c_rarg0, rec_adr); diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index e08d0b6f134b79ee5e74f41cf80a3afe2e766498..833a6ec9f6da32bd48cda2bd201faeeea3dd4e5a 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -469,6 +469,14 @@ void VM_Version::initialize() { } } + int inline_size = (UseSVE > 0 && MaxVectorSize >= 16) ? MaxVectorSize : 0; + if (FLAG_IS_DEFAULT(ArrayOperationPartialInlineSize)) { + FLAG_SET_DEFAULT(ArrayOperationPartialInlineSize, inline_size); + } else if (ArrayOperationPartialInlineSize != 0 && ArrayOperationPartialInlineSize != inline_size) { + warning("Setting ArrayOperationPartialInlineSize to %d", inline_size); + ArrayOperationPartialInlineSize = inline_size; + } + if (FLAG_IS_DEFAULT(OptoScheduling)) { OptoScheduling = true; } @@ -480,3 +488,22 @@ void VM_Version::initialize() { _spin_wait = get_spin_wait_desc(); } + +void VM_Version::initialize_cpu_information(void) { + // do nothing if cpu info has been initialized + if (_initialized) { + return; + } + + _no_of_cores = os::processor_count(); + _no_of_threads = _no_of_cores; + _no_of_sockets = _no_of_cores; + snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "AArch64"); + + int desc_len = snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "AArch64 "); + get_compatible_board(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len); + desc_len = (int)strlen(_cpu_desc); + snprintf(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len, " %s", _features_string); + + _initialized = true; +} diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp index 61f422bd2d38b3348f0294c1a741c8ba059b95a5..b6aec7ed01f985c97b009fb2dde99b73df3b7af8 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp @@ -153,6 +153,9 @@ public: // Is the CPU running emulated (for example macOS Rosetta running x86_64 code on M1 ARM (aarch64) static bool is_cpu_emulated(); #endif + + static void initialize_cpu_information(void); + }; #endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp deleted file mode 100644 index a95171173e9318615c439ea1b31c7bd2648e9677..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" -#include "runtime/os.inline.hpp" -#include "vm_version_ext_aarch64.hpp" - -// VM_Version_Ext statics -int VM_Version_Ext::_no_of_threads = 0; -int VM_Version_Ext::_no_of_cores = 0; -int VM_Version_Ext::_no_of_sockets = 0; -bool VM_Version_Ext::_initialized = false; -char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0}; -char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0}; - -void VM_Version_Ext::initialize_cpu_information(void) { - // do nothing if cpu info has been initialized - if (_initialized) { - return; - } - - int core_id = -1; - int chip_id = -1; - int len = 0; - char* src_string = NULL; - - _no_of_cores = os::processor_count(); - _no_of_threads = _no_of_cores; - _no_of_sockets = _no_of_cores; - snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "AArch64"); - - int desc_len = snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "AArch64 "); - VM_Version::get_compatible_board(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len); - desc_len = (int)strlen(_cpu_desc); - snprintf(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len, " %s", _features_string); - - _initialized = true; -} - -int VM_Version_Ext::number_of_threads(void) { - initialize_cpu_information(); - return _no_of_threads; -} - -int VM_Version_Ext::number_of_cores(void) { - initialize_cpu_information(); - return _no_of_cores; -} - -int VM_Version_Ext::number_of_sockets(void) { - initialize_cpu_information(); - return _no_of_sockets; -} - -const char* VM_Version_Ext::cpu_name(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE); - return tmp; -} - -const char* VM_Version_Ext::cpu_description(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE); - return tmp; -} diff --git a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.hpp deleted file mode 100644 index 0eced8e65575af258c3783b71bd1479d68d9cb99..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_AARCH64_VM_VERSION_EXT_AARCH64_HPP -#define CPU_AARCH64_VM_VERSION_EXT_AARCH64_HPP - -#include "runtime/vm_version.hpp" -#include "utilities/macros.hpp" - -class VM_Version_Ext : public VM_Version { - private: - static const size_t CPU_TYPE_DESC_BUF_SIZE = 256; - static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096; - - static int _no_of_threads; - static int _no_of_cores; - static int _no_of_sockets; - static bool _initialized; - static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE]; - static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE]; - - public: - static int number_of_threads(void); - static int number_of_cores(void); - static int number_of_sockets(void); - - static const char* cpu_name(void); - static const char* cpu_description(void); - static void initialize_cpu_information(void); - -}; - -#endif // CPU_AARCH64_VM_VERSION_EXT_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/vmreg_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/vmreg_aarch64.inline.hpp index 8452417b6cf188d4d90341271c23b3c2cc95519c..aa750104896f104e23d4541c9cd81cd37a62bf4d 100644 --- a/src/hotspot/cpu/aarch64/vmreg_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/vmreg_aarch64.inline.hpp @@ -26,17 +26,17 @@ #ifndef CPU_AARCH64_VMREG_AARCH64_INLINE_HPP #define CPU_AARCH64_VMREG_AARCH64_INLINE_HPP -inline VMReg RegisterImpl::as_VMReg() { +inline VMReg RegisterImpl::as_VMReg() const { if( this==noreg ) return VMRegImpl::Bad(); return VMRegImpl::as_VMReg(encoding() * RegisterImpl::max_slots_per_register); } -inline VMReg FloatRegisterImpl::as_VMReg() { +inline VMReg FloatRegisterImpl::as_VMReg() const { return VMRegImpl::as_VMReg((encoding() * FloatRegisterImpl::max_slots_per_register) + ConcreteRegisterImpl::max_gpr); } -inline VMReg PRegisterImpl::as_VMReg() { +inline VMReg PRegisterImpl::as_VMReg() const { return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_fpr); } diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index 9e76f430054ac8a1ccbe3a6324b77812d638d52c..f2ac7b58e7336b859ee494318270823ed9107d16 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -1,5 +1,5 @@ // -// Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -123,9 +123,18 @@ public: }; }; +// Assert that the given node is not a var shift. +bool assert_not_var_shift(const Node *n); %} source %{ + +// Assert that the given node is not a var shift. +bool assert_not_var_shift(const Node *n) { + assert(!n->as_ShiftV()->is_var_shift(), "illegal var shift"); + return true; +} + #define __ _masm. static FloatRegister reg_to_FloatRegister_object(int register_encoding); @@ -991,7 +1000,7 @@ const RegMask* Matcher::predicate_reg_mask(void) { return NULL; } -const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { +const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { return NULL; } @@ -8385,7 +8394,7 @@ instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{ // Conditional move instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(150); size(8); @@ -8398,9 +8407,9 @@ instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) % ins_pipe(ialu_reg); %} -instruct cmovLL_reg_LTGE_U(cmpOpL cmp, flagsRegUL_LTGE xcc, iRegL dst, iRegL src) %{ +instruct cmovLL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegL dst, iRegL src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(150); size(8); @@ -8415,7 +8424,7 @@ instruct cmovLL_reg_LTGE_U(cmpOpL cmp, flagsRegUL_LTGE xcc, iRegL dst, iRegL src instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(150); size(8); @@ -8430,7 +8439,7 @@ instruct cmovLL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, iRegL src) % instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iRegL src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(150); size(8); @@ -8443,9 +8452,9 @@ instruct cmovLL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, iReg ins_pipe(ialu_reg); %} -instruct cmovLL_reg_LEGT_U(cmpOpL_commute cmp, flagsRegUL_LEGT xcc, iRegL dst, iRegL src) %{ +instruct cmovLL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegL dst, iRegL src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(150); size(8); @@ -8460,7 +8469,7 @@ instruct cmovLL_reg_LEGT_U(cmpOpL_commute cmp, flagsRegUL_LEGT xcc, iRegL dst, i instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(140); size(8); format %{ "MOV$cmp $dst.lo,0\t! long\n\t" @@ -8472,9 +8481,9 @@ instruct cmovLL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, immL0 src) % ins_pipe(ialu_imm); %} -instruct cmovLL_imm_LTGE_U(cmpOpL cmp, flagsRegUL_LTGE xcc, iRegL dst, immL0 src) %{ +instruct cmovLL_imm_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegL dst, immL0 src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(140); size(8); format %{ "MOV$cmp $dst.lo,0\t! long\n\t" @@ -8488,7 +8497,7 @@ instruct cmovLL_imm_LTGE_U(cmpOpL cmp, flagsRegUL_LTGE xcc, iRegL dst, immL0 src instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(140); size(8); format %{ "MOV$cmp $dst.lo,0\t! long\n\t" @@ -8502,7 +8511,7 @@ instruct cmovLL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegL dst, immL0 src) % instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL0 src) %{ match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(140); size(8); format %{ "MOV$cmp $dst.lo,0\t! long\n\t" @@ -8516,7 +8525,20 @@ instruct cmovLL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegL dst, immL instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{ match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + + ins_cost(150); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_reg); +%} + +instruct cmovIL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, iRegI src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(150); size(4); @@ -8529,7 +8551,7 @@ instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) % instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) %{ match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(150); size(4); @@ -8540,9 +8562,22 @@ instruct cmovIL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, iRegI src) % ins_pipe(ialu_reg); %} +instruct cmovIL_reg_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, iRegI src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); + + ins_cost(150); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_reg); +%} + instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iRegI src) %{ match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(150); size(4); @@ -8553,11 +8588,51 @@ instruct cmovIL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, iReg ins_pipe(ialu_reg); %} -instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{ +instruct cmovIL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, iRegI src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); + + ins_cost(150); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_reg); +%} + +instruct cmovIL_imm16_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + + ins_cost(140); + size(4); + format %{ "MOVW$cmp $dst,$src" %} + ins_encode %{ + __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovIL_imm16_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, immI16 src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + + ins_cost(140); + size(4); + format %{ "MOVW$cmp $dst,$src" %} + ins_encode %{ + __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovIL_imm16_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{ match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(140); + size(4); format %{ "MOVW$cmp $dst,$src" %} ins_encode %{ __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); @@ -8565,11 +8640,12 @@ instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) ins_pipe(ialu_imm); %} -instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) %{ +instruct cmovIL_imm16_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, immI16 src) %{ match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(140); + size(4); format %{ "MOVW$cmp $dst,$src" %} ins_encode %{ __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); @@ -8577,11 +8653,12 @@ instruct cmovIL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immI16 src) ins_pipe(ialu_imm); %} -instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{ +instruct cmovIL_imm16_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI16 src) %{ match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(140); + size(4); format %{ "MOVW$cmp $dst,$src" %} ins_encode %{ __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); @@ -8589,9 +8666,113 @@ instruct cmovIL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immI ins_pipe(ialu_imm); %} +instruct cmovIL_imm16_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, immI16 src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); + + ins_cost(140); + size(4); + format %{ "MOVW$cmp $dst,$src" %} + ins_encode %{ + __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovIL_immMov_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immIMov src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + + ins_cost(140); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovIL_immMov_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegI dst, immIMov src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + + ins_cost(140); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovIL_immMov_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegI dst, immIMov src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); + + ins_cost(140); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovIL_immMov_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegI dst, immIMov src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); + + ins_cost(140); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovIL_immMov_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegI dst, immIMov src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); + + ins_cost(140); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovIL_immMov_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegI dst, immIMov src) %{ + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); + + ins_cost(140); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) %{ match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + + ins_cost(150); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_reg); +%} + +instruct cmovPL_reg_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegP dst, iRegP src) %{ + match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(150); size(4); @@ -8604,7 +8785,20 @@ instruct cmovPL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, iRegP src) % instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) %{ match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); + + ins_cost(150); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_reg); +%} + +instruct cmovPL_reg_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegP dst, iRegP src) %{ + match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(150); size(4); @@ -8617,7 +8811,20 @@ instruct cmovPL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, iRegP src) % instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iRegP src) %{ match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); + + ins_cost(150); + size(4); + format %{ "MOV$cmp $dst,$src" %} + ins_encode %{ + __ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_reg); +%} + +instruct cmovPL_reg_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegP dst, iRegP src) %{ + match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(150); size(4); @@ -8630,9 +8837,23 @@ instruct cmovPL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, iReg instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) %{ match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(140); + size(4); + format %{ "MOVW$cmp $dst,$src" %} + ins_encode %{ + __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovPL_imm_LTGE_U(cmpOpUL cmp, flagsRegUL_LTGE xcc, iRegP dst, immP0 src) %{ + match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); + + ins_cost(140); + size(4); format %{ "MOVW$cmp $dst,$src" %} ins_encode %{ __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); @@ -8642,9 +8863,23 @@ instruct cmovPL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegP dst, immP0 src) % instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) %{ match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); + + ins_cost(140); + size(4); + format %{ "MOVW$cmp $dst,$src" %} + ins_encode %{ + __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovPL_imm_EQNE_U(cmpOpUL cmp, flagsRegUL_EQNE xcc, iRegP dst, immP0 src) %{ + match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(140); + size(4); format %{ "MOVW$cmp $dst,$src" %} ins_encode %{ __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); @@ -8654,9 +8889,23 @@ instruct cmovPL_imm_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, iRegP dst, immP0 src) % instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP0 src) %{ match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); + + ins_cost(140); + size(4); + format %{ "MOVW$cmp $dst,$src" %} + ins_encode %{ + __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); + %} + ins_pipe(ialu_imm); +%} + +instruct cmovPL_imm_LEGT_U(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, iRegP dst, immP0 src) %{ + match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(140); + size(4); format %{ "MOVW$cmp $dst,$src" %} ins_encode %{ __ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode)); @@ -8666,7 +8915,7 @@ instruct cmovPL_imm_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, iRegP dst, immP instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{ match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(150); size(4); format %{ "FCPYS$cmp $dst,$src" %} @@ -8678,7 +8927,7 @@ instruct cmovFL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regF dst, regF src) %{ instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{ match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(150); size(4); format %{ "FCPYS$cmp $dst,$src" %} @@ -8690,7 +8939,7 @@ instruct cmovFL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regF dst, regF src) %{ instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF src) %{ match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(150); size(4); format %{ "FCPYS$cmp $dst,$src" %} @@ -8702,7 +8951,7 @@ instruct cmovFL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regF dst, regF instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{ match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge); ins_cost(150); size(4); @@ -8715,7 +8964,7 @@ instruct cmovDL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, regD dst, regD src) %{ instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{ match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne); ins_cost(150); size(4); @@ -8728,7 +8977,7 @@ instruct cmovDL_reg_EQNE(cmpOpL cmp, flagsRegL_EQNE xcc, regD dst, regD src) %{ instruct cmovDL_reg_LEGT(cmpOpL_commute cmp, flagsRegL_LEGT xcc, regD dst, regD src) %{ match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src))); - predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); + predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt); ins_cost(150); size(4); @@ -10351,7 +10600,7 @@ instruct vneg16B_reg(vecX dst, vecX src) %{ ins_pipe( ialu_reg_reg ); // FIXME %} -// ------------------------------ Shift --------------------------------------- +// ------------------------------ ShiftCount ---------------------------------- instruct vslcntD(vecD dst, iRegI cnt) %{ predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd()); @@ -10410,6 +10659,8 @@ instruct vsrcntX(vecX dst, iRegI cnt) %{ ins_pipe( ialu_reg_reg ); // FIXME %} +// ------------------------------ LogicalShift -------------------------------- + // Byte vector logical left/right shift based on sign instruct vsh8B_reg(vecD dst, vecD src, vecD shift) %{ predicate(n->as_Vector()->length() == 8); @@ -10526,9 +10777,9 @@ instruct vsh2L_reg(vecX dst, vecX src, vecX shift) %{ ins_pipe( ialu_reg_reg ); // FIXME %} -// ------------------------------ LeftShift ----------------------------------- +// ------------------------------ LogicalLeftShift ---------------------------- -// Byte vector left shift +// Byte vector logical left shift instruct vsl8B_reg(vecD dst, vecD src, vecD shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (LShiftVB src shift)); @@ -10550,7 +10801,7 @@ instruct vsl16B_reg(vecX dst, vecX src, vecX shift) %{ %} instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{ - predicate(n->as_Vector()->length() == 8); + predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n)); match(Set dst (LShiftVB src (LShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10566,7 +10817,7 @@ instruct vsl8B_immI(vecD dst, vecD src, immI shift) %{ %} instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 16); + predicate(n->as_Vector()->length() == 16 && assert_not_var_shift(n)); match(Set dst (LShiftVB src (LShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10581,11 +10832,10 @@ instruct vsl16B_immI(vecX dst, vecX src, immI shift) %{ ins_pipe( ialu_reg_reg ); // FIXME %} -// Shorts/Chars vector logical left/right shift +// Shorts/Chars vector logical left shift instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (LShiftVS src shift)); - match(Set dst (URShiftVS src shift)); size(4*1); ins_cost(DEFAULT_COST*1); // FIXME expand %{ @@ -10596,7 +10846,6 @@ instruct vsl4S_reg(vecD dst, vecD src, vecD shift) %{ instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (LShiftVS src shift)); - match(Set dst (URShiftVS src shift)); size(4*1); ins_cost(DEFAULT_COST*1); // FIXME expand %{ @@ -10605,7 +10854,7 @@ instruct vsl8S_reg(vecX dst, vecX src, vecX shift) %{ %} instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{ - predicate(n->as_Vector()->length() == 4); + predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n)); match(Set dst (LShiftVS src (LShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10621,7 +10870,7 @@ instruct vsl4S_immI(vecD dst, vecD src, immI shift) %{ %} instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 8); + predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n)); match(Set dst (LShiftVS src shift)); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10636,11 +10885,10 @@ instruct vsl8S_immI(vecX dst, vecX src, immI shift) %{ ins_pipe( ialu_reg_reg ); // FIXME %} -// Integers vector logical left/right shift +// Integers vector logical left shift instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{ predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd()); match(Set dst (LShiftVI src shift)); - match(Set dst (URShiftVI src shift)); size(4*1); ins_cost(DEFAULT_COST*1); // FIXME expand %{ @@ -10651,7 +10899,6 @@ instruct vsl2I_reg(vecD dst, vecD src, vecD shift) %{ instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{ predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd()); match(Set dst (LShiftVI src shift)); - match(Set dst (URShiftVI src shift)); size(4*1); ins_cost(DEFAULT_COST*1); // FIXME expand %{ @@ -10660,7 +10907,9 @@ instruct vsl4I_reg(vecX dst, vecX src, vecX shift) %{ %} instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{ - predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd()); + predicate(n->as_Vector()->length() == 2 && + VM_Version::has_simd() && + assert_not_var_shift(n)); match(Set dst (LShiftVI src (LShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10676,7 +10925,9 @@ instruct vsl2I_immI(vecD dst, vecD src, immI shift) %{ %} instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd()); + predicate(n->as_Vector()->length() == 4 && + VM_Version::has_simd() && + assert_not_var_shift(n)); match(Set dst (LShiftVI src (LShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10691,11 +10942,10 @@ instruct vsl4I_immI(vecX dst, vecX src, immI shift) %{ ins_pipe( ialu_reg_reg ); // FIXME %} -// Longs vector logical left/right shift +// Longs vector logical left shift instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (LShiftVL src shift)); - match(Set dst (URShiftVL src shift)); size(4*1); ins_cost(DEFAULT_COST*1); // FIXME expand %{ @@ -10704,7 +10954,7 @@ instruct vsl2L_reg(vecX dst, vecX src, vecX shift) %{ %} instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 2); + predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n)); match(Set dst (LShiftVL src (LShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10725,9 +10975,79 @@ instruct vsl2L_immI(vecX dst, vecX src, immI shift) %{ // for negative data because java code convert short value into int with // sign extension before a shift. +// Right shift with vector shift count on aarch32 SIMD is implemented as left +// shift by negative shift count value. +// +// Method is_var_shift() denotes that vector shift count is a variable shift: +// 1) for this case, vector shift count should be negated before conducting +// right shifts. E.g., vsrl4S_reg_var rule. +// 2) for the opposite case, vector shift count is generated via RShiftCntV +// rules and is already negated there. Hence, no negation is needed. +// E.g., vsrl4S_reg rule. + // Chars vector logical right shift +instruct vsrl4S_reg(vecD dst, vecD src, vecD shift) %{ + predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVS src shift)); + size(4); + ins_cost(DEFAULT_COST); + expand %{ + vsh4S_reg(dst, src, shift); + %} +%} + +instruct vsrl4S_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{ + predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVS src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B" + "VSHL.U16 $dst.D,$src.D,$tmp.D\t! logical right shift packed4S" + %} + ins_encode %{ + bool quad = false; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_16, quad); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct vsrl8S_reg(vecX dst, vecX src, vecX shift) %{ + predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVS src shift)); + size(4); + ins_cost(DEFAULT_COST); + expand %{ + vsh8S_reg(dst, src, shift); + %} +%} + +instruct vsrl8S_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{ + predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVS src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B" + "VSHL.U16 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed8S" + %} + ins_encode %{ + bool quad = true; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_16, quad); + %} + ins_pipe(ialu_reg_reg); +%} + instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{ - predicate(n->as_Vector()->length() == 4); + predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n)); match(Set dst (URShiftVS src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10743,7 +11063,7 @@ instruct vsrl4S_immI(vecD dst, vecD src, immI shift) %{ %} instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 8); + predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n)); match(Set dst (URShiftVS src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10759,8 +11079,78 @@ instruct vsrl8S_immI(vecX dst, vecX src, immI shift) %{ %} // Integers vector logical right shift +instruct vsrl2I_reg(vecD dst, vecD src, vecD shift) %{ + predicate(n->as_Vector()->length() == 2 && + VM_Version::has_simd() && + !n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVI src shift)); + size(4); + ins_cost(DEFAULT_COST); + expand %{ + vsh2I_reg(dst, src, shift); + %} +%} + +instruct vsrl2I_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{ + predicate(n->as_Vector()->length() == 2 && + VM_Version::has_simd() && + n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVI src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B" + "VSHL.U32 $dst.D,$src.D,$tmp.D\t! logical right shift packed2I" + %} + ins_encode %{ + bool quad = false; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_32, quad); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct vsrl4I_reg(vecX dst, vecX src, vecX shift) %{ + predicate(n->as_Vector()->length() == 4 && + VM_Version::has_simd() && + !n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVI src shift)); + size(4); + ins_cost(DEFAULT_COST); + expand %{ + vsh4I_reg(dst, src, shift); + %} +%} + +instruct vsrl4I_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{ + predicate(n->as_Vector()->length() == 4 && + VM_Version::has_simd() && + n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVI src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B" + "VSHL.U32 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed4I" + %} + ins_encode %{ + bool quad = true; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_32, quad); + %} + ins_pipe(ialu_reg_reg); +%} + instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{ - predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd()); + predicate(n->as_Vector()->length() == 2 && + VM_Version::has_simd() && + assert_not_var_shift(n)); match(Set dst (URShiftVI src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10776,7 +11166,9 @@ instruct vsrl2I_immI(vecD dst, vecD src, immI shift) %{ %} instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 4 && VM_Version::has_simd()); + predicate(n->as_Vector()->length() == 4 && + VM_Version::has_simd() && + assert_not_var_shift(n)); match(Set dst (URShiftVI src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10792,8 +11184,38 @@ instruct vsrl4I_immI(vecX dst, vecX src, immI shift) %{ %} // Longs vector logical right shift +instruct vsrl2L_reg(vecX dst, vecX src, vecX shift) %{ + predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVL src shift)); + size(4); + ins_cost(DEFAULT_COST); + expand %{ + vsh2L_reg(dst, src, shift); + %} +%} + +instruct vsrl2L_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{ + predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift()); + match(Set dst (URShiftVL src shift)); + effect(TEMP tmp, DEF dst, USE src, USE shift); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B" + "VSHL.U64 $dst.Q,$src.Q,$tmp.Q\t! logical right shift packed2L" + %} + ins_encode %{ + bool quad = true; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlUI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_64, quad); + %} + ins_pipe(ialu_reg_reg); +%} + instruct vsrl2L_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 2); + predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n)); match(Set dst (URShiftVL src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10927,9 +11349,8 @@ instruct vsha2L_reg(vecX dst, vecX src, vecX shift) %{ %} // Byte vector arithmetic right shift - instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{ - predicate(n->as_Vector()->length() == 8); + predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVB src shift)); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10938,8 +11359,28 @@ instruct vsra8B_reg(vecD dst, vecD src, vecD shift) %{ %} %} -instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{ - predicate(n->as_Vector()->length() == 16); +instruct vsra8B_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{ + predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift()); + match(Set dst (RShiftVB src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B" + "VSHL.S8 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed8B" + %} + ins_encode %{ + bool quad = false; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct vsra16B_reg(vecX dst, vecX src, vecX shift) %{ + predicate(n->as_Vector()->length() == 16 && !n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVB src shift)); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10948,13 +11389,33 @@ instruct vsrl16B_reg(vecX dst, vecX src, vecX shift) %{ %} %} -instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{ - predicate(n->as_Vector()->length() == 8); +instruct vsra16B_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{ + predicate(n->as_Vector()->length() == 16 && n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVB src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B" + "VSHL.S8 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed16B" + %} + ins_encode %{ + bool quad = true; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct vsra8B_immI(vecD dst, vecD src, immI shift) %{ + predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n)); + match(Set dst (RShiftVB src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME format %{ - "VSHR.S8 $dst.D,$src.D,$shift\t! logical right shift packed8B" + "VSHR.S8 $dst.D,$src.D,$shift\t! arithmetic right shift packed8B" %} ins_encode %{ bool quad = false; @@ -10964,13 +11425,13 @@ instruct vsrl8B_immI(vecD dst, vecD src, immI shift) %{ ins_pipe( ialu_reg_reg ); // FIXME %} -instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 16); - match(Set dst (RShiftVB src shift)); +instruct vsra16B_immI(vecX dst, vecX src, immI shift) %{ + predicate(n->as_Vector()->length() == 16 && assert_not_var_shift(n)); + match(Set dst (RShiftVB src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME format %{ - "VSHR.S8 $dst.Q,$src.Q,$shift\t! logical right shift packed16B" + "VSHR.S8 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed16B" %} ins_encode %{ bool quad = true; @@ -10982,7 +11443,7 @@ instruct vsrl16B_immI(vecX dst, vecX src, immI shift) %{ // Shorts vector arithmetic right shift instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{ - predicate(n->as_Vector()->length() == 4); + predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVS src shift)); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -10991,8 +11452,28 @@ instruct vsra4S_reg(vecD dst, vecD src, vecD shift) %{ %} %} +instruct vsra4S_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{ + predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift()); + match(Set dst (RShiftVS src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B" + "VSHL.S16 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed4S" + %} + ins_encode %{ + bool quad = false; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_16, quad); + %} + ins_pipe(ialu_reg_reg); +%} + instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{ - predicate(n->as_Vector()->length() == 8); + predicate(n->as_Vector()->length() == 8 && !n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVS src shift)); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -11001,13 +11482,33 @@ instruct vsra8S_reg(vecX dst, vecX src, vecX shift) %{ %} %} -instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{ - predicate(n->as_Vector()->length() == 4); +instruct vsra8S_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{ + predicate(n->as_Vector()->length() == 8 && n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVS src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B" + "VSHL.S16 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed8S" + %} + ins_encode %{ + bool quad = true; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_16, quad); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{ + predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n)); + match(Set dst (RShiftVS src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME format %{ - "VSHR.S16 $dst.D,$src.D,$shift\t! logical right shift packed4S" + "VSHR.S16 $dst.D,$src.D,$shift\t! arithmetic right shift packed4S" %} ins_encode %{ bool quad = false; @@ -11018,12 +11519,12 @@ instruct vsra4S_immI(vecD dst, vecD src, immI shift) %{ %} instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 8); - match(Set dst (RShiftVS src shift)); + predicate(n->as_Vector()->length() == 8 && assert_not_var_shift(n)); + match(Set dst (RShiftVS src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME format %{ - "VSHR.S16 $dst.Q,$src.Q,$shift\t! logical right shift packed8S" + "VSHR.S16 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed8S" %} ins_encode %{ bool quad = true; @@ -11035,7 +11536,7 @@ instruct vsra8S_immI(vecX dst, vecX src, immI shift) %{ // Integers vector arithmetic right shift instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{ - predicate(n->as_Vector()->length() == 2); + predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVI src shift)); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -11044,8 +11545,28 @@ instruct vsra2I_reg(vecD dst, vecD src, vecD shift) %{ %} %} +instruct vsra2I_reg_var(vecD dst, vecD src, vecD shift, vecD tmp) %{ + predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift()); + match(Set dst (RShiftVI src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.D,$shift.D\n\t! neg packed8B" + "VSHL.S32 $dst.D,$src.D,$tmp.D\t! arithmetic right shift packed2I" + %} + ins_encode %{ + bool quad = false; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_32, quad); + %} + ins_pipe(ialu_reg_reg); +%} + instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{ - predicate(n->as_Vector()->length() == 4); + predicate(n->as_Vector()->length() == 4 && !n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVI src shift)); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -11054,13 +11575,33 @@ instruct vsra4I_reg(vecX dst, vecX src, vecX shift) %{ %} %} -instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{ - predicate(n->as_Vector()->length() == 2); +instruct vsra4I_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{ + predicate(n->as_Vector()->length() == 4 && n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVI src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B" + "VSHL.S32 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed4I" + %} + ins_encode %{ + bool quad = true; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_32, quad); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{ + predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n)); + match(Set dst (RShiftVI src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME format %{ - "VSHR.S32 $dst.D,$src.D,$shift\t! logical right shift packed2I" + "VSHR.S32 $dst.D,$src.D,$shift\t! arithmetic right shift packed2I" %} ins_encode %{ bool quad = false; @@ -11071,12 +11612,12 @@ instruct vsra2I_immI(vecD dst, vecD src, immI shift) %{ %} instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 4); - match(Set dst (RShiftVI src shift)); + predicate(n->as_Vector()->length() == 4 && assert_not_var_shift(n)); + match(Set dst (RShiftVI src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME format %{ - "VSHR.S32 $dst.Q,$src.Q,$shift\t! logical right shift packed4I" + "VSHR.S32 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed4I" %} ins_encode %{ bool quad = true; @@ -11088,7 +11629,7 @@ instruct vsra4I_immI(vecX dst, vecX src, immI shift) %{ // Longs vector arithmetic right shift instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{ - predicate(n->as_Vector()->length() == 2); + predicate(n->as_Vector()->length() == 2 && !n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVL src shift)); size(4); ins_cost(DEFAULT_COST); // FIXME @@ -11097,13 +11638,33 @@ instruct vsra2L_reg(vecX dst, vecX src, vecX shift) %{ %} %} -instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{ - predicate(n->as_Vector()->length() == 2); +instruct vsra2L_reg_var(vecX dst, vecX src, vecX shift, vecX tmp) %{ + predicate(n->as_Vector()->length() == 2 && n->as_ShiftV()->is_var_shift()); match(Set dst (RShiftVL src shift)); + effect(TEMP tmp); + size(4*2); + ins_cost(DEFAULT_COST*2); + format %{ + "VNEG.S8 $tmp.Q,$shift.Q\n\t! neg packed16B" + "VSHL.S64 $dst.Q,$src.Q,$tmp.Q\t! arithmetic right shift packed2L" + %} + ins_encode %{ + bool quad = true; + __ vnegI($tmp$$FloatRegister, $shift$$FloatRegister, + MacroAssembler::VELEM_SIZE_8, quad); + __ vshlSI($dst$$FloatRegister, $tmp$$FloatRegister, $src$$FloatRegister, + MacroAssembler::VELEM_SIZE_64, quad); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct vsra2L_immI(vecX dst, vecX src, immI shift) %{ + predicate(n->as_Vector()->length() == 2 && assert_not_var_shift(n)); + match(Set dst (RShiftVL src (RShiftCntV shift))); size(4); ins_cost(DEFAULT_COST); // FIXME format %{ - "VSHR.S64 $dst.Q,$src.Q,$shift\t! logical right shift packed2L" + "VSHR.S64 $dst.Q,$src.Q,$shift\t! arithmetic right shift packed2L" %} ins_encode %{ bool quad = true; diff --git a/src/hotspot/cpu/arm/assembler_arm_32.cpp b/src/hotspot/cpu/arm/assembler_arm_32.cpp index 5dd9d39392a0e7d595e779c65af863d8eec0a3bf..6cb6e19cbd5b88d3ee9430496dcbded16ae06969 100644 --- a/src/hotspot/cpu/arm/assembler_arm_32.cpp +++ b/src/hotspot/cpu/arm/assembler_arm_32.cpp @@ -46,7 +46,7 @@ // Convert the raw encoding form into the form expected by the // constructor for Address. Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) { - RelocationHolder rspec; + RelocationHolder rspec = RelocationHolder::none; if (disp_reloc != relocInfo::none) { rspec = Relocation::spec_simple(disp_reloc); } diff --git a/src/hotspot/cpu/arm/bytes_arm.hpp b/src/hotspot/cpu/arm/bytes_arm.hpp index b0d481f314d13ca05e1495c35bd8cecd53dc79fb..34af43edcac0b4656e277b00cf17bca360b29fb6 100644 --- a/src/hotspot/cpu/arm/bytes_arm.hpp +++ b/src/hotspot/cpu/arm/bytes_arm.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef CPU_ARM_BYTES_ARM_HPP #define CPU_ARM_BYTES_ARM_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" #ifndef VM_LITTLE_ENDIAN diff --git a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp index 3ec2db3b313814fb0bcdceba56e31820cacc4b2b..f7ffe84618d1c59c6646a753047f27c29740392c 100644 --- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp @@ -1680,6 +1680,9 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr } else { assert(right->is_constant(), "must be"); const uint c = (uint)right->as_constant_ptr()->as_jint(); + if (!Assembler::is_arith_imm_in_range(c)) { + BAILOUT("illegal arithmetic operand"); + } switch (code) { case lir_logic_and: __ and_32(res, lreg, c); break; case lir_logic_or: __ orr_32(res, lreg, c); break; @@ -1820,8 +1823,8 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, __ teq(xhi, yhi); __ teq(xlo, ylo, eq); } else { - __ subs(xlo, xlo, ylo); - __ sbcs(xhi, xhi, yhi); + __ subs(Rtemp, xlo, ylo); + __ sbcs(Rtemp, xhi, yhi); } } else { ShouldNotReachHere(); @@ -2425,7 +2428,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) { Register hdr = op->hdr_opr()->as_pointer_register(); Register lock = op->lock_opr()->as_pointer_register(); - if (!UseFastLocking) { + if (UseHeavyMonitors) { __ b(*op->stub()->entry()); } else if (op->code() == lir_lock) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); diff --git a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp index 0a5b80b23b7659ac35ad4c2cd2fbed4335379503..69a76f4beb0d32882437d4a6227b66840e0fa227 100644 --- a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp @@ -377,7 +377,7 @@ void LIRGenerator::CardTableBarrierSet_post_barrier_helper(LIR_Opr addr, LIR_Con // Use unsigned type T_BOOLEAN here rather than (signed) T_BYTE since signed load // byte instruction does not support the addressing mode we need. - LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BOOLEAN); + LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift(), 0, T_BOOLEAN); if (UseCondCardMark) { LIR_Opr cur_value = new_register(T_INT); __ move(card_addr, cur_value); diff --git a/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp index 7f1d4341872c2dc36af92b4f011a9d6c64cf73a8..1bf3ce5c23d6494bd01581cfc892567626d041bd 100644 --- a/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp @@ -69,8 +69,8 @@ void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) { raw_pop(FP, LR); } -void C1_MacroAssembler::verified_entry() { - if (C1Breakpoint) { +void C1_MacroAssembler::verified_entry(bool breakAtEntry) { + if (breakAtEntry) { breakpoint(); } } diff --git a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp index 63bf45b8db5d38e4e84f0028c4dcce73108032f9..765b05e779b9e5e2164b297884ace283f6a12c90 100644 --- a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp @@ -218,7 +218,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, const Register card_addr = tmp1; __ mov_address(tmp2, (address)ct->byte_map_base()); - __ add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTable::card_shift)); + __ add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTable::card_shift())); __ ldrb(tmp2, Address(card_addr)); __ cmp(tmp2, (int)G1CardTable::g1_young_card_val()); @@ -452,7 +452,7 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* // explicitly specify that 'cardtable' has a relocInfo::none // type. __ lea(r_card_base_1, cardtable); - __ add(r_card_addr_0, r_card_base_1, AsmOperand(r_obj_0, lsr, CardTable::card_shift)); + __ add(r_card_addr_0, r_card_base_1, AsmOperand(r_obj_0, lsr, CardTable::card_shift())); // first quick check without barrier __ ldrb(r_tmp2, Address(r_card_addr_0)); diff --git a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp index 86f43597e220bb1b7f302dc59422cf0320e36de1..11b2ca2ef1d8c4a7dbbac6396c0903d3ac2d131c 100644 --- a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp @@ -55,8 +55,8 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ add_ptr_scaled_int32(count, addr, count, LogBytesPerHeapOop); __ sub(count, count, BytesPerHeapOop); // last addr - __ logical_shift_right(addr, addr, CardTable::card_shift); - __ logical_shift_right(count, count, CardTable::card_shift); + __ logical_shift_right(addr, addr, CardTable::card_shift()); + __ logical_shift_right(count, count, CardTable::card_shift()); __ sub(count, count, addr); // nb of cards // warning: Rthread has not been preserved @@ -129,7 +129,7 @@ void CardTableBarrierSetAssembler::store_check_part2(MacroAssembler* masm, Regis "Wrong barrier set kind"); assert(CardTable::dirty_card_val() == 0, "Dirty card value must be 0 due to optimizations."); - Address card_table_addr(card_table_base, obj, lsr, CardTable::card_shift); + Address card_table_addr(card_table_base, obj, lsr, CardTable::card_shift()); if (UseCondCardMark) { Label already_dirty; diff --git a/src/hotspot/cpu/arm/jniTypes_arm.hpp b/src/hotspot/cpu/arm/jniTypes_arm.hpp index 66596eac1a0346b7135d56946e9458afe00e5145..660e58110f886fac0583f0cbef71e5d8085189ff 100644 --- a/src/hotspot/cpu/arm/jniTypes_arm.hpp +++ b/src/hotspot/cpu/arm/jniTypes_arm.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define CPU_ARM_JNITYPES_ARM_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive jni diff --git a/src/hotspot/cpu/arm/matcher_arm.hpp b/src/hotspot/cpu/arm/matcher_arm.hpp index 6254f4b33991d66069d47cf02aee04e1e7ed4e7d..7552b014c061eaba521fc77f472cbf3fe76a8722 100644 --- a/src/hotspot/cpu/arm/matcher_arm.hpp +++ b/src/hotspot/cpu/arm/matcher_arm.hpp @@ -56,9 +56,6 @@ // No support for generic vector operands. static const bool supports_generic_vector_operands = false; - // No support for 48 extra htbl entries in aes-gcm intrinsic - static const int htbl_entries = -1; - static constexpr bool isSimpleConstant64(jlong value) { // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. return false; diff --git a/src/hotspot/cpu/arm/vm_version_arm.hpp b/src/hotspot/cpu/arm/vm_version_arm.hpp index a6e2dc8b442198115b3f4ad62fa36aefa16c4053..bdc3df12eb9f4d0b7fc4166583ccab5639efac70 100644 --- a/src/hotspot/cpu/arm/vm_version_arm.hpp +++ b/src/hotspot/cpu/arm/vm_version_arm.hpp @@ -106,6 +106,7 @@ class VM_Version: public Abstract_VM_Version { friend class VM_Version_StubGenerator; + static void initialize_cpu_information(void); }; #endif // CPU_ARM_VM_VERSION_ARM_HPP diff --git a/src/hotspot/cpu/arm/vm_version_arm_32.cpp b/src/hotspot/cpu/arm/vm_version_arm_32.cpp index a31857d9a47227a228f9bd65e3e0e37fdee59d8a..9e228b3d75191f84870891dde5021cf0a0618ec7 100644 --- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp +++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp @@ -347,3 +347,17 @@ void VM_Version::initialize() { _is_initialized = true; } + +void VM_Version::initialize_cpu_information(void) { + // do nothing if cpu info has been initialized + if (_initialized) { + return; + } + + _no_of_cores = os::processor_count(); + _no_of_threads = _no_of_cores; + _no_of_sockets = _no_of_cores; + snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "ARM%d", _arm_arch); + snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string); + _initialized = true; +} diff --git a/src/hotspot/cpu/arm/vm_version_ext_arm.cpp b/src/hotspot/cpu/arm/vm_version_ext_arm.cpp deleted file mode 100644 index 0e2a1ffa1369f9e13e66b0cfaa3811aeff6e0830..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/arm/vm_version_ext_arm.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" -#include "runtime/os.inline.hpp" -#include "vm_version_ext_arm.hpp" - -// VM_Version_Ext statics -int VM_Version_Ext::_no_of_threads = 0; -int VM_Version_Ext::_no_of_cores = 0; -int VM_Version_Ext::_no_of_sockets = 0; -bool VM_Version_Ext::_initialized = false; -char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0}; -char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0}; - -void VM_Version_Ext::initialize_cpu_information(void) { - // do nothing if cpu info has been initialized - if (_initialized) { - return; - } - - int core_id = -1; - int chip_id = -1; - int len = 0; - char* src_string = NULL; - - _no_of_cores = os::processor_count(); - _no_of_threads = _no_of_cores; - _no_of_sockets = _no_of_cores; - snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "ARM%d", _arm_arch); - snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string); - _initialized = true; -} - -int VM_Version_Ext::number_of_threads(void) { - initialize_cpu_information(); - return _no_of_threads; -} - -int VM_Version_Ext::number_of_cores(void) { - initialize_cpu_information(); - return _no_of_cores; -} - -int VM_Version_Ext::number_of_sockets(void) { - initialize_cpu_information(); - return _no_of_sockets; -} - -const char* VM_Version_Ext::cpu_name(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE); - return tmp; -} - -const char* VM_Version_Ext::cpu_description(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE); - return tmp; -} diff --git a/src/hotspot/cpu/arm/vm_version_ext_arm.hpp b/src/hotspot/cpu/arm/vm_version_ext_arm.hpp deleted file mode 100644 index 77fc4615e1b4450b02d42ebd0a6b80fd8c8d81f0..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/arm/vm_version_ext_arm.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_ARM_VM_VERSION_EXT_ARM_HPP -#define CPU_ARM_VM_VERSION_EXT_ARM_HPP - -#include "runtime/vm_version.hpp" -#include "utilities/macros.hpp" - -class VM_Version_Ext : public VM_Version { - private: - static const size_t CPU_TYPE_DESC_BUF_SIZE = 256; - static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096; - - static int _no_of_threads; - static int _no_of_cores; - static int _no_of_sockets; - static bool _initialized; - static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE]; - static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE]; - - public: - static int number_of_threads(void); - static int number_of_cores(void); - static int number_of_sockets(void); - - static const char* cpu_name(void); - static const char* cpu_description(void); - static void initialize_cpu_information(void); - -}; - -#endif // CPU_ARM_VM_VERSION_EXT_ARM_HPP diff --git a/src/hotspot/cpu/ppc/bytes_ppc.hpp b/src/hotspot/cpu/ppc/bytes_ppc.hpp index 8249068ecd6f0d71e211faa956772ff30435da1a..a4d061e9b732fa8f2613a64d0e86853ff53e40a6 100644 --- a/src/hotspot/cpu/ppc/bytes_ppc.hpp +++ b/src/hotspot/cpu/ppc/bytes_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2016 SAP SE. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #ifndef CPU_PPC_BYTES_PPC_HPP #define CPU_PPC_BYTES_PPC_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Bytes: AllStatic { public: diff --git a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp index 4f329d2e63333accbc0d53651f2bc3367e0f7310..109372bb1a4b155daebdfb5e64f03ecda14f3aaf 100644 --- a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp @@ -81,8 +81,6 @@ void RangeCheckStub::emit_code(LIR_Assembler* ce) { if (_info->deoptimize_on_exception()) { address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); - // May be used by optimizations like LoopInvariantCodeMotion or RangeCheckEliminator. - DEBUG_ONLY( __ untested("RangeCheckStub: predicate_failed_trap_id"); ) //__ load_const_optimized(R0, a); __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a)); __ mtctr(R0); diff --git a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp index 23e03cb36e361c712d1907796e5a08cf061f1d6e..b04c49152f3fb81e72a721c61d6592549f208669 100644 --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp @@ -942,9 +942,10 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi tmp = FrameMap::R0_opr; if (UseCompressedOops && !wide && c->as_jobject() != NULL) { AddressLiteral oop_addr = __ constant_oop_address(c->as_jobject()); - __ lis(R0, oop_addr.value() >> 16); // Don't care about sign extend (will use stw). + // Don't care about sign extend (will use stw). + __ lis(R0, 0); // Will get patched. __ relocate(oop_addr.rspec(), /*compressed format*/ 1); - __ ori(R0, R0, oop_addr.value() & 0xffff); + __ ori(R0, R0, 0); // Will get patched. } else { jobject2reg(c->as_jobject(), R0); } @@ -2689,7 +2690,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) { // Obj may not be an oop. if (op->code() == lir_lock) { MonitorEnterStub* stub = (MonitorEnterStub*)op->stub(); - if (UseFastLocking) { + if (!UseHeavyMonitors) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); // Add debug info for NullPointerException only if one is possible. if (op->info() != NULL) { @@ -2711,7 +2712,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) { } } else { assert (op->code() == lir_unlock, "Invalid code, expected lir_unlock"); - if (UseFastLocking) { + if (!UseHeavyMonitors) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); __ unlock_object(hdr, obj, lock, *op->stub()->entry()); } else { diff --git a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp index 2e7fb125eb3b6640ddb7587c8654a5bdae14e22c..fba889385ba6a5ba712db642ec301c659f414561 100644 --- a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp @@ -86,8 +86,8 @@ void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_by } -void C1_MacroAssembler::verified_entry() { - if (C1Breakpoint) illtrap(); +void C1_MacroAssembler::verified_entry(bool breakAtEntry) { + if (breakAtEntry) illtrap(); // build frame } diff --git a/src/hotspot/cpu/ppc/frame_ppc.cpp b/src/hotspot/cpu/ppc/frame_ppc.cpp index 870345789d6112339549d9964ebe4e7c9da3b531..b8e6433913b80a0956d720c745c41a9e2c33fbd7 100644 --- a/src/hotspot/cpu/ppc/frame_ppc.cpp +++ b/src/hotspot/cpu/ppc/frame_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -294,9 +294,57 @@ void frame::patch_pc(Thread* thread, address pc) { } bool frame::is_interpreted_frame_valid(JavaThread* thread) const { - // Is there anything to do? assert(is_interpreted_frame(), "Not an interpreted frame"); - return true; + // These are reasonable sanity checks + if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) { + return false; + } + if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { + return false; + } + int min_frame_slots = (abi_minframe_size + ijava_state_size) / sizeof(intptr_t); + if (fp() - min_frame_slots < sp()) { + return false; + } + // These are hacks to keep us out of trouble. + // The problem with these is that they mask other problems + if (fp() <= sp()) { // this attempts to deal with unsigned comparison above + return false; + } + + // do some validation of frame elements + + // first the method + + Method* m = *interpreter_frame_method_addr(); + + // validate the method we'd find in this potential sender + if (!Method::is_valid_method(m)) return false; + + // stack frames shouldn't be much larger than max_stack elements + // this test requires the use of unextended_sp which is the sp as seen by + // the current frame, and not sp which is the "raw" pc which could point + // further because of local variables of the callee method inserted after + // method arguments + if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { + return false; + } + + // validate bci/bcx + + address bcp = interpreter_frame_bcp(); + if (m->validate_bci_from_bcp(bcp) < 0) { + return false; + } + + // validate constantPoolCache* + ConstantPoolCache* cp = *interpreter_frame_cache_addr(); + if (MetaspaceObj::is_valid(cp) == false) return false; + + // validate locals + + address locals = (address) *interpreter_frame_locals_addr(); + return thread->is_in_stack_range_incl(locals, (address)fp()); } BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { diff --git a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp index a9328e8d616705b0e2caa8e40c254b5e46816a10..05c8374cfa4c8ca55d0c064308af9a4d45eb622c 100644 --- a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp @@ -245,7 +245,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Decorato Register Rbase = tmp2; __ load_const_optimized(Rbase, (address)(ct->card_table()->byte_map_base()), /*temp*/ tmp3); - __ srdi(Rcard_addr, store_addr, CardTable::card_shift); + __ srdi(Rcard_addr, store_addr, CardTable::card_shift()); // Get the address of the card. __ lbzx(/*card value*/ tmp3, Rbase, Rcard_addr); @@ -516,7 +516,7 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* __ std(addr, -8, R1_SP); __ std(tmp2, -16, R1_SP); - __ srdi(addr, R0, CardTable::card_shift); // Addr is passed in R0. + __ srdi(addr, R0, CardTable::card_shift()); // Addr is passed in R0. __ load_const_optimized(/*cardtable*/ tmp2, byte_map_base, tmp); __ add(addr, tmp2, addr); __ lbz(tmp, 0, addr); // tmp := [addr + cardtable] diff --git a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp index 8337317e3f2cc1a431aa8832d87005a72c222381..0d80f2fd95484922d76476d7fdcbe2c0c5c2d9cf 100644 --- a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp @@ -54,8 +54,8 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ addi(count, count, -BytesPerHeapOop); __ add(count, addr, count); // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.) - __ srdi(addr, addr, CardTable::card_shift); - __ srdi(count, count, CardTable::card_shift); + __ srdi(addr, addr, CardTable::card_shift()); + __ srdi(count, count, CardTable::card_shift()); __ subf(count, addr, count); __ add_const_optimized(addr, addr, (address)ct->byte_map_base(), R0); __ addi(count, count, 1); @@ -74,7 +74,7 @@ void CardTableBarrierSetAssembler::card_table_write(MacroAssembler* masm, Register tmp, Register obj) { assert_different_registers(obj, tmp, R0); __ load_const_optimized(tmp, (address)byte_map_base, R0); - __ srdi(obj, obj, CardTable::card_shift); + __ srdi(obj, obj, CardTable::card_shift()); __ li(R0, CardTable::dirty_card_val()); __ stbx(R0, tmp, obj); } diff --git a/src/hotspot/cpu/ppc/jniTypes_ppc.hpp b/src/hotspot/cpu/ppc/jniTypes_ppc.hpp index ef1fe4acfdf4bd8562e44e584d237473f2c18426..13ccaf408e9686f47fa29a6bd9c0a941f17576fd 100644 --- a/src/hotspot/cpu/ppc/jniTypes_ppc.hpp +++ b/src/hotspot/cpu/ppc/jniTypes_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2013 SAP SE. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #define CPU_PPC_JNITYPES_PPC_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index 98565003691a45fd9c35ea0609d3c8ec2717cd60..d8397ed6fa5382e12e5981854a46a50997b26fc0 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,7 +233,7 @@ address MacroAssembler::patch_set_narrow_oop(address a, address bound, narrowOop return inst1_addr; } -// Get compressed oop or klass constant. +// Get compressed oop constant. narrowOop MacroAssembler::get_narrow_oop(address a, address bound) { assert(UseCompressedOops, "Should only patch compressed oops"); @@ -2660,27 +2660,32 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register andi_(temp, displaced_header, markWord::monitor_value); bne(CCR0, object_has_monitor); - // Set displaced_header to be (markWord of object | UNLOCK_VALUE). - ori(displaced_header, displaced_header, markWord::unlocked_value); - - // Load Compare Value application register. - - // Initialize the box. (Must happen before we update the object mark!) - std(displaced_header, BasicLock::displaced_header_offset_in_bytes(), box); - - // Must fence, otherwise, preceding store(s) may float below cmpxchg. - // Compare object markWord with mark and if equal exchange scratch1 with object markWord. - cmpxchgd(/*flag=*/flag, - /*current_value=*/current_header, - /*compare_value=*/displaced_header, - /*exchange_value=*/box, - /*where=*/oop, - MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq, - MacroAssembler::cmpxchgx_hint_acquire_lock(), - noreg, - &cas_failed, - /*check without membar and ldarx first*/true); - assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + if (!UseHeavyMonitors) { + // Set displaced_header to be (markWord of object | UNLOCK_VALUE). + ori(displaced_header, displaced_header, markWord::unlocked_value); + + // Load Compare Value application register. + + // Initialize the box. (Must happen before we update the object mark!) + std(displaced_header, BasicLock::displaced_header_offset_in_bytes(), box); + + // Must fence, otherwise, preceding store(s) may float below cmpxchg. + // Compare object markWord with mark and if equal exchange scratch1 with object markWord. + cmpxchgd(/*flag=*/flag, + /*current_value=*/current_header, + /*compare_value=*/displaced_header, + /*exchange_value=*/box, + /*where=*/oop, + MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq, + MacroAssembler::cmpxchgx_hint_acquire_lock(), + noreg, + &cas_failed, + /*check without membar and ldarx first*/true); + assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + } else { + // Set NE to indicate 'failure' -> take slow-path. + crandc(flag, Assembler::equal, flag, Assembler::equal); + } // If the compare-and-exchange succeeded, then we found an unlocked // object and we have now locked it. @@ -2727,16 +2732,17 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register // Store a non-null value into the box. std(box, BasicLock::displaced_header_offset_in_bytes(), box); + beq(flag, cont); -# ifdef ASSERT + // Check for recursive locking. + cmpd(flag, current_header, R16_thread); bne(flag, cont); - // We have acquired the monitor, check some invariants. - addi(/*monitor=*/temp, temp, -ObjectMonitor::owner_offset_in_bytes()); - // Invariant 1: _recursions should be 0. - //assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); - asm_assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), temp, - "monitor->_recursions should be 0"); -# endif + + // Current thread already owns the lock. Just increment recursions. + Register recursions = displaced_header; + ld(recursions, ObjectMonitor::recursions_offset_in_bytes()-ObjectMonitor::owner_offset_in_bytes(), temp); + addi(recursions, recursions, 1); + std(recursions, ObjectMonitor::recursions_offset_in_bytes()-ObjectMonitor::owner_offset_in_bytes(), temp); #if INCLUDE_RTM_OPT } // use_rtm() @@ -2752,8 +2758,7 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe bool use_rtm) { assert_different_registers(oop, box, temp, displaced_header, current_header); assert(flag != CCR0, "bad condition register"); - Label cont; - Label object_has_monitor; + Label cont, object_has_monitor, notRecursive; #if INCLUDE_RTM_OPT if (UseRTMForStackLocks && use_rtm) { @@ -2768,12 +2773,14 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe } #endif - // Find the lock address and load the displaced header from the stack. - ld(displaced_header, BasicLock::displaced_header_offset_in_bytes(), box); + if (!UseHeavyMonitors) { + // Find the lock address and load the displaced header from the stack. + ld(displaced_header, BasicLock::displaced_header_offset_in_bytes(), box); - // If the displaced header is 0, we have a recursive unlock. - cmpdi(flag, displaced_header, 0); - beq(flag, cont); + // If the displaced header is 0, we have a recursive unlock. + cmpdi(flag, displaced_header, 0); + beq(flag, cont); + } // Handle existing monitor. // The object has an existing monitor iff (mark & monitor_value) != 0. @@ -2782,20 +2789,24 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe andi_(R0, current_header, markWord::monitor_value); bne(CCR0, object_has_monitor); - // Check if it is still a light weight lock, this is is true if we see - // the stack address of the basicLock in the markWord of the object. - // Cmpxchg sets flag to cmpd(current_header, box). - cmpxchgd(/*flag=*/flag, - /*current_value=*/current_header, - /*compare_value=*/box, - /*exchange_value=*/displaced_header, - /*where=*/oop, - MacroAssembler::MemBarRel, - MacroAssembler::cmpxchgx_hint_release_lock(), - noreg, - &cont); - - assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + if (!UseHeavyMonitors) { + // Check if it is still a light weight lock, this is is true if we see + // the stack address of the basicLock in the markWord of the object. + // Cmpxchg sets flag to cmpd(current_header, box). + cmpxchgd(/*flag=*/flag, + /*current_value=*/current_header, + /*compare_value=*/box, + /*exchange_value=*/displaced_header, + /*where=*/oop, + MacroAssembler::MemBarRel, + MacroAssembler::cmpxchgx_hint_release_lock(), + noreg, + &cont); + assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); + } else { + // Set NE to indicate 'failure' -> take slow-path. + crandc(flag, Assembler::equal, flag, Assembler::equal); + } // Handle existing monitor. b(cont); @@ -2819,11 +2830,16 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe #endif ld(displaced_header, ObjectMonitor::recursions_offset_in_bytes(), current_header); - xorr(temp, R16_thread, temp); // Will be 0 if we are the owner. - orr(temp, temp, displaced_header); // Will be 0 if there are 0 recursions. - cmpdi(flag, temp, 0); + + cmpd(flag, temp, R16_thread); bne(flag, cont); + addic_(displaced_header, displaced_header, -1); + blt(CCR0, notRecursive); // Not recursive if negative after decrement. + std(displaced_header, ObjectMonitor::recursions_offset_in_bytes(), current_header); + b(cont); // flag is already EQ here. + + bind(notRecursive); ld(temp, ObjectMonitor::EntryList_offset_in_bytes(), current_header); ld(displaced_header, ObjectMonitor::cxq_offset_in_bytes(), current_header); orr(temp, temp, displaced_header); // Will be 0 if both are 0. diff --git a/src/hotspot/cpu/ppc/matcher_ppc.hpp b/src/hotspot/cpu/ppc/matcher_ppc.hpp index c07525bf79e71ab8882e6ee851f73710ad312174..df2074dee24001b286dc90d0f27392cb7ec2d9f5 100644 --- a/src/hotspot/cpu/ppc/matcher_ppc.hpp +++ b/src/hotspot/cpu/ppc/matcher_ppc.hpp @@ -57,9 +57,6 @@ // No support for generic vector operands. static const bool supports_generic_vector_operands = false; - // No support for 48 extra htbl entries in aes-gcm intrinsic - static const int htbl_entries = -1; - static constexpr bool isSimpleConstant64(jlong value) { // Probably always true, even if a temp register is required. return true; diff --git a/src/hotspot/cpu/ppc/nativeInst_ppc.hpp b/src/hotspot/cpu/ppc/nativeInst_ppc.hpp index 03b03238b025bdbef7110f7bfc88ace304532e6b..e9cc46e868112e82c505c5029c289b32818c0c3a 100644 --- a/src/hotspot/cpu/ppc/nativeInst_ppc.hpp +++ b/src/hotspot/cpu/ppc/nativeInst_ppc.hpp @@ -257,7 +257,7 @@ class NativeMovConstReg: public NativeInstruction { // Patch the code stream and oop pool. void set_data(intptr_t x); - // Patch narrow oop constants. Use this also for narrow klass. + // Patch narrow oop constants. void set_narrow_oop(narrowOop data, CodeBlob *code = NULL); void verify() NOT_DEBUG_RETURN; diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 2ced017e2f400a007c8f2529d8d413b0d61b6261..832982deb4552f1477017ba7ab174dacd72c1e47 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -2185,7 +2185,7 @@ const RegMask* Matcher::predicate_reg_mask(void) { return NULL; } -const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { +const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { return NULL; } @@ -5953,7 +5953,7 @@ instruct loadConN_hi(iRegNdst dst, immN src) %{ format %{ "LIS $dst, $src \t// narrow oop hi" %} size(4); ins_encode %{ - __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); + __ lis($dst$$Register, 0); // Will get patched. %} ins_pipe(pipe_class_default); %} @@ -5966,11 +5966,9 @@ instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} size(4); ins_encode %{ - assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); - int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - __ relocate(rspec, 1); - __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); + AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant); + __ relocate(addrlit.rspec(), /*compressed format*/ 1); + __ ori($dst$$Register, $src1$$Register, 0); // Will get patched. %} ins_pipe(pipe_class_default); %} @@ -6085,12 +6083,9 @@ instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} size(4); ins_encode %{ - intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant); - assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); - int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); - RelocationHolder rspec = metadata_Relocation::spec(klass_index); - - __ relocate(rspec, 1); + // Notify OOP recorder (don't need the relocation) + AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant); + intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value()); __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); %} ins_pipe(pipe_class_default); diff --git a/src/hotspot/cpu/ppc/relocInfo_ppc.cpp b/src/hotspot/cpu/ppc/relocInfo_ppc.cpp index 71ced03459f9e5914223e748f91b37746dae80bf..a3a63c6283faf1f0d554bd4df2056cefcb591192 100644 --- a/src/hotspot/cpu/ppc/relocInfo_ppc.cpp +++ b/src/hotspot/cpu/ppc/relocInfo_ppc.cpp @@ -33,34 +33,15 @@ #include "runtime/safepoint.hpp" void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) { - // The following comment is from the declaration of DataRelocation: - // - // "The "o" (displacement) argument is relevant only to split relocations - // on RISC machines. In some CPUs (SPARC), the set-hi and set-lo ins'ns - // can encode more than 32 bits between them. This allows compilers to - // share set-hi instructions between addresses that differ by a small - // offset (e.g., different static variables in the same class). - // On such machines, the "x" argument to set_value on all set-lo - // instructions must be the same as the "x" argument for the - // corresponding set-hi instructions. The "o" arguments for the - // set-hi instructions are ignored, and must not affect the high-half - // immediate constant. The "o" arguments for the set-lo instructions are - // added into the low-half immediate constant, and must not overflow it." - // - // Currently we don't support splitting of relocations, so o must be - // zero: + // Currently we don't support splitting of relocations. assert(o == 0, "tried to split relocations"); if (!verify_only) { if (format() != 1) { nativeMovConstReg_at(addr())->set_data_plain(((intptr_t)x), code()); } else { - assert(type() == relocInfo::oop_type || type() == relocInfo::metadata_type, - "how to encode else?"); - narrowOop no = (type() == relocInfo::oop_type) ? - CompressedOops::encode(cast_to_oop(x)) : - // Type punning compressed klass pointer as narrowOop. - CompressedOops::narrow_oop_cast(CompressedKlassPointers::encode((Klass*)x)); + assert(type() == relocInfo::oop_type, "how to encode else?"); + narrowOop no = CompressedOops::encode(cast_to_oop(x)); nativeMovConstReg_at(addr())->set_narrow_oop(no, code()); } } else { diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index a834fa1af36f2fc617c29b1fafc939ea1295bc85..315ca3f706282f15b0777cae86a4d4583354eb12 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -3216,8 +3216,9 @@ void SharedRuntime::montgomery_multiply(jint *a_ints, jint *b_ints, jint *n_ints // Make very sure we don't use so much space that the stack might // overflow. 512 jints corresponds to an 16384-bit integer and // will use here a total of 8k bytes of stack space. + int divisor = sizeof(unsigned long) * 4; + guarantee(longwords <= 8192 / divisor, "must be"); int total_allocation = longwords * sizeof (unsigned long) * 4; - guarantee(total_allocation <= 8192, "must be"); unsigned long *scratch = (unsigned long *)alloca(total_allocation); // Local scratch arrays @@ -3246,8 +3247,9 @@ void SharedRuntime::montgomery_square(jint *a_ints, jint *n_ints, // Make very sure we don't use so much space that the stack might // overflow. 512 jints corresponds to an 16384-bit integer and // will use here a total of 6k bytes of stack space. + int divisor = sizeof(unsigned long) * 3; + guarantee(longwords <= (8192 / divisor), "must be"); int total_allocation = longwords * sizeof (unsigned long) * 3; - guarantee(total_allocation <= 8192, "must be"); unsigned long *scratch = (unsigned long *)alloca(total_allocation); // Local scratch arrays diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index 0e68a38dbaf9a453e6ff197e21bb5dd3fb74b9bb..901918f7b37f5684079edac3a085d4f36b923e3c 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4656,8 +4656,6 @@ class StubGenerator: public StubCodeGenerator { public: StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { - // replace the standard masm with a special one: - _masm = new MacroAssembler(code); if (all) { generate_all(); } else { diff --git a/src/hotspot/cpu/ppc/vm_version_ext_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ext_ppc.cpp deleted file mode 100644 index 8840a762840338cb176361576afef18648814ae7..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/ppc/vm_version_ext_ppc.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "jvm.h" -#include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" -#include "runtime/vm_version.hpp" -#include "vm_version_ext_ppc.hpp" - -// VM_Version_Ext statics -int VM_Version_Ext::_no_of_threads = 0; -int VM_Version_Ext::_no_of_cores = 0; -int VM_Version_Ext::_no_of_sockets = 0; -bool VM_Version_Ext::_initialized = false; -char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0}; -char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0}; - -// get cpu information. -void VM_Version_Ext::initialize_cpu_information(void) { - // do nothing if cpu info has been initialized - if (_initialized) { - return; - } - - _no_of_cores = os::processor_count(); - _no_of_threads = _no_of_cores; - _no_of_sockets = _no_of_cores; - snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64); - snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", features_string()); - _initialized = true; -} - -int VM_Version_Ext::number_of_threads(void) { - initialize_cpu_information(); - return _no_of_threads; -} - -int VM_Version_Ext::number_of_cores(void) { - initialize_cpu_information(); - return _no_of_cores; -} - -int VM_Version_Ext::number_of_sockets(void) { - initialize_cpu_information(); - return _no_of_sockets; -} - -const char* VM_Version_Ext::cpu_name(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE); - return tmp; -} - -const char* VM_Version_Ext::cpu_description(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE); - return tmp; -} diff --git a/src/hotspot/cpu/ppc/vm_version_ext_ppc.hpp b/src/hotspot/cpu/ppc/vm_version_ext_ppc.hpp deleted file mode 100644 index 36df6f19fd3739523891ce835aff201af87b5f24..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/ppc/vm_version_ext_ppc.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_PPC_VM_VERSION_EXT_PPC_HPP -#define CPU_PPC_VM_VERSION_EXT_PPC_HPP - -#include "runtime/vm_version.hpp" -#include "utilities/macros.hpp" - -#define CPU_INFO "cpu_info" -#define CPU_TYPE "fpu_type" -#define CPU_DESCRIPTION "implementation" -#define CHIP_ID "chip_id" -#define CORE_ID "core_id" - -class VM_Version_Ext : public VM_Version { - private: - - static const size_t CPU_TYPE_DESC_BUF_SIZE = 256; - static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096; - - static int _no_of_threads; - static int _no_of_cores; - static int _no_of_sockets; - static bool _initialized; - static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE]; - static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE]; - - static void initialize_cpu_information(void); - - public: - - static int number_of_threads(void); - static int number_of_cores(void); - static int number_of_sockets(void); - - static const char* cpu_name(void); - static const char* cpu_description(void); -}; - -#endif // CPU_PPC_VM_VERSION_EXT_PPC_HPP diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp index 0b2aa63bceadcd833d1d992d53ceceba323ad683..e8138643a1f1a442ee7ecc0552d19b125c1cd8ed 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -435,7 +435,7 @@ void VM_Version::check_virtualizations() { // system_type=...qemu indicates PowerKVM // e.g. system_type=IBM pSeries (emulated by qemu) char line[500]; - FILE* fp = fopen(info_file, "r"); + FILE* fp = os::fopen(info_file, "r"); if (fp == NULL) { return; } @@ -767,3 +767,18 @@ void VM_Version::allow_all() { void VM_Version::revert() { _features = saved_features; } + +// get cpu information. +void VM_Version::initialize_cpu_information(void) { + // do nothing if cpu info has been initialized + if (_initialized) { + return; + } + + _no_of_cores = os::processor_count(); + _no_of_threads = _no_of_cores; + _no_of_sockets = _no_of_cores; + snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64); + snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", features_string()); + _initialized = true; +} diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.hpp b/src/hotspot/cpu/ppc/vm_version_ppc.hpp index 89352192615c53b082d94802832ce213f35eeb3b..0a9d5ce081045d5e61aa91ded0457283640e85fd 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp @@ -128,6 +128,8 @@ public: // POWER 8: DSCR current value. static uint64_t _dscr_val; + + static void initialize_cpu_information(void); }; #endif // CPU_PPC_VM_VERSION_PPC_HPP diff --git a/src/hotspot/cpu/s390/bytes_s390.hpp b/src/hotspot/cpu/s390/bytes_s390.hpp index f6882f980abface44aed4169f259389bdce1b1e6..9b4d7b0422148e1a71efe21d4a02176bc25d8cd4 100644 --- a/src/hotspot/cpu/s390/bytes_s390.hpp +++ b/src/hotspot/cpu/s390/bytes_s390.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2018 SAP SE. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #ifndef CPU_S390_BYTES_S390_HPP #define CPU_S390_BYTES_S390_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Bytes: AllStatic { public: diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index cb5903886caf59b251228bbe84f815aba63e644c..1d1f163826e243de60c85a19890b5191a1140bee 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -2730,7 +2730,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) { Register obj = op->obj_opr()->as_register(); // May not be an oop. Register hdr = op->hdr_opr()->as_register(); Register lock = op->lock_opr()->as_register(); - if (!UseFastLocking) { + if (UseHeavyMonitors) { __ branch_optimized(Assembler::bcondAlways, *op->stub()->entry()); } else if (op->code() == lir_lock) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); diff --git a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp index aaad1575a82a345e23ff33b528f1e90178b51711..5eac4ae149b34756351005d43fc81f56071e6023 100644 --- a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp @@ -73,8 +73,8 @@ void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_by push_frame(frame_size_in_bytes); } -void C1_MacroAssembler::verified_entry() { - if (C1Breakpoint) z_illtrap(0xC1); +void C1_MacroAssembler::verified_entry(bool breakAtEntry) { + if (breakAtEntry) z_illtrap(0xC1); } void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { diff --git a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp index 83040fb6b7f41a0a88a09459f7a93b5443fada2d..04a6b88052c99cf11b4397061af77f5abd28888a 100644 --- a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,22 +47,44 @@ // Note: // cnt is signed int. Do not rely on high word! // counts # characters, not bytes. -// The result is the number of characters copied before the first incompatible character was found. -// If precise is true, the processing stops exactly at this point. Otherwise, the result may be off -// by a few bytes. The result always indicates the number of copied characters. -// When used as a character index, the returned value points to the first incompatible character. // -// Note: Does not behave exactly like package private StringUTF16 compress java implementation in case of failure: -// - Different number of characters may have been written to dead array (if precise is false). -// - Returns a number --- - // Strings with 4 and 8 characters were fond to occur very frequently. + // Strings with 4 and 8 characters were found to occur very frequently. // Therefore, we handle them right away with minimal overhead. Label skipShortcut, skip4Shortcut, skip8Shortcut; Register Rout = Z_R0; @@ -133,7 +156,8 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R if (VM_Version::has_VectorFacility()) { const int min_vcnt = 32; // Minimum #characters required to use vector instructions. // Otherwise just do nothing in vector mode. - // Must be multiple of 2*(vector register length in chars (8 HW = 128 bits)). + // Must correspond to # vector registers used by implementation, + // and must be a power of 2. const int log_min_vcnt = exact_log2(min_vcnt); Label VectorLoop, VectorDone, VectorBreak; @@ -150,7 +174,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_brz(VectorDone); // not enough data for vector loop z_vzero(Vzero); // all zeroes - z_vgmh(Vmask, 0, 7); // generate 0xff00 mask for all 2-byte elements + z_vgmh(Vmask, mask_ix_l, mask_ix_r); // generate 0xff00/0xff80 mask for all 2-byte elements z_sllg(Z_R0, Rix, log_min_vcnt); // remember #chars that will be processed by vector loop bind(VectorLoop); @@ -162,7 +186,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_vo(Vtmp2, Z_V22, Z_V23); z_vo(Vtmp1, Vtmp1, Vtmp2); z_vn(Vtmp1, Vtmp1, Vmask); - z_vceqhs(Vtmp1, Vtmp1, Vzero); // high half of all chars must be zero for successful compress. + z_vceqhs(Vtmp1, Vtmp1, Vzero); // all bits selected by mask must be zero for successful compress. z_bvnt(VectorBreak); // break vector loop if not all vector elements compare eq -> incompatible character found. // re-process data from current iteration in break handler. @@ -187,7 +211,8 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R { const int min_cnt = 8; // Minimum #characters required to use unrolled loop. // Otherwise just do nothing in unrolled loop. - // Must be multiple of 8. + // Must correspond to # registers used by implementation, + // and must be a power of 2. const int log_min_cnt = exact_log2(min_cnt); Label UnrolledLoop, UnrolledDone, UnrolledBreak; @@ -197,7 +222,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_lr(Rix, Rcnt); z_sr(Rix, Z_R0); } - z_sra(Rix, log_min_cnt); // unrolled loop count + z_sra(Rix, log_min_cnt); // unrolled loop count z_brz(UnrolledDone); bind(UnrolledLoop); @@ -244,6 +269,8 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_sll(Rix, log_min_cnt); // # chars not yet processed in UnrolledLoop (due to break), broken iteration not included. z_sr(Z_R0, Rix); // fix # chars processed OK so far. if (!precise) { + // Because we don't need to be precise, we just return the # of characters which have been written. + // The first illegal character is in the index range [result-min_cnt/2, result+min_cnt/2). z_lgfr(result, Z_R0); z_sllg(Z_R1, Z_R0, 1); // # src bytes already processed. Only lower 32 bits are valid! // Z_R1 contents must be treated as unsigned operand! For huge strings, @@ -274,7 +301,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_brh(ScalarDoit); z_llh(Z_R1, 0, Z_R0, Rsrc); z_bre(Scalar2Char); - z_tmll(Z_R1, 0xff00); + z_tmll(Z_R1, char_mask); z_lghi(result, 0); // cnt == 1, first char invalid, no chars successfully processed z_brnaz(AllDone); z_stc(Z_R1, 0, Z_R0, Rdst); @@ -283,11 +310,11 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R bind(Scalar2Char); z_llh(Z_R0, 2, Z_R0, Rsrc); - z_tmll(Z_R1, 0xff00); + z_tmll(Z_R1, char_mask); z_lghi(result, 0); // cnt == 2, first char invalid, no chars successfully processed z_brnaz(AllDone); z_stc(Z_R1, 0, Z_R0, Rdst); - z_tmll(Z_R0, 0xff00); + z_tmll(Z_R0, char_mask); z_lghi(result, 1); // cnt == 2, second char invalid, one char successfully processed z_brnaz(AllDone); z_stc(Z_R0, 1, Z_R0, Rdst); @@ -299,17 +326,17 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R #endif if (VM_Version::has_DistinctOpnds()) { - z_srk(Rix, Rcnt, Z_R0); // remaining # chars to compress in unrolled loop + z_srk(Rix, Rcnt, Z_R0); // remaining # chars to compress in scalar loop } else { z_lr(Rix, Rcnt); z_sr(Rix, Z_R0); } - z_lgfr(result, Rcnt); // # processed characters (if all runs ok). - z_brz(ScalarDone); // uses CC from Rix calculation + z_lgfr(result, Rcnt); // # processed characters (if all encodes ok). + z_brz(ScalarDone); // anything left to do? (uses CC from Rix calculation) bind(ScalarLoop); z_llh(Z_R1, 0, Z_R0, Rsrc); - z_tmll(Z_R1, 0xff00); + z_tmll(Z_R1, char_mask); z_brnaz(ScalarBreak); z_stc(Z_R1, 0, Z_R0, Rdst); add2reg(Rsrc, 2); @@ -329,7 +356,11 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R bind(AllDone); if (precise) { - BLOCK_COMMENT("} encode_iso_array"); + if (toASCII) { + BLOCK_COMMENT("} encode_ascii_array"); + } else { + BLOCK_COMMENT("} encode_iso_array"); + } } else { BLOCK_COMMENT("} string_compress"); } diff --git a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.hpp b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.hpp index 08112a482d05cd4618d3504e5fc31adce444c402..a6c9865649522d807d91c3255daa05e9c04ad865 100644 --- a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.hpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +39,7 @@ // Early clobber: result. // Boolean precise controls accuracy of result value. unsigned int string_compress(Register result, Register src, Register dst, Register cnt, - Register tmp, bool precise); + Register tmp, bool precise, bool toASCII); // Inflate byte[] to char[]. unsigned int string_inflate_trot(Register src, Register dst, Register cnt, Register tmp); diff --git a/src/hotspot/cpu/s390/frame_s390.cpp b/src/hotspot/cpu/s390/frame_s390.cpp index d29227bb32effd34af833a9dbbd128fee57ac2eb..bfb38ffcdafa31a800ae6397ee7bf4ff19a07b30 100644 --- a/src/hotspot/cpu/s390/frame_s390.cpp +++ b/src/hotspot/cpu/s390/frame_s390.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2019 SAP SE. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -298,9 +298,57 @@ void frame::patch_pc(Thread* thread, address pc) { } bool frame::is_interpreted_frame_valid(JavaThread* thread) const { - // Is there anything to do? assert(is_interpreted_frame(), "Not an interpreted frame"); - return true; + // These are reasonable sanity checks + if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) { + return false; + } + if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { + return false; + } + int min_frame_slots = (z_abi_16_size + z_ijava_state_size) / sizeof(intptr_t); + if (fp() - min_frame_slots < sp()) { + return false; + } + // These are hacks to keep us out of trouble. + // The problem with these is that they mask other problems + if (fp() <= sp()) { // this attempts to deal with unsigned comparison above + return false; + } + + // do some validation of frame elements + + // first the method + + Method* m = *interpreter_frame_method_addr(); + + // validate the method we'd find in this potential sender + if (!Method::is_valid_method(m)) return false; + + // stack frames shouldn't be much larger than max_stack elements + // this test requires the use of unextended_sp which is the sp as seen by + // the current frame, and not sp which is the "raw" pc which could point + // further because of local variables of the callee method inserted after + // method arguments + if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { + return false; + } + + // validate bci/bcx + + address bcp = interpreter_frame_bcp(); + if (m->validate_bci_from_bcp(bcp) < 0) { + return false; + } + + // validate constantPoolCache* + ConstantPoolCache* cp = *interpreter_frame_cache_addr(); + if (MetaspaceObj::is_valid(cp) == false) return false; + + // validate locals + + address locals = (address) *interpreter_frame_locals_addr(); + return thread->is_in_stack_range_incl(locals, (address)fp()); } BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp index 7258630bb0b9d30dfbd4691d675ddd7c27449733..b6e3d9eb2c7b5ab59ed1a4a3a95356a2b8edac76 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp @@ -305,7 +305,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Decorato // calculate address of card __ load_const_optimized(Rbase, (address)ct->card_table()->byte_map_base()); // Card table base. - __ z_srlg(Rcard_addr, Rstore_addr, CardTable::card_shift); // Index into card table. + __ z_srlg(Rcard_addr, Rstore_addr, CardTable::card_shift()); // Index into card table. __ z_algr(Rcard_addr, Rbase); // Explicit calculation needed for cli. Rbase = noreg; // end of lifetime @@ -548,7 +548,7 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* // Calculate address of card corresponding to the updated oop slot. AddressLiteral rs(byte_map_base); - __ z_srlg(addr_card, addr_oop, CardTable::card_shift); + __ z_srlg(addr_card, addr_oop, CardTable::card_shift()); addr_oop = noreg; // dead now __ load_const_optimized(cardtable, rs); // cardtable := __ z_agr(addr_card, cardtable); // addr_card := addr_oop>>card_shift + cardtable diff --git a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp index d3f7bafd33ea3a82a2a0857e6605cecefffb79a9..0124868e46a6fe0b9b49115c146d646b56f59011 100644 --- a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp @@ -70,8 +70,8 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ load_const_optimized(Z_R1, (address)ct->byte_map_base()); // count = (count>>shift) - (addr>>shift) - __ z_srlg(addr, addr, CardTable::card_shift); - __ z_srlg(count, count, CardTable::card_shift); + __ z_srlg(addr, addr, CardTable::card_shift()); + __ z_srlg(count, count, CardTable::card_shift()); // Prefetch first elements of card table for update. if (VM_Version::has_Prefetch()) { @@ -146,7 +146,7 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register st assert_different_registers(store_addr, tmp); - __ z_srlg(store_addr, store_addr, CardTable::card_shift); + __ z_srlg(store_addr, store_addr, CardTable::card_shift()); __ load_absolute_address(tmp, (address)ct->byte_map_base()); __ z_agr(store_addr, tmp); __ z_mvi(0, store_addr, CardTable::dirty_card_val()); diff --git a/src/hotspot/cpu/s390/jniTypes_s390.hpp b/src/hotspot/cpu/s390/jniTypes_s390.hpp index 56f4a05c6d4bfb5bbc0775f80b6e48279f51f898..951e7f5f6d28e8a9de2df73038bbb1465f14bb6a 100644 --- a/src/hotspot/cpu/s390/jniTypes_s390.hpp +++ b/src/hotspot/cpu/s390/jniTypes_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -30,7 +30,7 @@ // jni types to the array of arguments passed into JavaCalls::call. #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" class JNITypes : AllStatic { diff --git a/src/hotspot/cpu/s390/matcher_s390.hpp b/src/hotspot/cpu/s390/matcher_s390.hpp index 09cb819a6414ab29b5f1a8c540767858ed27603a..ac55bd84dff10a5f79b3ae1376c31a37e0351d21 100644 --- a/src/hotspot/cpu/s390/matcher_s390.hpp +++ b/src/hotspot/cpu/s390/matcher_s390.hpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,9 +58,6 @@ // No support for generic vector operands. static const bool supports_generic_vector_operands = false; - // No support for 48 extra htbl entries in aes-gcm intrinsic - static const int htbl_entries = -1; - static constexpr bool isSimpleConstant64(jlong value) { // Probably always true, even if a temp register is required. return true; @@ -153,6 +151,6 @@ } // Implements a variant of EncodeISOArrayNode that encode ASCII only - static const bool supports_encode_ascii_array = false; + static const bool supports_encode_ascii_array = true; #endif // CPU_S390_MATCHER_S390_HPP diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index 60c27c61a514c4cdcb190b661dab10f4d27e4b5c..74ad8ef40d31cfd15d7b7091e290487e5e2e6785 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -1,6 +1,6 @@ // -// Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2017, 2020 SAP SE. All rights reserved. +// Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2017, 2022 SAP SE. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -1544,7 +1544,7 @@ const RegMask* Matcher::predicate_reg_mask(void) { return NULL; } -const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { +const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { return NULL; } @@ -10230,7 +10230,7 @@ instruct string_compress(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tm format %{ "String Compress $src->$dst($len) -> $result" %} ins_encode %{ __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register, - $tmp$$Register, false); + $tmp$$Register, false, false); %} ins_pipe(pipe_class_dummy); %} @@ -10291,10 +10291,24 @@ instruct encode_iso_array(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI t match(Set result (EncodeISOArray src (Binary dst len))); effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too. ins_cost(300); - format %{ "Encode array $src->$dst($len) -> $result" %} + format %{ "Encode iso array $src->$dst($len) -> $result" %} ins_encode %{ __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register, - $tmp$$Register, true); + $tmp$$Register, true, false); + %} + ins_pipe(pipe_class_dummy); +%} + +// encode char[] to byte[] in ASCII +instruct encode_ascii_array(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tmp, flagsReg cr) %{ + predicate(((EncodeISOArrayNode*)n)->is_ascii()); + match(Set result (EncodeISOArray src (Binary dst len))); + effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too. + ins_cost(300); + format %{ "Encode ascii array $src->$dst($len) -> $result" %} + ins_encode %{ + __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register, + $tmp$$Register, true, true); %} ins_pipe(pipe_class_dummy); %} diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 2b310f6e44f75921f50ac022201587ca855096e5..107ec979ffd22df2e82c7b97489128308b639b46 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -3219,8 +3219,9 @@ void SharedRuntime::montgomery_multiply(jint *a_ints, jint *b_ints, jint *n_ints // Make very sure we don't use so much space that the stack might // overflow. 512 jints corresponds to an 16384-bit integer and // will use here a total of 8k bytes of stack space. + int divisor = sizeof(unsigned long) * 4; + guarantee(longwords <= 8192 / divisor, "must be"); int total_allocation = longwords * sizeof (unsigned long) * 4; - guarantee(total_allocation <= 8192, "must be"); unsigned long *scratch = (unsigned long *)alloca(total_allocation); // Local scratch arrays @@ -3249,8 +3250,9 @@ void SharedRuntime::montgomery_square(jint *a_ints, jint *n_ints, // Make very sure we don't use so much space that the stack might // overflow. 512 jints corresponds to an 16384-bit integer and // will use here a total of 6k bytes of stack space. + int divisor = sizeof(unsigned long) * 3; + guarantee(longwords <= (8192 / divisor), "must be"); int total_allocation = longwords * sizeof (unsigned long) * 3; - guarantee(total_allocation <= 8192, "must be"); unsigned long *scratch = (unsigned long *)alloca(total_allocation); // Local scratch arrays diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 218b0b378b91041d3b4288d153949b0b96da0874..102200fc08f3537c894a88e91b20b0a2d511e9b3 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2019 SAP SE. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2404,9 +2404,6 @@ class StubGenerator: public StubCodeGenerator { public: StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { - // Replace the standard masm with a special one: - _masm = new MacroAssembler(code); - _stub_count = !all ? 0x100 : 0x200; if (all) { generate_all(); diff --git a/src/hotspot/cpu/s390/vm_version_ext_s390.cpp b/src/hotspot/cpu/s390/vm_version_ext_s390.cpp deleted file mode 100644 index 2be9d1c5ede1937922dab2152a0f441b05e04d0d..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/s390/vm_version_ext_s390.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "jvm.h" -#include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" -#include "vm_version_ext_s390.hpp" - -// VM_Version_Ext statics -int VM_Version_Ext::_no_of_threads = 0; -int VM_Version_Ext::_no_of_cores = 0; -int VM_Version_Ext::_no_of_sockets = 0; -bool VM_Version_Ext::_initialized = false; -char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0}; -char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0}; - -// get cpu information. -void VM_Version_Ext::initialize_cpu_information(void) { - // do nothing if cpu info has been initialized - if (_initialized) { - return; - } - - _no_of_cores = os::processor_count(); - _no_of_threads = _no_of_cores; - _no_of_sockets = _no_of_cores; - snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "s390 %s", VM_Version::get_model_string()); - snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "s390 %s", features_string()); - _initialized = true; -} - -int VM_Version_Ext::number_of_threads(void) { - initialize_cpu_information(); - return _no_of_threads; -} - -int VM_Version_Ext::number_of_cores(void) { - initialize_cpu_information(); - return _no_of_cores; -} - -int VM_Version_Ext::number_of_sockets(void) { - initialize_cpu_information(); - return _no_of_sockets; -} - -const char* VM_Version_Ext::cpu_name(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE); - return tmp; -} - -const char* VM_Version_Ext::cpu_description(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE); - return tmp; -} diff --git a/src/hotspot/cpu/s390/vm_version_ext_s390.hpp b/src/hotspot/cpu/s390/vm_version_ext_s390.hpp deleted file mode 100644 index 8e6bc62e52df835cf8c40c8100be60b5e11f95cb..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/s390/vm_version_ext_s390.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_S390_VM_VERSION_EXT_S390_HPP -#define CPU_S390_VM_VERSION_EXT_S390_HPP - -#include "runtime/vm_version.hpp" -#include "utilities/macros.hpp" - -#define CPU_INFO "cpu_info" -#define CPU_TYPE "fpu_type" -#define CPU_DESCRIPTION "implementation" -#define CHIP_ID "chip_id" -#define CORE_ID "core_id" - -class VM_Version_Ext : public VM_Version { - private: - - static const size_t CPU_TYPE_DESC_BUF_SIZE = 256; - static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096; - - static int _no_of_threads; - static int _no_of_cores; - static int _no_of_sockets; - static bool _initialized; - static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE]; - static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE]; - - static void initialize_cpu_information(void); - - public: - - static int number_of_threads(void); - static int number_of_cores(void); - static int number_of_sockets(void); - - static const char* cpu_name(void); - static const char* cpu_description(void); -}; - -#endif // CPU_S390_VM_VERSION_EXT_S390_HPP diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp index d7b68f907c7e370aeb5c405a7c01fc4548f1b069..6c077943d3a5a8b128010e0dc42f2497b21297bb 100644 --- a/src/hotspot/cpu/s390/vm_version_s390.cpp +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp @@ -1490,3 +1490,19 @@ unsigned long VM_Version::z_SIGSEGV() { ); return ZeroBuffer; } + + +// get cpu information. +void VM_Version::initialize_cpu_information(void) { + // do nothing if cpu info has been initialized + if (_initialized) { + return; + } + + _no_of_cores = os::processor_count(); + _no_of_threads = _no_of_cores; + _no_of_sockets = _no_of_cores; + snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "s390 %s", VM_Version::get_model_string()); + snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "s390 %s", features_string()); + _initialized = true; +} diff --git a/src/hotspot/cpu/s390/vm_version_s390.hpp b/src/hotspot/cpu/s390/vm_version_s390.hpp index 176aa7549c0c807cd73d83d9233d160e536d6522..a2fb7dd8e9a3fafe578dd8cd9468ff90436b4b07 100644 --- a/src/hotspot/cpu/s390/vm_version_s390.hpp +++ b/src/hotspot/cpu/s390/vm_version_s390.hpp @@ -533,6 +533,8 @@ class VM_Version: public Abstract_VM_Version { // Sometimes helpful for debugging. static unsigned long z_SIGILL(); static unsigned long z_SIGSEGV(); + + static void initialize_cpu_information(void); }; #endif // CPU_S390_VM_VERSION_S390_HPP diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 4c23b12d0b5becef7bfc4dce6d23a5b9e09b69f8..c645e5461de5117260b48807e81b8b493a00f3d0 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -186,7 +186,7 @@ Address::Address(address loc, RelocationHolder spec) { // Address. An index of 4 (rsp) corresponds to having no index, so convert // that to noreg for the Address constructor. Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) { - RelocationHolder rspec; + RelocationHolder rspec = RelocationHolder::none; if (disp_reloc != relocInfo::none) { rspec = Relocation::spec_simple(disp_reloc); } @@ -2473,6 +2473,16 @@ void Assembler::movddup(XMMRegister dst, XMMRegister src) { emit_int16(0x12, 0xC0 | encode); } +void Assembler::vmovddup(XMMRegister dst, Address src, int vector_len) { + assert(VM_Version::supports_avx(), ""); + InstructionMark im(this); + InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_rex_vex_w_reverted(); + simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + emit_int8(0x12); + emit_operand(dst, src); +} + void Assembler::kmovbl(KRegister dst, KRegister src) { assert(VM_Version::supports_avx512dq(), ""); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false); @@ -2788,6 +2798,15 @@ void Assembler::kshiftlbl(KRegister dst, KRegister src, int imm8) { emit_int8(imm8); } +void Assembler::kshiftlql(KRegister dst, KRegister src, int imm8) { + assert(VM_Version::supports_avx512bw(), ""); + InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), 0 , src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); + emit_int16(0x33, (0xC0 | encode)); + emit_int8(imm8); +} + + void Assembler::kshiftrbl(KRegister dst, KRegister src, int imm8) { assert(VM_Version::supports_avx512dq(), ""); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false); @@ -2819,6 +2838,13 @@ void Assembler::kshiftrql(KRegister dst, KRegister src, int imm8) { emit_int8(imm8); } +void Assembler::kunpckdql(KRegister dst, KRegister src1, KRegister src2) { + assert(VM_Version::supports_avx512bw(), ""); + InstructionAttr attributes(AVX_256bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes); + emit_int16(0x4B, (0xC0 | encode)); +} + void Assembler::movb(Address dst, int imm8) { InstructionMark im(this); prefix(dst); @@ -4813,6 +4839,14 @@ void Assembler::vpopcntd(XMMRegister dst, XMMRegister src, int vector_len) { emit_int16(0x55, (0xC0 | encode)); } +void Assembler::vpopcntq(XMMRegister dst, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512_vpopcntdq(), "must support vpopcntdq feature"); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x55, (0xC0 | encode)); +} + void Assembler::popf() { emit_int8((unsigned char)0x9D); } @@ -7578,6 +7612,9 @@ void Assembler::pxor(XMMRegister dst, XMMRegister src) { void Assembler::vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(UseAVX > 0, "requires some form of AVX"); + assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : + vector_len == AVX_256bit ? VM_Version::supports_avx2() : + vector_len == AVX_512bit ? VM_Version::supports_evex() : 0, ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int16((unsigned char)0xEF, (0xC0 | encode)); @@ -7585,6 +7622,9 @@ void Assembler::vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vec void Assembler::vpxor(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { assert(UseAVX > 0, "requires some form of AVX"); + assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : + vector_len == AVX_256bit ? VM_Version::supports_avx2() : + vector_len == AVX_512bit ? VM_Version::supports_evex() : 0, ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit); @@ -9261,7 +9301,7 @@ void Assembler::evpsraq(XMMRegister dst, KRegister mask, XMMRegister src, int sh attributes.reset_is_clear_context(); } int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); - emit_int24(0x73, (0xC0 | encode), shift & 0xFF); + emit_int24(0x72, (0xC0 | encode), shift & 0xFF); } void Assembler::evpsllw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) { @@ -9709,6 +9749,68 @@ void Assembler::evpmaxsq(XMMRegister dst, KRegister mask, XMMRegister nds, Addre emit_operand(dst, src); } +void Assembler::evpternlogd(XMMRegister dst, int imm8, KRegister mask, XMMRegister src2, XMMRegister src3, bool merge, int vector_len) { + assert(VM_Version::supports_evex(), "requires EVEX support"); + assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support"); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + attributes.set_embedded_opmask_register_specifier(mask); + if (merge) { + attributes.reset_is_clear_context(); + } + int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src3->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); + emit_int24(0x25, (unsigned char)(0xC0 | encode), imm8); +} + +void Assembler::evpternlogd(XMMRegister dst, int imm8, KRegister mask, XMMRegister src2, Address src3, bool merge, int vector_len) { + assert(VM_Version::supports_evex(), "requires EVEX support"); + assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support"); + assert(dst != xnoreg, "sanity"); + InstructionMark im(this); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + attributes.set_embedded_opmask_register_specifier(mask); + attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit); + if (merge) { + attributes.reset_is_clear_context(); + } + vex_prefix(src3, src2->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); + emit_int8(0x25); + emit_operand(dst, src3); + emit_int8(imm8); +} + +void Assembler::evpternlogq(XMMRegister dst, int imm8, KRegister mask, XMMRegister src2, XMMRegister src3, bool merge, int vector_len) { + assert(VM_Version::supports_evex(), "requires EVEX support"); + assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support"); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + attributes.set_embedded_opmask_register_specifier(mask); + if (merge) { + attributes.reset_is_clear_context(); + } + int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src3->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); + emit_int24(0x25, (unsigned char)(0xC0 | encode), imm8); +} + +void Assembler::evpternlogq(XMMRegister dst, int imm8, KRegister mask, XMMRegister src2, Address src3, bool merge, int vector_len) { + assert(VM_Version::supports_evex(), "requires EVEX support"); + assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support"); + assert(dst != xnoreg, "sanity"); + InstructionMark im(this); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + attributes.set_embedded_opmask_register_specifier(mask); + attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit); + if (merge) { + attributes.reset_is_clear_context(); + } + vex_prefix(src3, src2->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); + emit_int8(0x25); + emit_operand(dst, src3); + emit_int8(imm8); +} + // duplicate 4-byte integer data from src into programmed locations in dest : requires AVX512VL void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len) { assert(UseAVX >= 2, ""); @@ -11101,6 +11203,10 @@ void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, Address emit_int8((unsigned char)comparison); } +// Register is a class, but it would be assigned numerical value. +// "0" is assigned for xmm0. Thus we need to ignore -Wnonnull. +PRAGMA_DIAG_PUSH +PRAGMA_NONNULL_IGNORED void Assembler::evprord(XMMRegister dst, KRegister mask, XMMRegister src, int shift, bool merge, int vector_len) { assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); @@ -11124,6 +11230,7 @@ void Assembler::evprorq(XMMRegister dst, KRegister mask, XMMRegister src, int sh int encode = vex_prefix_and_encode(xmm0->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int24(0x72, (0xC0 | encode), shift & 0xFF); } +PRAGMA_DIAG_POP void Assembler::evprorvd(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) { assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), ""); @@ -11292,6 +11399,20 @@ void Assembler::bzhiq(Register dst, Register src1, Register src2) { emit_int16((unsigned char)0xF5, (0xC0 | encode)); } +void Assembler::pext(Register dst, Register src1, Register src2) { + assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes); + emit_int16((unsigned char)0xF5, (0xC0 | encode)); +} + +void Assembler::pdep(Register dst, Register src1, Register src2) { + assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes); + emit_int16((unsigned char)0xF5, (0xC0 | encode)); +} + void Assembler::shlxl(Register dst, Register src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true); diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index 5a6e9129fd8b80eade69b91f56a6d89a32c7b584..2cfb1e293609764a18ff0321fd1fff6ba997cf2c 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -377,7 +377,7 @@ class AddressLiteral { private: address target() { return _target; } - bool is_lval() { return _is_lval; } + bool is_lval() const { return _is_lval; } relocInfo::relocType reloc() const { return _rspec.type(); } const RelocationHolder& rspec() const { return _rspec; } @@ -1467,6 +1467,7 @@ private: void movb(Register dst, Address src); void movddup(XMMRegister dst, XMMRegister src); + void vmovddup(XMMRegister dst, Address src, int vector_len); void kandbl(KRegister dst, KRegister src1, KRegister src2); void kandwl(KRegister dst, KRegister src1, KRegister src2); @@ -1510,12 +1511,15 @@ private: void kxnorbl(KRegister dst, KRegister src1, KRegister src2); void kshiftlbl(KRegister dst, KRegister src, int imm8); + void kshiftlql(KRegister dst, KRegister src, int imm8); void kshiftrbl(KRegister dst, KRegister src, int imm8); void kshiftrwl(KRegister dst, KRegister src, int imm8); void kshiftrdl(KRegister dst, KRegister src, int imm8); void kshiftrql(KRegister dst, KRegister src, int imm8); void ktestq(KRegister src1, KRegister src2); void ktestd(KRegister src1, KRegister src2); + void kunpckdql(KRegister dst, KRegister src1, KRegister src2); + void ktestql(KRegister dst, KRegister src); void ktestdl(KRegister dst, KRegister src); @@ -1866,6 +1870,7 @@ private: void popcntl(Register dst, Register src); void vpopcntd(XMMRegister dst, XMMRegister src, int vector_len); + void vpopcntq(XMMRegister dst, XMMRegister src, int vector_len); #ifdef _LP64 void popcntq(Register dst, Address src); @@ -2184,6 +2189,9 @@ private: void shrxq(Register dst, Register src1, Register src2); void bzhiq(Register dst, Register src1, Register src2); + void pdep(Register dst, Register src1, Register src2); + void pext(Register dst, Register src1, Register src2); + //====================VECTOR ARITHMETIC===================================== // Add Packed Floating-Point Values @@ -2407,6 +2415,12 @@ private: void evprorvd(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len); void evprorvq(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len); + void evpternlogd(XMMRegister dst, int imm8, KRegister mask, XMMRegister src2, XMMRegister src3, bool merge, int vector_len); + void evpternlogd(XMMRegister dst, int imm8, KRegister mask, XMMRegister src2, Address src3, bool merge, int vector_len); + void evpternlogq(XMMRegister dst, int imm8, KRegister mask, XMMRegister src2, XMMRegister src3, bool merge, int vector_len); + void evpternlogq(XMMRegister dst, int imm8, KRegister mask, XMMRegister src2, Address src3, bool merge, int vector_len); + + // Sub packed integers void psubb(XMMRegister dst, XMMRegister src); void psubw(XMMRegister dst, XMMRegister src); diff --git a/src/hotspot/cpu/x86/bytes_x86.hpp b/src/hotspot/cpu/x86/bytes_x86.hpp index 4ce19a473b49a1b054b79b1addb72084464fa7ce..cb5987d2c8262ba3f77d5d4eb216e416ad027576 100644 --- a/src/hotspot/cpu/x86/bytes_x86.hpp +++ b/src/hotspot/cpu/x86/bytes_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef CPU_X86_BYTES_X86_HPP #define CPU_X86_BYTES_X86_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/align.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index 07f2762fa16f1f3417eb8279ceaef6643923e34f..eaeeae235f0d2be6ff8f2adface509258fa9e777 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -461,7 +461,11 @@ int LIR_Assembler::emit_unwind_handler() { if (method()->is_synchronized()) { monitor_address(0, FrameMap::rax_opr); stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); - __ unlock_object(rdi, rsi, rax, *stub->entry()); + if (UseHeavyMonitors) { + __ jmp(*stub->entry()); + } else { + __ unlock_object(rdi, rsi, rax, *stub->entry()); + } __ bind(*stub->continuation()); } @@ -3498,7 +3502,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) { Register obj = op->obj_opr()->as_register(); // may not be an oop Register hdr = op->hdr_opr()->as_register(); Register lock = op->lock_opr()->as_register(); - if (!UseFastLocking) { + if (UseHeavyMonitors) { __ jmp(*op->stub()->entry()); } else if (op->code() == lir_lock) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); diff --git a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp index 0b62108c79fa266265fd50aff85b9b57798440b5..819c36957b35a0f48d43c291902583c5adc09f07 100644 --- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp @@ -192,8 +192,32 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o LIR_Address* addr; if (index_opr->is_constant()) { int elem_size = type2aelembytes(type); - addr = new LIR_Address(array_opr, - offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); +#ifdef _LP64 + jint index = index_opr->as_jint(); + jlong disp = offset_in_bytes + (jlong)(index) * elem_size; + if (disp > max_jint) { + // Displacement overflow. Cannot directly use instruction with 32-bit displacement for 64-bit addresses. + // Convert array index to long to do array offset computation with 64-bit values. + index_opr = new_register(T_LONG); + __ move(LIR_OprFact::longConst(index), index_opr); + addr = new LIR_Address(array_opr, index_opr, LIR_Address::scale(type), offset_in_bytes, type); + } else { + addr = new LIR_Address(array_opr, (intx)disp, type); + } +#else + // A displacement overflow can also occur for x86 but that is not a problem due to the 32-bit address range! + // Let's assume an array 'a' and an access with displacement 'disp'. When disp overflows, then "a + disp" will + // always be negative (i.e. underflows the 32-bit address range): + // Let N = 2^32: a + signed_overflow(disp) = a + disp - N. + // "a + disp" is always smaller than N. If an index was chosen which would point to an address beyond N, then + // range checks would catch that and throw an exception. Thus, a + disp < 0 holds which means that it always + // underflows the 32-bit address range: + // unsigned_underflow(a + signed_overflow(disp)) = unsigned_underflow(a + disp - N) + // = (a + disp - N) + N = a + disp + // This shows that we still end up at the correct address with a displacement overflow due to the 32-bit address + // range limitation. This overflow only needs to be handled if addresses can be larger as on 64-bit platforms. + addr = new LIR_Address(array_opr, offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); +#endif // _LP64 } else { #ifdef _LP64 if (index_opr->type() == T_INT) { diff --git a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp index 80d0ca4dd181d338720e5a3d9b8b80a93527e580..26a1f36c94d02a8b4f3464b7895bdf6cddaf919b 100644 --- a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp @@ -331,18 +331,18 @@ void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) { } -void C1_MacroAssembler::verified_entry() { - if (C1Breakpoint || VerifyFPU) { +void C1_MacroAssembler::verified_entry(bool breakAtEntry) { + if (breakAtEntry || VerifyFPU) { // Verified Entry first instruction should be 5 bytes long for correct // patching by patch_verified_entry(). // - // C1Breakpoint and VerifyFPU have one byte first instruction. + // Breakpoint and VerifyFPU have one byte first instruction. // Also first instruction will be one byte "push(rbp)" if stack banging // code is not generated (see build_frame() above). // For all these cases generate long instruction first. fat_nop(); } - if (C1Breakpoint)int3(); + if (breakAtEntry) int3(); // build frame IA32_ONLY( verify_FPU(0, "method_entry"); ) } diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 4aec9668a148a6a398d533b632345500ef22350e..65166197616ca89ef07512a0b6a397fd745157d4 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -485,6 +485,7 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp #if INCLUDE_RTM_OPT if (UseRTMForStackLocks && use_rtm) { + assert(!UseHeavyMonitors, "+UseHeavyMonitors and +UseRTMForStackLocks are mutually exclusive"); rtm_stack_locking(objReg, tmpReg, scrReg, cx2Reg, stack_rtm_counters, method_data, profile_rtm, DONE_LABEL, IsInflated); @@ -495,20 +496,25 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp testptr(tmpReg, markWord::monitor_value); // inflated vs stack-locked|neutral jccb(Assembler::notZero, IsInflated); - // Attempt stack-locking ... - orptr (tmpReg, markWord::unlocked_value); - movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS - lock(); - cmpxchgptr(boxReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Updates tmpReg - jcc(Assembler::equal, DONE_LABEL); // Success - - // Recursive locking. - // The object is stack-locked: markword contains stack pointer to BasicLock. - // Locked by current thread if difference with current SP is less than one page. - subptr(tmpReg, rsp); - // Next instruction set ZFlag == 1 (Success) if difference is less then one page. - andptr(tmpReg, (int32_t) (NOT_LP64(0xFFFFF003) LP64_ONLY(7 - os::vm_page_size())) ); - movptr(Address(boxReg, 0), tmpReg); + if (!UseHeavyMonitors) { + // Attempt stack-locking ... + orptr (tmpReg, markWord::unlocked_value); + movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS + lock(); + cmpxchgptr(boxReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Updates tmpReg + jcc(Assembler::equal, DONE_LABEL); // Success + + // Recursive locking. + // The object is stack-locked: markword contains stack pointer to BasicLock. + // Locked by current thread if difference with current SP is less than one page. + subptr(tmpReg, rsp); + // Next instruction set ZFlag == 1 (Success) if difference is less then one page. + andptr(tmpReg, (int32_t) (NOT_LP64(0xFFFFF003) LP64_ONLY(7 - os::vm_page_size())) ); + movptr(Address(boxReg, 0), tmpReg); + } else { + // Clear ZF so that we take the slow path at the DONE label. objReg is known to be not 0. + testptr(objReg, objReg); + } jmp(DONE_LABEL); bind(IsInflated); @@ -638,6 +644,7 @@ void C2_MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register t #if INCLUDE_RTM_OPT if (UseRTMForStackLocks && use_rtm) { + assert(!UseHeavyMonitors, "+UseHeavyMonitors and +UseRTMForStackLocks are mutually exclusive"); Label L_regular_unlock; movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // fetch markword andptr(tmpReg, markWord::lock_mask_in_place); // look at 2 lock bits @@ -649,11 +656,15 @@ void C2_MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register t } #endif - cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD); // Examine the displaced header - jcc (Assembler::zero, DONE_LABEL); // 0 indicates recursive stack-lock + if (!UseHeavyMonitors) { + cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD); // Examine the displaced header + jcc (Assembler::zero, DONE_LABEL); // 0 indicates recursive stack-lock + } movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Examine the object's markword - testptr(tmpReg, markWord::monitor_value); // Inflated? - jccb (Assembler::zero, Stacked); + if (!UseHeavyMonitors) { + testptr(tmpReg, markWord::monitor_value); // Inflated? + jccb (Assembler::zero, Stacked); + } // It's inflated. #if INCLUDE_RTM_OPT @@ -795,11 +806,12 @@ void C2_MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register t testl (boxReg, 0); // set ICC.ZF=1 to indicate success jmpb (DONE_LABEL); - bind (Stacked); - movptr(tmpReg, Address (boxReg, 0)); // re-fetch - lock(); - cmpxchgptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Uses RAX which is box - + if (!UseHeavyMonitors) { + bind (Stacked); + movptr(tmpReg, Address (boxReg, 0)); // re-fetch + lock(); + cmpxchgptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Uses RAX which is box + } #endif bind(DONE_LABEL); } @@ -2180,84 +2192,6 @@ void C2_MacroAssembler::evpcmp(BasicType typ, KRegister kdmask, KRegister ksmask } } -void C2_MacroAssembler::vpcmpu(BasicType typ, XMMRegister dst, XMMRegister src1, XMMRegister src2, ComparisonPredicate comparison, - int vlen_in_bytes, XMMRegister vtmp1, XMMRegister vtmp2, Register scratch) { - int vlen_enc = vector_length_encoding(vlen_in_bytes*2); - switch (typ) { - case T_BYTE: - vpmovzxbw(vtmp1, src1, vlen_enc); - vpmovzxbw(vtmp2, src2, vlen_enc); - vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::W, vlen_enc, scratch); - vpacksswb(dst, dst, dst, vlen_enc); - break; - case T_SHORT: - vpmovzxwd(vtmp1, src1, vlen_enc); - vpmovzxwd(vtmp2, src2, vlen_enc); - vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::D, vlen_enc, scratch); - vpackssdw(dst, dst, dst, vlen_enc); - break; - case T_INT: - vpmovzxdq(vtmp1, src1, vlen_enc); - vpmovzxdq(vtmp2, src2, vlen_enc); - vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::Q, vlen_enc, scratch); - vpermilps(dst, dst, 8, vlen_enc); - break; - default: - assert(false, "Should not reach here"); - } - if (vlen_in_bytes == 16) { - vpermpd(dst, dst, 0x8, vlen_enc); - } -} - -void C2_MacroAssembler::vpcmpu32(BasicType typ, XMMRegister dst, XMMRegister src1, XMMRegister src2, ComparisonPredicate comparison, int vlen_in_bytes, - XMMRegister vtmp1, XMMRegister vtmp2, XMMRegister vtmp3, Register scratch) { - int vlen_enc = vector_length_encoding(vlen_in_bytes); - switch (typ) { - case T_BYTE: - vpmovzxbw(vtmp1, src1, vlen_enc); - vpmovzxbw(vtmp2, src2, vlen_enc); - vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::W, vlen_enc, scratch); - vextracti128(vtmp1, src1, 1); - vextracti128(vtmp2, src2, 1); - vpmovzxbw(vtmp1, vtmp1, vlen_enc); - vpmovzxbw(vtmp2, vtmp2, vlen_enc); - vpcmpCCW(vtmp3, vtmp1, vtmp2, comparison, Assembler::W, vlen_enc, scratch); - vpacksswb(dst, dst, vtmp3, vlen_enc); - vpermpd(dst, dst, 0xd8, vlen_enc); - break; - case T_SHORT: - vpmovzxwd(vtmp1, src1, vlen_enc); - vpmovzxwd(vtmp2, src2, vlen_enc); - vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::D, vlen_enc, scratch); - vextracti128(vtmp1, src1, 1); - vextracti128(vtmp2, src2, 1); - vpmovzxwd(vtmp1, vtmp1, vlen_enc); - vpmovzxwd(vtmp2, vtmp2, vlen_enc); - vpcmpCCW(vtmp3, vtmp1, vtmp2, comparison, Assembler::D, vlen_enc, scratch); - vpackssdw(dst, dst, vtmp3, vlen_enc); - vpermpd(dst, dst, 0xd8, vlen_enc); - break; - case T_INT: - vpmovzxdq(vtmp1, src1, vlen_enc); - vpmovzxdq(vtmp2, src2, vlen_enc); - vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::Q, vlen_enc, scratch); - vpshufd(dst, dst, 8, vlen_enc); - vpermq(dst, dst, 8, vlen_enc); - vextracti128(vtmp1, src1, 1); - vextracti128(vtmp2, src2, 1); - vpmovzxdq(vtmp1, vtmp1, vlen_enc); - vpmovzxdq(vtmp2, vtmp2, vlen_enc); - vpcmpCCW(vtmp3, vtmp1, vtmp2, comparison, Assembler::Q, vlen_enc, scratch); - vpshufd(vtmp3, vtmp3, 8, vlen_enc); - vpermq(vtmp3, vtmp3, 0x80, vlen_enc); - vpblendd(dst, dst, vtmp3, 0xf0, vlen_enc); - break; - default: - assert(false, "Should not reach here"); - } -} - void C2_MacroAssembler::evpblend(BasicType typ, XMMRegister dst, KRegister kmask, XMMRegister src1, XMMRegister src2, bool merge, int vector_len) { switch(typ) { case T_BYTE: @@ -4140,7 +4074,66 @@ void C2_MacroAssembler::vector_castF2I_evex(XMMRegister dst, XMMRegister src, XM bind(done); } +void C2_MacroAssembler::evpternlog(XMMRegister dst, int func, KRegister mask, XMMRegister src2, XMMRegister src3, + bool merge, BasicType bt, int vlen_enc) { + if (bt == T_INT) { + evpternlogd(dst, func, mask, src2, src3, merge, vlen_enc); + } else { + assert(bt == T_LONG, ""); + evpternlogq(dst, func, mask, src2, src3, merge, vlen_enc); + } +} + +void C2_MacroAssembler::evpternlog(XMMRegister dst, int func, KRegister mask, XMMRegister src2, Address src3, + bool merge, BasicType bt, int vlen_enc) { + if (bt == T_INT) { + evpternlogd(dst, func, mask, src2, src3, merge, vlen_enc); + } else { + assert(bt == T_LONG, ""); + evpternlogq(dst, func, mask, src2, src3, merge, vlen_enc); + } +} + #ifdef _LP64 +void C2_MacroAssembler::vector_long_to_maskvec(XMMRegister dst, Register src, Register rtmp1, + Register rtmp2, XMMRegister xtmp, int mask_len, + int vec_enc) { + int index = 0; + int vindex = 0; + mov64(rtmp1, 0x0101010101010101L); + pdep(rtmp1, src, rtmp1); + if (mask_len > 8) { + movq(rtmp2, src); + vpxor(xtmp, xtmp, xtmp, vec_enc); + movq(xtmp, rtmp1); + } + movq(dst, rtmp1); + + mask_len -= 8; + while (mask_len > 0) { + assert ((mask_len & 0x7) == 0, "mask must be multiple of 8"); + index++; + if ((index % 2) == 0) { + pxor(xtmp, xtmp); + } + mov64(rtmp1, 0x0101010101010101L); + shrq(rtmp2, 8); + pdep(rtmp1, rtmp2, rtmp1); + pinsrq(xtmp, rtmp1, index % 2); + vindex = index / 2; + if (vindex) { + // Write entire 16 byte vector when both 64 bit + // lanes are update to save redundant instructions. + if (index % 2) { + vinsertf128(dst, dst, xtmp, vindex); + } + } else { + vmovdqu(dst, xtmp); + } + mask_len -= 8; + } +} + void C2_MacroAssembler::vector_mask_operation_helper(int opc, Register dst, Register tmp, int masklen) { switch(opc) { case Op_VectorMaskTrueCount: @@ -4261,3 +4254,30 @@ void C2_MacroAssembler::vector_mask_operation(int opc, Register dst, XMMRegister vector_mask_operation_helper(opc, dst, tmp, masklen); } #endif + +void C2_MacroAssembler::vector_maskall_operation(KRegister dst, Register src, int mask_len) { + if (VM_Version::supports_avx512bw()) { + if (mask_len > 32) { + kmovql(dst, src); + } else { + kmovdl(dst, src); + if (mask_len != 32) { + kshiftrdl(dst, dst, 32 - mask_len); + } + } + } else { + assert(mask_len <= 16, ""); + kmovwl(dst, src); + if (mask_len != 16) { + kshiftrwl(dst, dst, 16 - mask_len); + } + } +} + +#ifndef _LP64 +void C2_MacroAssembler::vector_maskall_operation32(KRegister dst, Register src, KRegister tmp, int mask_len) { + assert(VM_Version::supports_avx512bw(), ""); + kmovdl(tmp, src); + kunpckdql(dst, tmp, tmp); +} +#endif diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp index e6588e0485d09792b982c43e82d769ea16f551c6..b97c1ed607d4b19bdfcfaa44f19a8291ef8ce1b6 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,12 +146,6 @@ public: void load_iota_indices(XMMRegister dst, Register scratch, int vlen_in_bytes); - // vector compare - void vpcmpu(BasicType typ, XMMRegister dst, XMMRegister src1, XMMRegister src2, ComparisonPredicate comparison, int vlen_in_bytes, - XMMRegister vtmp1, XMMRegister vtmp2, Register scratch); - void vpcmpu32(BasicType typ, XMMRegister dst, XMMRegister src1, XMMRegister src2, ComparisonPredicate comparison, int vlen_in_bytes, - XMMRegister vtmp1, XMMRegister vtmp2, XMMRegister vtmp3, Register scratch); - // Reductions for vectors of bytes, shorts, ints, longs, floats, and doubles. // dst = src1 reduce(op, src2) using vtmp as temps @@ -230,7 +224,16 @@ public: void vector_mask_operation(int opc, Register dst, XMMRegister mask, XMMRegister xtmp, Register tmp, int masklen, BasicType bt, int vec_enc); + void vector_long_to_maskvec(XMMRegister dst, Register src, Register rtmp1, + Register rtmp2, XMMRegister xtmp, int mask_len, int vec_enc); +#endif + + void vector_maskall_operation(KRegister dst, Register src, int mask_len); + +#ifndef _LP64 + void vector_maskall_operation32(KRegister dst, Register src, KRegister ktmp, int mask_len); #endif + void string_indexof_char(Register str1, Register cnt1, Register ch, Register result, XMMRegister vec1, XMMRegister vec2, XMMRegister vec3, Register tmp); @@ -302,4 +305,11 @@ public: void vector_castD2L_evex(XMMRegister dst, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2, KRegister ktmp1, KRegister ktmp2, AddressLiteral double_sign_flip, Register scratch, int vec_enc); + + void evpternlog(XMMRegister dst, int func, KRegister mask, XMMRegister src2, XMMRegister src3, + bool merge, BasicType bt, int vlen_enc); + + void evpternlog(XMMRegister dst, int func, KRegister mask, XMMRegister src2, Address src3, + bool merge, BasicType bt, int vlen_enc); + #endif // CPU_X86_C2_MACROASSEMBLER_X86_HPP diff --git a/src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp b/src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp index f3f66f3d7bc15f6d00aee1ef61a3a92df4538049..415d8a99933e2159f9ba2c9aa576a284c6595e9f 100644 --- a/src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp +++ b/src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef CPU_X86_INTELJCCERRATUM_X86_HPP #define CPU_X86_INTELJCCERRATUM_X86_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class Block; diff --git a/src/hotspot/cpu/x86/copy_x86.hpp b/src/hotspot/cpu/x86/copy_x86.hpp index dc150a568afc76bfa0c313cb33745b3d2f18f318..74228b57f6c58949af2c1baa041cb899bcfb3fd5 100644 --- a/src/hotspot/cpu/x86/copy_x86.hpp +++ b/src/hotspot/cpu/x86/copy_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,4 +59,293 @@ static void pd_zero_to_bytes(void* to, size_t count) { (void)memset(to, 0, count); } +static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { +#if defined AMD64 || defined _WINDOWS + (void)memmove(to, from, count * HeapWordSize); +#else + // Includes a zero-count check. + intx temp = 0; + __asm__ volatile(" testl %6,%6 ;" + " jz 7f ;" + " cmpl %4,%5 ;" + " leal -4(%4,%6,4),%3;" + " jbe 1f ;" + " cmpl %7,%5 ;" + " jbe 4f ;" + "1: cmpl $32,%6 ;" + " ja 3f ;" + " subl %4,%1 ;" + "2: movl (%4),%3 ;" + " movl %7,(%5,%4,1) ;" + " addl $4,%0 ;" + " subl $1,%2 ;" + " jnz 2b ;" + " jmp 7f ;" + "3: rep; smovl ;" + " jmp 7f ;" + "4: cmpl $32,%2 ;" + " movl %7,%0 ;" + " leal -4(%5,%6,4),%1;" + " ja 6f ;" + " subl %4,%1 ;" + "5: movl (%4),%3 ;" + " movl %7,(%5,%4,1) ;" + " subl $4,%0 ;" + " subl $1,%2 ;" + " jnz 5b ;" + " jmp 7f ;" + "6: std ;" + " rep; smovl ;" + " cld ;" + "7: nop " + : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) + : "0" (from), "1" (to), "2" (count), "3" (temp) + : "memory", "flags"); +#endif // AMD64 +} + +static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { +#ifdef AMD64 + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + (void)memcpy(to, from, count * HeapWordSize); + break; + } +#else +#if defined _WINDOWS + (void)memcpy(to, from, count * HeapWordSize); +#else + // Includes a zero-count check. + intx temp = 0; + __asm__ volatile(" testl %6,%6 ;" + " jz 3f ;" + " cmpl $32,%6 ;" + " ja 2f ;" + " subl %4,%1 ;" + "1: movl (%4),%3 ;" + " movl %7,(%5,%4,1);" + " addl $4,%0 ;" + " subl $1,%2 ;" + " jnz 1b ;" + " jmp 3f ;" + "2: rep; smovl ;" + "3: nop " + : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) + : "0" (from), "1" (to), "2" (count), "3" (temp) + : "memory", "cc"); +#endif // _WINDOWS +#endif // AMD64 +} + +static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { +#ifdef AMD64 + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + while (count-- > 0) { + *to++ = *from++; + } + break; + } +#else + // pd_disjoint_words is word-atomic in this implementation. + pd_disjoint_words(from, to, count); +#endif // AMD64 +} + +static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_words(from, to, count); +} + +static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + pd_disjoint_words(from, to, count); +} + +static void pd_conjoint_bytes(const void* from, void* to, size_t count) { +#if defined AMD64 || defined _WINDOWS + (void)memmove(to, from, count); +#else + // Includes a zero-count check. + intx temp = 0; + __asm__ volatile(" testl %6,%6 ;" + " jz 13f ;" + " cmpl %4,%5 ;" + " leal -1(%4,%6),%3 ;" + " jbe 1f ;" + " cmpl %7,%5 ;" + " jbe 8f ;" + "1: cmpl $3,%6 ;" + " jbe 6f ;" + " movl %6,%3 ;" + " movl $4,%2 ;" + " subl %4,%2 ;" + " andl $3,%2 ;" + " jz 2f ;" + " subl %6,%3 ;" + " rep; smovb ;" + "2: movl %7,%2 ;" + " shrl $2,%2 ;" + " jz 5f ;" + " cmpl $32,%2 ;" + " ja 4f ;" + " subl %4,%1 ;" + "3: movl (%4),%%edx ;" + " movl %%edx,(%5,%4,1);" + " addl $4,%0 ;" + " subl $1,%2 ;" + " jnz 3b ;" + " addl %4,%1 ;" + " jmp 5f ;" + "4: rep; smovl ;" + "5: movl %7,%2 ;" + " andl $3,%2 ;" + " jz 13f ;" + "6: xorl %7,%3 ;" + "7: movb (%4,%7,1),%%dl ;" + " movb %%dl,(%5,%7,1) ;" + " addl $1,%3 ;" + " subl $1,%2 ;" + " jnz 7b ;" + " jmp 13f ;" + "8: std ;" + " cmpl $12,%2 ;" + " ja 9f ;" + " movl %7,%0 ;" + " leal -1(%6,%5),%1 ;" + " jmp 11f ;" + "9: xchgl %3,%2 ;" + " movl %6,%0 ;" + " addl $1,%2 ;" + " leal -1(%7,%5),%1 ;" + " andl $3,%2 ;" + " jz 10f ;" + " subl %6,%3 ;" + " rep; smovb ;" + "10: movl %7,%2 ;" + " subl $3,%0 ;" + " shrl $2,%2 ;" + " subl $3,%1 ;" + " rep; smovl ;" + " andl $3,%3 ;" + " jz 12f ;" + " movl %7,%2 ;" + " addl $3,%0 ;" + " addl $3,%1 ;" + "11: rep; smovb ;" + "12: cld ;" + "13: nop ;" + : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) + : "0" (from), "1" (to), "2" (count), "3" (temp) + : "memory", "flags", "%edx"); +#endif // AMD64 +} + +static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { + pd_conjoint_bytes(from, to, count); +} + +// Windows has a different implementation +#ifndef _WINDOWS +static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { + _Copy_conjoint_jshorts_atomic(from, to, count); +} + +static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { +#ifdef AMD64 + _Copy_conjoint_jints_atomic(from, to, count); +#else + assert(HeapWordSize == BytesPerInt, "heapwords and jints must be the same size"); + // pd_conjoint_words is word-atomic in this implementation. + pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count); +#endif // AMD64 +} + +static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { +#ifdef AMD64 + _Copy_conjoint_jlongs_atomic(from, to, count); +#else + // Guarantee use of fild/fistp or xmm regs via some asm code, because compilers won't. + if (from > to) { + while (count-- > 0) { + __asm__ volatile("fildll (%0); fistpll (%1)" + : + : "r" (from), "r" (to) + : "memory" ); + ++from; + ++to; + } + } else { + while (count-- > 0) { + __asm__ volatile("fildll (%0,%2,8); fistpll (%1,%2,8)" + : + : "r" (from), "r" (to), "r" (count) + : "memory" ); + } + } +#endif // AMD64 +} + +static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { +#ifdef AMD64 + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); +#else + assert(HeapWordSize == BytesPerOop, "heapwords and oops must be the same size"); + // pd_conjoint_words is word-atomic in this implementation. + pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count); +#endif // AMD64 +} + +static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_bytes(from, to, count); +} + +static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jshorts(from, to, count); +} + +static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { +#ifdef AMD64 + _Copy_arrayof_conjoint_jints(from, to, count); +#else + pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count); +#endif // AMD64 +} + +static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { +#ifdef AMD64 + _Copy_arrayof_conjoint_jlongs(from, to, count); +#else + pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); +#endif // AMD64 +} + +static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { +#ifdef AMD64 + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_arrayof_conjoint_jlongs(from, to, count); +#else + pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count); +#endif // AMD64 +} + +#endif // _WINDOWS + #endif // CPU_X86_COPY_X86_HPP diff --git a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp index 645c2fec8bd9e9a49c7ae77293cf680ddf1ac8cd..6525b13c5c253e54b3b2a4bce288a506ed582304 100644 --- a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp @@ -298,7 +298,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, const Register cardtable = tmp2; __ movptr(card_addr, store_addr); - __ shrptr(card_addr, CardTable::card_shift); + __ shrptr(card_addr, CardTable::card_shift()); // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT // a valid address and therefore is not properly handled by the relocation code. __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base()); @@ -540,7 +540,7 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* const Register card_addr = rcx; __ load_parameter(0, card_addr); - __ shrptr(card_addr, CardTable::card_shift); + __ shrptr(card_addr, CardTable::card_shift()); // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT // a valid address and therefore is not properly handled by the relocation code. __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base()); diff --git a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp index 9b2d2c5efedcee2eba8c4a90adfe02b7e054dd7c..7fc36ffae8f0ba32a025bbf2cf81aa71eb85c378 100644 --- a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp @@ -60,8 +60,8 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl #ifdef _LP64 __ leaq(end, Address(addr, count, TIMES_OOP, 0)); // end == addr+count*oop_size __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive - __ shrptr(addr, CardTable::card_shift); - __ shrptr(end, CardTable::card_shift); + __ shrptr(addr, CardTable::card_shift()); + __ shrptr(end, CardTable::card_shift()); __ subptr(end, addr); // end --> cards count __ mov64(tmp, disp); @@ -72,8 +72,8 @@ __ BIND(L_loop); __ jcc(Assembler::greaterEqual, L_loop); #else __ lea(end, Address(addr, count, Address::times_ptr, -wordSize)); - __ shrptr(addr, CardTable::card_shift); - __ shrptr(end, CardTable::card_shift); + __ shrptr(addr, CardTable::card_shift()); + __ shrptr(end, CardTable::card_shift()); __ subptr(end, addr); // end --> count __ BIND(L_loop); Address cardtable(addr, count, Address::times_1, disp); @@ -93,7 +93,7 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob CardTableBarrierSet* ctbs = barrier_set_cast(bs); CardTable* ct = ctbs->card_table(); - __ shrptr(obj, CardTable::card_shift); + __ shrptr(obj, CardTable::card_shift()); Address card_addr; diff --git a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp index 28c295d6139cf69dd5c4fdf0f194ae460759c202..64169b015293084fc4a9ec692c5d88977d38af6a 100644 --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp @@ -420,9 +420,9 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, if (is_strong) { if (is_narrow) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong_narrow), arg0, arg1); + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong_narrow), arg0, arg1); } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong), arg0, arg1); + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong), arg0, arg1); } } else if (is_weak) { if (is_narrow) { @@ -433,7 +433,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, } else { assert(is_phantom, "only remaining strength"); assert(!is_narrow, "phantom access cannot be narrow"); - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom), arg0, arg1); + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom), arg0, arg1); } #ifdef _LP64 diff --git a/src/hotspot/cpu/x86/jniTypes_x86.hpp b/src/hotspot/cpu/x86/jniTypes_x86.hpp index 403a0b63e2be74c8853298b646351e81085a8d9f..5c925474796d4373d43008c00d7feca2b17090de 100644 --- a/src/hotspot/cpu/x86/jniTypes_x86.hpp +++ b/src/hotspot/cpu/x86/jniTypes_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define CPU_X86_JNITYPES_X86_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive jni diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 36f480069749852497da30b6d6825d6e10f98a26..10a1cb4b6a1a0c094566558413e86fbdc0a9beff 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2702,6 +2702,15 @@ void MacroAssembler::movss(XMMRegister dst, AddressLiteral src) { } } +void MacroAssembler::vmovddup(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch) { + if (reachable(src)) { + Assembler::vmovddup(dst, as_Address(src), vector_len); + } else { + lea(rscratch, src); + Assembler::vmovddup(dst, Address(rscratch, 0), vector_len); + } +} + void MacroAssembler::mulsd(XMMRegister dst, AddressLiteral src) { if (reachable(src)) { Assembler::mulsd(dst, as_Address(src)); @@ -3151,6 +3160,15 @@ void MacroAssembler::vpbroadcastw(XMMRegister dst, XMMRegister src, int vector_l Assembler::vpbroadcastw(dst, src, vector_len); } +void MacroAssembler::vbroadcastsd(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch) { + if (reachable(src)) { + Assembler::vbroadcastsd(dst, as_Address(src), vector_len); + } else { + lea(rscratch, src); + Assembler::vbroadcastsd(dst, Address(rscratch, 0), vector_len); + } +} + void MacroAssembler::vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(((dst->encoding() < 16 && src->encoding() < 16 && nds->encoding() < 16) || VM_Version::supports_avx512vlbw()),"XMM register should be 0-15"); Assembler::vpcmpeqb(dst, nds, src, vector_len); @@ -3219,7 +3237,7 @@ void MacroAssembler::vpcmpCC(XMMRegister dst, XMMRegister nds, XMMRegister src, } } -void MacroAssembler::vpcmpCCW(XMMRegister dst, XMMRegister nds, XMMRegister src, ComparisonPredicate cond, Width width, int vector_len, Register scratch_reg) { +void MacroAssembler::vpcmpCCW(XMMRegister dst, XMMRegister nds, XMMRegister src, XMMRegister xtmp, ComparisonPredicate cond, Width width, int vector_len) { int eq_cond_enc = 0x29; int gt_cond_enc = 0x37; if (width != Assembler::Q) { @@ -3232,15 +3250,18 @@ void MacroAssembler::vpcmpCCW(XMMRegister dst, XMMRegister nds, XMMRegister src, break; case neq: vpcmpCC(dst, nds, src, eq_cond_enc, width, vector_len); - vpxor(dst, dst, ExternalAddress(StubRoutines::x86::vector_all_bits_set()), vector_len, scratch_reg); + vallones(xtmp, vector_len); + vpxor(dst, xtmp, dst, vector_len); break; case le: vpcmpCC(dst, nds, src, gt_cond_enc, width, vector_len); - vpxor(dst, dst, ExternalAddress(StubRoutines::x86::vector_all_bits_set()), vector_len, scratch_reg); + vallones(xtmp, vector_len); + vpxor(dst, xtmp, dst, vector_len); break; case nlt: vpcmpCC(dst, src, nds, gt_cond_enc, width, vector_len); - vpxor(dst, dst, ExternalAddress(StubRoutines::x86::vector_all_bits_set()), vector_len, scratch_reg); + vallones(xtmp, vector_len); + vpxor(dst, xtmp, dst, vector_len); break; case lt: vpcmpCC(dst, src, nds, gt_cond_enc, width, vector_len); @@ -4630,12 +4651,19 @@ void MacroAssembler::verify_heapbase(const char* msg) { assert (Universe::heap() != NULL, "java heap should be initialized"); if (CheckCompressedOops) { Label ok; - push(rscratch1); // cmpptr trashes rscratch1 - cmpptr(r12_heapbase, ExternalAddress((address)CompressedOops::ptrs_base_addr())); + const auto src2 = ExternalAddress((address)CompressedOops::ptrs_base_addr()); + assert(!src2.is_lval(), "should not be lval"); + const bool is_src2_reachable = reachable(src2); + if (!is_src2_reachable) { + push(rscratch1); // cmpptr trashes rscratch1 + } + cmpptr(r12_heapbase, src2); jcc(Assembler::equal, ok); STOP(msg); bind(ok); - pop(rscratch1); + if (!is_src2_reachable) { + pop(rscratch1); + } } } #endif diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index 5c101b496875eb22ac4f622db7dbbdf06e4299af..3593874866ca81157b1fa49f975034d866383443 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1176,6 +1176,9 @@ public: void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } void movsd(XMMRegister dst, AddressLiteral src); + using Assembler::vmovddup; + void vmovddup(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); + void mulpd(XMMRegister dst, XMMRegister src) { Assembler::mulpd(dst, src); } void mulpd(XMMRegister dst, Address src) { Assembler::mulpd(dst, src); } void mulpd(XMMRegister dst, AddressLiteral src); @@ -1284,6 +1287,9 @@ public: void vpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len); void vpbroadcastw(XMMRegister dst, Address src, int vector_len) { Assembler::vpbroadcastw(dst, src, vector_len); } + using Assembler::vbroadcastsd; + void vbroadcastsd(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = rscratch1); + void vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); @@ -1310,7 +1316,7 @@ public: void evpbroadcast(BasicType type, XMMRegister dst, Register src, int vector_len); // Emit comparison instruction for the specified comparison predicate. - void vpcmpCCW(XMMRegister dst, XMMRegister nds, XMMRegister src, ComparisonPredicate cond, Width width, int vector_len, Register scratch_reg); + void vpcmpCCW(XMMRegister dst, XMMRegister nds, XMMRegister src, XMMRegister xtmp, ComparisonPredicate cond, Width width, int vector_len); void vpcmpCC(XMMRegister dst, XMMRegister nds, XMMRegister src, int cond_encoding, Width width, int vector_len); void vpmovzxbw(XMMRegister dst, Address src, int vector_len); @@ -1489,8 +1495,14 @@ public: void vpxor(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg = rscratch1); // Simple version for AVX2 256bit vectors - void vpxor(XMMRegister dst, XMMRegister src) { Assembler::vpxor(dst, dst, src, true); } - void vpxor(XMMRegister dst, Address src) { Assembler::vpxor(dst, dst, src, true); } + void vpxor(XMMRegister dst, XMMRegister src) { + assert(UseAVX >= 2, "Should be at least AVX2"); + Assembler::vpxor(dst, dst, src, AVX_256bit); + } + void vpxor(XMMRegister dst, Address src) { + assert(UseAVX >= 2, "Should be at least AVX2"); + Assembler::vpxor(dst, dst, src, AVX_256bit); + } void vpermd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vpermd(dst, nds, src, vector_len); } void vpermd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg); diff --git a/src/hotspot/cpu/x86/matcher_x86.hpp b/src/hotspot/cpu/x86/matcher_x86.hpp index 2dcd1e6e7a94adacf4494dfa848dd884ef2e10a4..61af24cf31c52261cbb2fd7149c880f1a22373fb 100644 --- a/src/hotspot/cpu/x86/matcher_x86.hpp +++ b/src/hotspot/cpu/x86/matcher_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,8 +148,6 @@ static const bool int_in_long = false; #endif - // Number of htbl entries for aes-gcm intrinsic - static const int htbl_entries = 96; // Does the CPU supports vector variable shift instructions? static bool supports_vector_variable_shifts(void) { @@ -168,20 +166,7 @@ // Does the CPU supports vector unsigned comparison instructions? static const bool supports_vector_comparison_unsigned(int vlen, BasicType bt) { - int vlen_in_bytes = vlen * type2aelembytes(bt); - if ((UseAVX > 2) && (VM_Version::supports_avx512vl() || vlen_in_bytes == 64)) - return true; - else { - // instruction set supports only signed comparison - // so need to zero extend to higher integral type and perform comparison - // cannot cast long to higher integral type - // and on avx1 cannot cast 128 bit integral vectors to higher size - - if ((bt != T_LONG) && - ((UseAVX >= 2) || (vlen_in_bytes <= 8))) - return true; - } - return false; + return true; } // Some microarchitectures have mask registers used on vectors diff --git a/src/hotspot/cpu/x86/rdtsc_x86.cpp b/src/hotspot/cpu/x86/rdtsc_x86.cpp index a4e743cc2dfbfaf9ca2ebda349cbd2cad6d61091..c6109ccdefec75be712e06f15345e74cf4a3890b 100644 --- a/src/hotspot/cpu/x86/rdtsc_x86.cpp +++ b/src/hotspot/cpu/x86/rdtsc_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "runtime/globals_extension.hpp" #include "runtime/orderAccess.hpp" #include "runtime/thread.inline.hpp" -#include "vm_version_ext_x86.hpp" +#include "vm_version_x86.hpp" // The following header contains the implementations of rdtsc() #include OS_CPU_HEADER_INLINE(os) @@ -101,9 +101,9 @@ static jlong initialize_frequency() { // if platform supports invariant tsc, // apply higher resolution and granularity for conversion calculations - if (VM_Version_Ext::supports_tscinv_ext()) { + if (VM_Version::supports_tscinv_ext()) { // for invariant tsc platforms, take the maximum qualified cpu frequency - tsc_freq = (double)VM_Version_Ext::maximum_qualified_cpu_frequency(); + tsc_freq = (double)VM_Version::maximum_qualified_cpu_frequency(); os_to_tsc_conv_factor = tsc_freq / os_freq; } else { // use measurements to estimate @@ -171,7 +171,7 @@ static bool ergonomics() { } bool Rdtsc::is_supported() { - return VM_Version_Ext::supports_tscinv_ext(); + return VM_Version::supports_tscinv_ext(); } bool Rdtsc::is_elapsed_counter_enabled() { @@ -198,7 +198,7 @@ bool Rdtsc::initialize() { static bool initialized = false; if (!initialized) { assert(!rdtsc_elapsed_counter_enabled, "invariant"); - VM_Version_Ext::initialize(); + VM_Version::initialize_tsc(); assert(0 == tsc_frequency, "invariant"); assert(0 == _epoch, "invariant"); bool result = initialize_elapsed_counter(); // init hw diff --git a/src/hotspot/cpu/x86/rdtsc_x86.hpp b/src/hotspot/cpu/x86/rdtsc_x86.hpp index f66997c9cfedfeae8cd1650931b79a656bbd9022..d9e77a0ae6bcf32d6d79711255d7fbc9b2b0b47f 100644 --- a/src/hotspot/cpu/x86/rdtsc_x86.hpp +++ b/src/hotspot/cpu/x86/rdtsc_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ #ifndef CPU_X86_RDTSC_X86_HPP #define CPU_X86_RDTSC_X86_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" // Interface to the x86 rdtsc() time counter, if available. diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp index a00af0e4af0d61c1ccf64598a5ef314a3a2e2930..e5a46138473dff074e7032b7943842e0489d7c0a 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp @@ -1705,36 +1705,41 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, // Load the oop from the handle __ movptr(obj_reg, Address(oop_handle_reg, 0)); - // Load immediate 1 into swap_reg %rax, - __ movptr(swap_reg, 1); - - // Load (object->mark() | 1) into swap_reg %rax, - __ orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - - // Save (object->mark() | 1) into BasicLock's displaced header - __ movptr(Address(lock_reg, mark_word_offset), swap_reg); - - // src -> dest iff dest == rax, else rax, <- dest - // *obj_reg = lock_reg iff *obj_reg == rax, else rax, = *(obj_reg) - __ lock(); - __ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ jcc(Assembler::equal, lock_done); - - // Test if the oopMark is an obvious stack pointer, i.e., - // 1) (mark & 3) == 0, and - // 2) rsp <= mark < mark + os::pagesize() - // These 3 tests can be done by evaluating the following - // expression: ((mark - rsp) & (3 - os::vm_page_size())), - // assuming both stack pointer and pagesize have their - // least significant 2 bits clear. - // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg - - __ subptr(swap_reg, rsp); - __ andptr(swap_reg, 3 - os::vm_page_size()); - - // Save the test result, for recursive case, the result is zero - __ movptr(Address(lock_reg, mark_word_offset), swap_reg); - __ jcc(Assembler::notEqual, slow_path_lock); + if (!UseHeavyMonitors) { + // Load immediate 1 into swap_reg %rax, + __ movptr(swap_reg, 1); + + // Load (object->mark() | 1) into swap_reg %rax, + __ orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + + // Save (object->mark() | 1) into BasicLock's displaced header + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); + + // src -> dest iff dest == rax, else rax, <- dest + // *obj_reg = lock_reg iff *obj_reg == rax, else rax, = *(obj_reg) + __ lock(); + __ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + __ jcc(Assembler::equal, lock_done); + + // Test if the oopMark is an obvious stack pointer, i.e., + // 1) (mark & 3) == 0, and + // 2) rsp <= mark < mark + os::pagesize() + // These 3 tests can be done by evaluating the following + // expression: ((mark - rsp) & (3 - os::vm_page_size())), + // assuming both stack pointer and pagesize have their + // least significant 2 bits clear. + // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg + + __ subptr(swap_reg, rsp); + __ andptr(swap_reg, 3 - os::vm_page_size()); + + // Save the test result, for recursive case, the result is zero + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); + __ jcc(Assembler::notEqual, slow_path_lock); + } else { + __ jmp(slow_path_lock); + } + // Slow path will re-enter here __ bind(lock_done); } @@ -1852,28 +1857,34 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, // Get locked oop from the handle we passed to jni __ movptr(obj_reg, Address(oop_handle_reg, 0)); - // Simple recursive lock? + if (!UseHeavyMonitors) { + // Simple recursive lock? - __ cmpptr(Address(rbp, lock_slot_rbp_offset), (int32_t)NULL_WORD); - __ jcc(Assembler::equal, done); + __ cmpptr(Address(rbp, lock_slot_rbp_offset), (int32_t)NULL_WORD); + __ jcc(Assembler::equal, done); + } - // Must save rax, if if it is live now because cmpxchg must use it + // Must save rax, if it is live now because cmpxchg must use it if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { save_native_result(masm, ret_type, stack_slots); } - // get old displaced header - __ movptr(rbx, Address(rbp, lock_slot_rbp_offset)); + if (!UseHeavyMonitors) { + // get old displaced header + __ movptr(rbx, Address(rbp, lock_slot_rbp_offset)); - // get address of the stack lock - __ lea(rax, Address(rbp, lock_slot_rbp_offset)); + // get address of the stack lock + __ lea(rax, Address(rbp, lock_slot_rbp_offset)); - // Atomic swap old header if oop still contains the stack lock - // src -> dest iff dest == rax, else rax, <- dest - // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg) - __ lock(); - __ cmpxchgptr(rbx, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ jcc(Assembler::notEqual, slow_path_unlock); + // Atomic swap old header if oop still contains the stack lock + // src -> dest iff dest == rax, else rax, <- dest + // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg) + __ lock(); + __ cmpxchgptr(rbx, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + __ jcc(Assembler::notEqual, slow_path_unlock); + } else { + __ jmp(slow_path_unlock); + } // slow path re-enters here __ bind(unlock_done); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index f78ec39c25e42c7dc8a3c3d55e776546cec92091..6597c91bb42ff11d09b4c5c741a35bd0b27f8d25 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1918,37 +1918,41 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, // Load the oop from the handle __ movptr(obj_reg, Address(oop_handle_reg, 0)); - // Load immediate 1 into swap_reg %rax - __ movl(swap_reg, 1); + if (!UseHeavyMonitors) { + // Load immediate 1 into swap_reg %rax + __ movl(swap_reg, 1); - // Load (object->mark() | 1) into swap_reg %rax - __ orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + // Load (object->mark() | 1) into swap_reg %rax + __ orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - // Save (object->mark() | 1) into BasicLock's displaced header - __ movptr(Address(lock_reg, mark_word_offset), swap_reg); + // Save (object->mark() | 1) into BasicLock's displaced header + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); - // src -> dest iff dest == rax else rax <- dest - __ lock(); - __ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ jcc(Assembler::equal, lock_done); + // src -> dest iff dest == rax else rax <- dest + __ lock(); + __ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + __ jcc(Assembler::equal, lock_done); - // Hmm should this move to the slow path code area??? + // Hmm should this move to the slow path code area??? - // Test if the oopMark is an obvious stack pointer, i.e., - // 1) (mark & 3) == 0, and - // 2) rsp <= mark < mark + os::pagesize() - // These 3 tests can be done by evaluating the following - // expression: ((mark - rsp) & (3 - os::vm_page_size())), - // assuming both stack pointer and pagesize have their - // least significant 2 bits clear. - // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg + // Test if the oopMark is an obvious stack pointer, i.e., + // 1) (mark & 3) == 0, and + // 2) rsp <= mark < mark + os::pagesize() + // These 3 tests can be done by evaluating the following + // expression: ((mark - rsp) & (3 - os::vm_page_size())), + // assuming both stack pointer and pagesize have their + // least significant 2 bits clear. + // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg - __ subptr(swap_reg, rsp); - __ andptr(swap_reg, 3 - os::vm_page_size()); + __ subptr(swap_reg, rsp); + __ andptr(swap_reg, 3 - os::vm_page_size()); - // Save the test result, for recursive case, the result is zero - __ movptr(Address(lock_reg, mark_word_offset), swap_reg); - __ jcc(Assembler::notEqual, slow_path_lock); + // Save the test result, for recursive case, the result is zero + __ movptr(Address(lock_reg, mark_word_offset), swap_reg); + __ jcc(Assembler::notEqual, slow_path_lock); + } else { + __ jmp(slow_path_lock); + } // Slow path will re-enter here @@ -2055,26 +2059,32 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, __ movptr(obj_reg, Address(oop_handle_reg, 0)); Label done; - // Simple recursive lock? - __ cmpptr(Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size), (int32_t)NULL_WORD); - __ jcc(Assembler::equal, done); + if (!UseHeavyMonitors) { + // Simple recursive lock? + __ cmpptr(Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size), (int32_t)NULL_WORD); + __ jcc(Assembler::equal, done); + } - // Must save rax if if it is live now because cmpxchg must use it + // Must save rax if it is live now because cmpxchg must use it if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { save_native_result(masm, ret_type, stack_slots); } - // get address of the stack lock - __ lea(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); - // get old displaced header - __ movptr(old_hdr, Address(rax, 0)); + if (!UseHeavyMonitors) { + // get address of the stack lock + __ lea(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); + // get old displaced header + __ movptr(old_hdr, Address(rax, 0)); - // Atomic swap old header if oop still contains the stack lock - __ lock(); - __ cmpxchgptr(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes())); - __ jcc(Assembler::notEqual, slow_path_unlock); + // Atomic swap old header if oop still contains the stack lock + __ lock(); + __ cmpxchgptr(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes())); + __ jcc(Assembler::notEqual, slow_path_unlock); + } else { + __ jmp(slow_path_unlock); + } // slow path re-enters here __ bind(unlock_done); @@ -3532,8 +3542,9 @@ void SharedRuntime::montgomery_multiply(jint *a_ints, jint *b_ints, jint *n_ints // Make very sure we don't use so much space that the stack might // overflow. 512 jints corresponds to an 16384-bit integer and // will use here a total of 8k bytes of stack space. + int divisor = sizeof(julong) * 4; + guarantee(longwords <= 8192 / divisor, "must be"); int total_allocation = longwords * sizeof (julong) * 4; - guarantee(total_allocation <= 8192, "must be"); julong *scratch = (julong *)alloca(total_allocation); // Local scratch arrays @@ -3561,8 +3572,9 @@ void SharedRuntime::montgomery_square(jint *a_ints, jint *n_ints, // Make very sure we don't use so much space that the stack might // overflow. 512 jints corresponds to an 16384-bit integer and // will use here a total of 6k bytes of stack space. + int divisor = sizeof(julong) * 3; + guarantee(longwords <= (8192 / divisor), "must be"); int total_allocation = longwords * sizeof (julong) * 3; - guarantee(total_allocation <= 8192, "must be"); julong *scratch = (julong *)alloca(total_allocation); // Local scratch arrays diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index e80d105bc365a835681d51660d8f8292f5e8aa0e..8b7188ca42c88ff68959b723b177f950d8fa87bc 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -1221,11 +1221,6 @@ class StubGenerator: public StubCodeGenerator { } __ addptr(qword_count, 4); __ BIND(L_end); - if (UseAVX >= 2) { - // clean upper bits of YMM registers - __ vpxor(xmm0, xmm0); - __ vpxor(xmm1, xmm1); - } } else { // Copy 32-bytes per iteration __ BIND(L_loop); @@ -1299,11 +1294,6 @@ class StubGenerator: public StubCodeGenerator { } __ subptr(qword_count, 4); __ BIND(L_end); - if (UseAVX >= 2) { - // clean upper bits of YMM registers - __ vpxor(xmm0, xmm0); - __ vpxor(xmm1, xmm1); - } } else { // Copy 32-bytes per iteration __ BIND(L_loop); @@ -4138,6 +4128,7 @@ class StubGenerator: public StubCodeGenerator { const Register len = c_rarg3; // src len (must be multiple of blocksize 16) __ enter(); // required for proper stackwalking of RuntimeStub frame __ aesecb_encrypt(from, to, key, len); + __ vzeroupper(); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); return start; @@ -4153,6 +4144,7 @@ class StubGenerator: public StubCodeGenerator { const Register len = c_rarg3; // src len (must be multiple of blocksize 16) __ enter(); // required for proper stackwalking of RuntimeStub frame __ aesecb_decrypt(from, to, key, len); + __ vzeroupper(); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); return start; @@ -4414,9 +4406,8 @@ class StubGenerator: public StubCodeGenerator { const Register state = c_rarg5; const Address subkeyH_mem(rbp, 2 * wordSize); const Register subkeyHtbl = r11; - const Address avx512_subkeyH_mem(rbp, 3 * wordSize); const Register avx512_subkeyHtbl = r13; - const Address counter_mem(rbp, 4 * wordSize); + const Address counter_mem(rbp, 3 * wordSize); const Register counter = r12; #else const Address key_mem(rbp, 6 * wordSize); @@ -4425,9 +4416,8 @@ class StubGenerator: public StubCodeGenerator { const Register state = r13; const Address subkeyH_mem(rbp, 8 * wordSize); const Register subkeyHtbl = r14; - const Address avx512_subkeyH_mem(rbp, 9 * wordSize); const Register avx512_subkeyHtbl = r12; - const Address counter_mem(rbp, 10 * wordSize); + const Address counter_mem(rbp, 9 * wordSize); const Register counter = rsi; #endif __ enter(); @@ -4444,10 +4434,20 @@ class StubGenerator: public StubCodeGenerator { __ movptr(state, state_mem); #endif __ movptr(subkeyHtbl, subkeyH_mem); - __ movptr(avx512_subkeyHtbl, avx512_subkeyH_mem); __ movptr(counter, counter_mem); +// Save rbp and rsp + __ push(rbp); + __ movq(rbp, rsp); +// Align stack + __ andq(rsp, -64); + __ subptr(rsp, 96 * longSize); // Create space on the stack for htbl entries + __ movptr(avx512_subkeyHtbl, rsp); __ aesgcm_encrypt(in, len, ct, out, key, state, subkeyHtbl, avx512_subkeyHtbl, counter); + __ vzeroupper(); + + __ movq(rsp, rbp); + __ pop(rbp); // Restore state before leaving routine #ifdef _WIN64 @@ -4564,6 +4564,7 @@ class StubGenerator: public StubCodeGenerator { #endif __ push(rbx); __ aesctr_encrypt(from, to, key, counter, len_reg, used, used_addr, saved_encCounter_start); + __ vzeroupper(); // Restore state before leaving routine __ pop(rbx); #ifdef _WIN64 @@ -5184,6 +5185,7 @@ address generate_cipherBlockChaining_decryptVectorAESCrypt() { __ evpxorq(RK14, RK14, RK14, Assembler::AVX_512bit); __ BIND(Lcbc_exit); + __ vzeroupper(); __ pop(rbx); #ifdef _WIN64 __ movl(rax, len_mem); @@ -6261,6 +6263,9 @@ address generate_avx_ghash_processBlocks() { __ cmpl(length, 63); __ jcc(Assembler::lessEqual, L_finalBit); + __ mov64(rax, 0x0000ffffffffffff); + __ kmovql(k2, rax); + __ align32(); __ BIND(L_process64Loop); @@ -6282,7 +6287,7 @@ address generate_avx_ghash_processBlocks() { __ vpmaddwd(merged0, merge_ab_bc0, pack32_op, Assembler::AVX_512bit); __ vpermb(merged0, pack24bits, merged0, Assembler::AVX_512bit); - __ evmovdquq(Address(dest, dp), merged0, Assembler::AVX_512bit); + __ evmovdqub(Address(dest, dp), k2, merged0, true, Assembler::AVX_512bit); __ subl(length, 64); __ addptr(source, 64); @@ -7056,6 +7061,7 @@ address generate_avx_ghash_processBlocks() { __ shrdl(tmp4, tmp3); __ movl(Address(newArr, nIdx, Address::times_4), tmp4); __ BIND(Exit); + __ vzeroupper(); // Restore callee save registers. __ pop(tmp5); #ifdef _WINDOWS @@ -7177,6 +7183,7 @@ address generate_avx_ghash_processBlocks() { __ movl(Address(newArr, idx, Address::times_4), tmp3); __ BIND(Exit); + __ vzeroupper(); // Restore callee save registers. __ pop(tmp5); #ifdef _WINDOWS diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp index 75dc0535d2a5506fe9cbd1bd73776706d0bc3352..8702a28ac689fc071bd4bf91acfcdb7d7bf7adb5 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp @@ -445,3 +445,18 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M return entry_point; } +address TemplateInterpreterGenerator::generate_currentThread() { + + address entry_point = __ pc(); + + __ movptr(rax, Address(r15_thread, JavaThread::threadObj_offset())); + + __ resolve_oop_handle(rax, rscratch1); + + __ pop(rcx); + __ mov(rsp, r13); + __ jmp(rcx); + + return entry_point; +} + diff --git a/src/hotspot/cpu/x86/vm_version_ext_x86.cpp b/src/hotspot/cpu/x86/vm_version_ext_x86.cpp deleted file mode 100644 index 84e8c9fa819a87c9ca8ad779c671961b9a2e9b9c..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/x86/vm_version_ext_x86.cpp +++ /dev/null @@ -1,982 +0,0 @@ -/* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "jvm.h" -#include "utilities/macros.hpp" -#include "asm/macroAssembler.hpp" -#include "asm/macroAssembler.inline.hpp" -#include "code/codeBlob.hpp" -#include "memory/allocation.inline.hpp" -#include "memory/resourceArea.hpp" -#include "runtime/java.hpp" -#include "runtime/stubCodeGenerator.hpp" -#include "vm_version_ext_x86.hpp" - -typedef enum { - CPU_FAMILY_8086_8088 = 0, - CPU_FAMILY_INTEL_286 = 2, - CPU_FAMILY_INTEL_386 = 3, - CPU_FAMILY_INTEL_486 = 4, - CPU_FAMILY_PENTIUM = 5, - CPU_FAMILY_PENTIUMPRO = 6, // Same family several models - CPU_FAMILY_PENTIUM_4 = 0xF -} FamilyFlag; - -typedef enum { - RDTSCP_FLAG = 0x08000000, // bit 27 - INTEL64_FLAG = 0x20000000 // bit 29 -} _featureExtendedEdxFlag; - -#define CPUID_STANDARD_FN 0x0 -#define CPUID_STANDARD_FN_1 0x1 -#define CPUID_STANDARD_FN_4 0x4 -#define CPUID_STANDARD_FN_B 0xb - -#define CPUID_EXTENDED_FN 0x80000000 -#define CPUID_EXTENDED_FN_1 0x80000001 -#define CPUID_EXTENDED_FN_2 0x80000002 -#define CPUID_EXTENDED_FN_3 0x80000003 -#define CPUID_EXTENDED_FN_4 0x80000004 -#define CPUID_EXTENDED_FN_7 0x80000007 -#define CPUID_EXTENDED_FN_8 0x80000008 - -typedef enum { - FPU_FLAG = 0x00000001, - VME_FLAG = 0x00000002, - DE_FLAG = 0x00000004, - PSE_FLAG = 0x00000008, - TSC_FLAG = 0x00000010, - MSR_FLAG = 0x00000020, - PAE_FLAG = 0x00000040, - MCE_FLAG = 0x00000080, - CX8_FLAG = 0x00000100, - APIC_FLAG = 0x00000200, - SEP_FLAG = 0x00000800, - MTRR_FLAG = 0x00001000, - PGE_FLAG = 0x00002000, - MCA_FLAG = 0x00004000, - CMOV_FLAG = 0x00008000, - PAT_FLAG = 0x00010000, - PSE36_FLAG = 0x00020000, - PSNUM_FLAG = 0x00040000, - CLFLUSH_FLAG = 0x00080000, - DTS_FLAG = 0x00200000, - ACPI_FLAG = 0x00400000, - MMX_FLAG = 0x00800000, - FXSR_FLAG = 0x01000000, - SSE_FLAG = 0x02000000, - SSE2_FLAG = 0x04000000, - SS_FLAG = 0x08000000, - HTT_FLAG = 0x10000000, - TM_FLAG = 0x20000000 -} FeatureEdxFlag; - -static BufferBlob* cpuid_brand_string_stub_blob; -static const int cpuid_brand_string_stub_size = 550; - -extern "C" { - typedef void (*getCPUIDBrandString_stub_t)(void*); -} - -static getCPUIDBrandString_stub_t getCPUIDBrandString_stub = NULL; - -class VM_Version_Ext_StubGenerator: public StubCodeGenerator { - public: - - VM_Version_Ext_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} - - address generate_getCPUIDBrandString(void) { - // Flags to test CPU type. - const uint32_t HS_EFL_AC = 0x40000; - const uint32_t HS_EFL_ID = 0x200000; - // Values for when we don't have a CPUID instruction. - const int CPU_FAMILY_SHIFT = 8; - const uint32_t CPU_FAMILY_386 = (3 << CPU_FAMILY_SHIFT); - const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT); - - Label detect_486, cpu486, detect_586, done, ext_cpuid; - - StubCodeMark mark(this, "VM_Version_Ext", "getCPUIDNameInfo_stub"); -# define __ _masm-> - - address start = __ pc(); - - // - // void getCPUIDBrandString(VM_Version::CpuidInfo* cpuid_info); - // - // LP64: rcx and rdx are first and second argument registers on windows - - __ push(rbp); -#ifdef _LP64 - __ mov(rbp, c_rarg0); // cpuid_info address -#else - __ movptr(rbp, Address(rsp, 8)); // cpuid_info address -#endif - __ push(rbx); - __ push(rsi); - __ pushf(); // preserve rbx, and flags - __ pop(rax); - __ push(rax); - __ mov(rcx, rax); - // - // if we are unable to change the AC flag, we have a 386 - // - __ xorl(rax, HS_EFL_AC); - __ push(rax); - __ popf(); - __ pushf(); - __ pop(rax); - __ cmpptr(rax, rcx); - __ jccb(Assembler::notEqual, detect_486); - - __ movl(rax, CPU_FAMILY_386); - __ jmp(done); - - // - // If we are unable to change the ID flag, we have a 486 which does - // not support the "cpuid" instruction. - // - __ bind(detect_486); - __ mov(rax, rcx); - __ xorl(rax, HS_EFL_ID); - __ push(rax); - __ popf(); - __ pushf(); - __ pop(rax); - __ cmpptr(rcx, rax); - __ jccb(Assembler::notEqual, detect_586); - - __ bind(cpu486); - __ movl(rax, CPU_FAMILY_486); - __ jmp(done); - - // - // At this point, we have a chip which supports the "cpuid" instruction - // - __ bind(detect_586); - __ xorl(rax, rax); - __ cpuid(); - __ orl(rax, rax); - __ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input - // value of at least 1, we give up and - // assume a 486 - - // - // Extended cpuid(0x80000000) for processor brand string detection - // - __ bind(ext_cpuid); - __ movl(rax, CPUID_EXTENDED_FN); - __ cpuid(); - __ cmpl(rax, CPUID_EXTENDED_FN_4); - __ jcc(Assembler::below, done); - - // - // Extended cpuid(0x80000002) // first 16 bytes in brand string - // - __ movl(rax, CPUID_EXTENDED_FN_2); - __ cpuid(); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_0_offset()))); - __ movl(Address(rsi, 0), rax); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_1_offset()))); - __ movl(Address(rsi, 0), rbx); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_2_offset()))); - __ movl(Address(rsi, 0), rcx); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_3_offset()))); - __ movl(Address(rsi,0), rdx); - - // - // Extended cpuid(0x80000003) // next 16 bytes in brand string - // - __ movl(rax, CPUID_EXTENDED_FN_3); - __ cpuid(); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_4_offset()))); - __ movl(Address(rsi, 0), rax); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_5_offset()))); - __ movl(Address(rsi, 0), rbx); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_6_offset()))); - __ movl(Address(rsi, 0), rcx); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_7_offset()))); - __ movl(Address(rsi,0), rdx); - - // - // Extended cpuid(0x80000004) // last 16 bytes in brand string - // - __ movl(rax, CPUID_EXTENDED_FN_4); - __ cpuid(); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_8_offset()))); - __ movl(Address(rsi, 0), rax); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_9_offset()))); - __ movl(Address(rsi, 0), rbx); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_10_offset()))); - __ movl(Address(rsi, 0), rcx); - __ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_11_offset()))); - __ movl(Address(rsi,0), rdx); - - // - // return - // - __ bind(done); - __ popf(); - __ pop(rsi); - __ pop(rbx); - __ pop(rbp); - __ ret(0); - -# undef __ - - return start; - }; -}; - - -// VM_Version_Ext statics -const size_t VM_Version_Ext::VENDOR_LENGTH = 13; -const size_t VM_Version_Ext::CPU_EBS_MAX_LENGTH = (3 * 4 * 4 + 1); -const size_t VM_Version_Ext::CPU_TYPE_DESC_BUF_SIZE = 256; -const size_t VM_Version_Ext::CPU_DETAILED_DESC_BUF_SIZE = 4096; -char* VM_Version_Ext::_cpu_brand_string = NULL; -int64_t VM_Version_Ext::_max_qualified_cpu_frequency = 0; - -int VM_Version_Ext::_no_of_threads = 0; -int VM_Version_Ext::_no_of_cores = 0; -int VM_Version_Ext::_no_of_packages = 0; - -void VM_Version_Ext::initialize(void) { - ResourceMark rm; - - cpuid_brand_string_stub_blob = BufferBlob::create("getCPUIDBrandString_stub", cpuid_brand_string_stub_size); - if (cpuid_brand_string_stub_blob == NULL) { - vm_exit_during_initialization("Unable to allocate getCPUIDBrandString_stub"); - } - CodeBuffer c(cpuid_brand_string_stub_blob); - VM_Version_Ext_StubGenerator g(&c); - getCPUIDBrandString_stub = CAST_TO_FN_PTR(getCPUIDBrandString_stub_t, - g.generate_getCPUIDBrandString()); -} - -const char* VM_Version_Ext::cpu_model_description(void) { - uint32_t cpu_family = extended_cpu_family(); - uint32_t cpu_model = extended_cpu_model(); - const char* model = NULL; - - if (cpu_family == CPU_FAMILY_PENTIUMPRO) { - for (uint32_t i = 0; i <= cpu_model; i++) { - model = _model_id_pentium_pro[i]; - if (model == NULL) { - break; - } - } - } - return model; -} - -const char* VM_Version_Ext::cpu_brand_string(void) { - if (_cpu_brand_string == NULL) { - _cpu_brand_string = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_EBS_MAX_LENGTH, mtInternal); - if (NULL == _cpu_brand_string) { - return NULL; - } - int ret_val = cpu_extended_brand_string(_cpu_brand_string, CPU_EBS_MAX_LENGTH); - if (ret_val != OS_OK) { - FREE_C_HEAP_ARRAY(char, _cpu_brand_string); - _cpu_brand_string = NULL; - } - } - return _cpu_brand_string; -} - -const char* VM_Version_Ext::cpu_brand(void) { - const char* brand = NULL; - - if ((_cpuid_info.std_cpuid1_ebx.value & 0xFF) > 0) { - int brand_num = _cpuid_info.std_cpuid1_ebx.value & 0xFF; - brand = _brand_id[0]; - for (int i = 0; brand != NULL && i <= brand_num; i += 1) { - brand = _brand_id[i]; - } - } - return brand; -} - -bool VM_Version_Ext::cpu_is_em64t(void) { - return ((_cpuid_info.ext_cpuid1_edx.value & INTEL64_FLAG) == INTEL64_FLAG); -} - -bool VM_Version_Ext::is_netburst(void) { - return (is_intel() && (extended_cpu_family() == CPU_FAMILY_PENTIUM_4)); -} - -bool VM_Version_Ext::supports_tscinv_ext(void) { - if (!supports_tscinv_bit()) { - return false; - } - - if (is_intel()) { - return true; - } - - if (is_amd()) { - return !is_amd_Barcelona(); - } - - if (is_hygon()) { - return true; - } - - return false; -} - -void VM_Version_Ext::resolve_cpu_information_details(void) { - - // in future we want to base this information on proper cpu - // and cache topology enumeration such as: - // Intel 64 Architecture Processor Topology Enumeration - // which supports system cpu and cache topology enumeration - // either using 2xAPICIDs or initial APICIDs - - // currently only rough cpu information estimates - // which will not necessarily reflect the exact configuration of the system - - // this is the number of logical hardware threads - // visible to the operating system - _no_of_threads = os::processor_count(); - - // find out number of threads per cpu package - int threads_per_package = threads_per_core() * cores_per_cpu(); - - // use amount of threads visible to the process in order to guess number of sockets - _no_of_packages = _no_of_threads / threads_per_package; - - // process might only see a subset of the total number of threads - // from a single processor package. Virtualization/resource management for example. - // If so then just write a hard 1 as num of pkgs. - if (0 == _no_of_packages) { - _no_of_packages = 1; - } - - // estimate the number of cores - _no_of_cores = cores_per_cpu() * _no_of_packages; -} - -int VM_Version_Ext::number_of_threads(void) { - if (_no_of_threads == 0) { - resolve_cpu_information_details(); - } - return _no_of_threads; -} - -int VM_Version_Ext::number_of_cores(void) { - if (_no_of_cores == 0) { - resolve_cpu_information_details(); - } - return _no_of_cores; -} - -int VM_Version_Ext::number_of_sockets(void) { - if (_no_of_packages == 0) { - resolve_cpu_information_details(); - } - return _no_of_packages; -} - -const char* VM_Version_Ext::cpu_family_description(void) { - int cpu_family_id = extended_cpu_family(); - if (is_amd()) { - if (cpu_family_id < ExtendedFamilyIdLength_AMD) { - return _family_id_amd[cpu_family_id]; - } - } - if (is_intel()) { - if (cpu_family_id == CPU_FAMILY_PENTIUMPRO) { - return cpu_model_description(); - } - if (cpu_family_id < ExtendedFamilyIdLength_INTEL) { - return _family_id_intel[cpu_family_id]; - } - } - if (is_hygon()) { - return "Dhyana"; - } - return "Unknown x86"; -} - -int VM_Version_Ext::cpu_type_description(char* const buf, size_t buf_len) { - assert(buf != NULL, "buffer is NULL!"); - assert(buf_len >= CPU_TYPE_DESC_BUF_SIZE, "buffer len should at least be == CPU_TYPE_DESC_BUF_SIZE!"); - - const char* cpu_type = NULL; - const char* x64 = NULL; - - if (is_intel()) { - cpu_type = "Intel"; - x64 = cpu_is_em64t() ? " Intel64" : ""; - } else if (is_amd()) { - cpu_type = "AMD"; - x64 = cpu_is_em64t() ? " AMD64" : ""; - } else if (is_hygon()) { - cpu_type = "Hygon"; - x64 = cpu_is_em64t() ? " AMD64" : ""; - } else { - cpu_type = "Unknown x86"; - x64 = cpu_is_em64t() ? " x86_64" : ""; - } - - jio_snprintf(buf, buf_len, "%s %s%s SSE SSE2%s%s%s%s%s%s%s%s", - cpu_type, - cpu_family_description(), - supports_ht() ? " (HT)" : "", - supports_sse3() ? " SSE3" : "", - supports_ssse3() ? " SSSE3" : "", - supports_sse4_1() ? " SSE4.1" : "", - supports_sse4_2() ? " SSE4.2" : "", - supports_sse4a() ? " SSE4A" : "", - is_netburst() ? " Netburst" : "", - is_intel_family_core() ? " Core" : "", - x64); - - return OS_OK; -} - -int VM_Version_Ext::cpu_extended_brand_string(char* const buf, size_t buf_len) { - assert(buf != NULL, "buffer is NULL!"); - assert(buf_len >= CPU_EBS_MAX_LENGTH, "buffer len should at least be == CPU_EBS_MAX_LENGTH!"); - assert(getCPUIDBrandString_stub != NULL, "not initialized"); - - // invoke newly generated asm code to fetch CPU Brand String - getCPUIDBrandString_stub(&_cpuid_info); - - // fetch results into buffer - *((uint32_t*) &buf[0]) = _cpuid_info.proc_name_0; - *((uint32_t*) &buf[4]) = _cpuid_info.proc_name_1; - *((uint32_t*) &buf[8]) = _cpuid_info.proc_name_2; - *((uint32_t*) &buf[12]) = _cpuid_info.proc_name_3; - *((uint32_t*) &buf[16]) = _cpuid_info.proc_name_4; - *((uint32_t*) &buf[20]) = _cpuid_info.proc_name_5; - *((uint32_t*) &buf[24]) = _cpuid_info.proc_name_6; - *((uint32_t*) &buf[28]) = _cpuid_info.proc_name_7; - *((uint32_t*) &buf[32]) = _cpuid_info.proc_name_8; - *((uint32_t*) &buf[36]) = _cpuid_info.proc_name_9; - *((uint32_t*) &buf[40]) = _cpuid_info.proc_name_10; - *((uint32_t*) &buf[44]) = _cpuid_info.proc_name_11; - - return OS_OK; -} - -size_t VM_Version_Ext::cpu_write_support_string(char* const buf, size_t buf_len) { - guarantee(buf != NULL, "buffer is NULL!"); - guarantee(buf_len > 0, "buffer len not enough!"); - - unsigned int flag = 0; - unsigned int fi = 0; - size_t written = 0; - const char* prefix = ""; - -#define WRITE_TO_BUF(string) \ - { \ - int res = jio_snprintf(&buf[written], buf_len - written, "%s%s", prefix, string); \ - if (res < 0) { \ - return buf_len - 1; \ - } \ - written += res; \ - if (prefix[0] == '\0') { \ - prefix = ", "; \ - } \ - } - - for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) { - if (flag == HTT_FLAG && (((_cpuid_info.std_cpuid1_ebx.value >> 16) & 0xff) <= 1)) { - continue; /* no hyperthreading */ - } else if (flag == SEP_FLAG && (cpu_family() == CPU_FAMILY_PENTIUMPRO && ((_cpuid_info.std_cpuid1_eax.value & 0xff) < 0x33))) { - continue; /* no fast system call */ - } - if ((_cpuid_info.std_cpuid1_edx.value & flag) && strlen(_feature_edx_id[fi]) > 0) { - WRITE_TO_BUF(_feature_edx_id[fi]); - } - } - - for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) { - if ((_cpuid_info.std_cpuid1_ecx.value & flag) && strlen(_feature_ecx_id[fi]) > 0) { - WRITE_TO_BUF(_feature_ecx_id[fi]); - } - } - - for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) { - if ((_cpuid_info.ext_cpuid1_ecx.value & flag) && strlen(_feature_extended_ecx_id[fi]) > 0) { - WRITE_TO_BUF(_feature_extended_ecx_id[fi]); - } - } - - for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) { - if ((_cpuid_info.ext_cpuid1_edx.value & flag) && strlen(_feature_extended_edx_id[fi]) > 0) { - WRITE_TO_BUF(_feature_extended_edx_id[fi]); - } - } - - if (supports_tscinv_bit()) { - WRITE_TO_BUF("Invariant TSC"); - } - - return written; -} - -/** - * Write a detailed description of the cpu to a given buffer, including - * feature set. - */ -int VM_Version_Ext::cpu_detailed_description(char* const buf, size_t buf_len) { - assert(buf != NULL, "buffer is NULL!"); - assert(buf_len >= CPU_DETAILED_DESC_BUF_SIZE, "buffer len should at least be == CPU_DETAILED_DESC_BUF_SIZE!"); - - static const char* unknown = ""; - char vendor_id[VENDOR_LENGTH]; - const char* family = NULL; - const char* model = NULL; - const char* brand = NULL; - int outputLen = 0; - - family = cpu_family_description(); - if (family == NULL) { - family = unknown; - } - - model = cpu_model_description(); - if (model == NULL) { - model = unknown; - } - - brand = cpu_brand_string(); - - if (brand == NULL) { - brand = cpu_brand(); - if (brand == NULL) { - brand = unknown; - } - } - - *((uint32_t*) &vendor_id[0]) = _cpuid_info.std_vendor_name_0; - *((uint32_t*) &vendor_id[4]) = _cpuid_info.std_vendor_name_2; - *((uint32_t*) &vendor_id[8]) = _cpuid_info.std_vendor_name_1; - vendor_id[VENDOR_LENGTH-1] = '\0'; - - outputLen = jio_snprintf(buf, buf_len, "Brand: %s, Vendor: %s\n" - "Family: %s (0x%x), Model: %s (0x%x), Stepping: 0x%x\n" - "Ext. family: 0x%x, Ext. model: 0x%x, Type: 0x%x, Signature: 0x%8.8x\n" - "Features: ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n" - "Ext. features: eax: 0x%8.8x, ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n" - "Supports: ", - brand, - vendor_id, - family, - extended_cpu_family(), - model, - extended_cpu_model(), - cpu_stepping(), - _cpuid_info.std_cpuid1_eax.bits.ext_family, - _cpuid_info.std_cpuid1_eax.bits.ext_model, - _cpuid_info.std_cpuid1_eax.bits.proc_type, - _cpuid_info.std_cpuid1_eax.value, - _cpuid_info.std_cpuid1_ebx.value, - _cpuid_info.std_cpuid1_ecx.value, - _cpuid_info.std_cpuid1_edx.value, - _cpuid_info.ext_cpuid1_eax, - _cpuid_info.ext_cpuid1_ebx, - _cpuid_info.ext_cpuid1_ecx, - _cpuid_info.ext_cpuid1_edx); - - if (outputLen < 0 || (size_t) outputLen >= buf_len - 1) { - if (buf_len > 0) { buf[buf_len-1] = '\0'; } - return OS_ERR; - } - - cpu_write_support_string(&buf[outputLen], buf_len - outputLen); - - return OS_OK; -} - -const char* VM_Version_Ext::cpu_name(void) { - char cpu_type_desc[CPU_TYPE_DESC_BUF_SIZE]; - size_t cpu_desc_len = sizeof(cpu_type_desc); - - cpu_type_description(cpu_type_desc, cpu_desc_len); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, cpu_desc_len, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, cpu_type_desc, cpu_desc_len); - return tmp; -} - -const char* VM_Version_Ext::cpu_description(void) { - char cpu_detailed_desc_buffer[CPU_DETAILED_DESC_BUF_SIZE]; - size_t cpu_detailed_desc_len = sizeof(cpu_detailed_desc_buffer); - - cpu_detailed_description(cpu_detailed_desc_buffer, cpu_detailed_desc_len); - - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, cpu_detailed_desc_len, mtTracing); - - if (NULL == tmp) { - return NULL; - } - - strncpy(tmp, cpu_detailed_desc_buffer, cpu_detailed_desc_len); - return tmp; -} - -/** - * For information about extracting the frequency from the cpu brand string, please see: - * - * Intel Processor Identification and the CPUID Instruction - * Application Note 485 - * May 2012 - * - * The return value is the frequency in Hz. - */ -int64_t VM_Version_Ext::max_qualified_cpu_freq_from_brand_string(void) { - const char* const brand_string = cpu_brand_string(); - if (brand_string == NULL) { - return 0; - } - const int64_t MEGA = 1000000; - int64_t multiplier = 0; - int64_t frequency = 0; - uint8_t idx = 0; - // The brand string buffer is at most 48 bytes. - // -2 is to prevent buffer overrun when looking for y in yHz, as z is +2 from y. - for (; idx < 48-2; ++idx) { - // Format is either "x.xxyHz" or "xxxxyHz", where y=M, G, T and x are digits. - // Search brand string for "yHz" where y is M, G, or T. - if (brand_string[idx+1] == 'H' && brand_string[idx+2] == 'z') { - if (brand_string[idx] == 'M') { - multiplier = MEGA; - } else if (brand_string[idx] == 'G') { - multiplier = MEGA * 1000; - } else if (brand_string[idx] == 'T') { - multiplier = MEGA * MEGA; - } - break; - } - } - if (multiplier > 0) { - // Compute freqency (in Hz) from brand string. - if (brand_string[idx-3] == '.') { // if format is "x.xx" - frequency = (brand_string[idx-4] - '0') * multiplier; - frequency += (brand_string[idx-2] - '0') * multiplier / 10; - frequency += (brand_string[idx-1] - '0') * multiplier / 100; - } else { // format is "xxxx" - frequency = (brand_string[idx-4] - '0') * 1000; - frequency += (brand_string[idx-3] - '0') * 100; - frequency += (brand_string[idx-2] - '0') * 10; - frequency += (brand_string[idx-1] - '0'); - frequency *= multiplier; - } - } - return frequency; -} - - -int64_t VM_Version_Ext::maximum_qualified_cpu_frequency(void) { - if (_max_qualified_cpu_frequency == 0) { - _max_qualified_cpu_frequency = max_qualified_cpu_freq_from_brand_string(); - } - return _max_qualified_cpu_frequency; -} - -const char* const VM_Version_Ext::_family_id_intel[ExtendedFamilyIdLength_INTEL] = { - "8086/8088", - "", - "286", - "386", - "486", - "Pentium", - "Pentium Pro", //or Pentium-M/Woodcrest depeding on model - "", - "", - "", - "", - "", - "", - "", - "", - "Pentium 4" -}; - -const char* const VM_Version_Ext::_family_id_amd[ExtendedFamilyIdLength_AMD] = { - "", - "", - "", - "", - "5x86", - "K5/K6", - "Athlon/AthlonXP", - "", - "", - "", - "", - "", - "", - "", - "", - "Opteron/Athlon64", - "Opteron QC/Phenom", // Barcelona et.al. - "", - "", - "", - "", - "", - "", - "Zen" -}; -// Partially from Intel 64 and IA-32 Architecture Software Developer's Manual, -// September 2013, Vol 3C Table 35-1 -const char* const VM_Version_Ext::_model_id_pentium_pro[] = { - "", - "Pentium Pro", - "", - "Pentium II model 3", - "", - "Pentium II model 5/Xeon/Celeron", - "Celeron", - "Pentium III/Pentium III Xeon", - "Pentium III/Pentium III Xeon", - "Pentium M model 9", // Yonah - "Pentium III, model A", - "Pentium III, model B", - "", - "Pentium M model D", // Dothan - "", - "Core 2", // 0xf Woodcrest/Conroe/Merom/Kentsfield/Clovertown - "", - "", - "", - "", - "", - "", - "Celeron", // 0x16 Celeron 65nm - "Core 2", // 0x17 Penryn / Harpertown - "", - "", - "Core i7", // 0x1A CPU_MODEL_NEHALEM_EP - "Atom", // 0x1B Z5xx series Silverthorn - "", - "Core 2", // 0x1D Dunnington (6-core) - "Nehalem", // 0x1E CPU_MODEL_NEHALEM - "", - "", - "", - "", - "", - "", - "Westmere", // 0x25 CPU_MODEL_WESTMERE - "", - "", - "", // 0x28 - "", - "Sandy Bridge", // 0x2a "2nd Generation Intel Core i7, i5, i3" - "", - "Westmere-EP", // 0x2c CPU_MODEL_WESTMERE_EP - "Sandy Bridge-EP", // 0x2d CPU_MODEL_SANDYBRIDGE_EP - "Nehalem-EX", // 0x2e CPU_MODEL_NEHALEM_EX - "Westmere-EX", // 0x2f CPU_MODEL_WESTMERE_EX - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "Ivy Bridge", // 0x3a - "", - "Haswell", // 0x3c "4th Generation Intel Core Processor" - "", // 0x3d "Next Generation Intel Core Processor" - "Ivy Bridge-EP", // 0x3e "Next Generation Intel Xeon Processor E7 Family" - "", // 0x3f "Future Generation Intel Xeon Processor" - "", - "", - "", - "", - "", - "Haswell", // 0x45 "4th Generation Intel Core Processor" - "Haswell", // 0x46 "4th Generation Intel Core Processor" - NULL -}; - -/* Brand ID is for back compability - * Newer CPUs uses the extended brand string */ -const char* const VM_Version_Ext::_brand_id[] = { - "", - "Celeron processor", - "Pentium III processor", - "Intel Pentium III Xeon processor", - "", - "", - "", - "", - "Intel Pentium 4 processor", - NULL -}; - - -const char* const VM_Version_Ext::_feature_edx_id[] = { - "On-Chip FPU", - "Virtual Mode Extensions", - "Debugging Extensions", - "Page Size Extensions", - "Time Stamp Counter", - "Model Specific Registers", - "Physical Address Extension", - "Machine Check Exceptions", - "CMPXCHG8B Instruction", - "On-Chip APIC", - "", - "Fast System Call", - "Memory Type Range Registers", - "Page Global Enable", - "Machine Check Architecture", - "Conditional Mov Instruction", - "Page Attribute Table", - "36-bit Page Size Extension", - "Processor Serial Number", - "CLFLUSH Instruction", - "", - "Debug Trace Store feature", - "ACPI registers in MSR space", - "Intel Architecture MMX Technology", - "Fast Float Point Save and Restore", - "Streaming SIMD extensions", - "Streaming SIMD extensions 2", - "Self-Snoop", - "Hyper Threading", - "Thermal Monitor", - "", - "Pending Break Enable" -}; - -const char* const VM_Version_Ext::_feature_extended_edx_id[] = { - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "SYSCALL/SYSRET", - "", - "", - "", - "", - "", - "", - "", - "", - "Execute Disable Bit", - "", - "", - "", - "", - "", - "", - "RDTSCP", - "", - "Intel 64 Architecture", - "", - "" -}; - -const char* const VM_Version_Ext::_feature_ecx_id[] = { - "Streaming SIMD Extensions 3", - "PCLMULQDQ", - "64-bit DS Area", - "MONITOR/MWAIT instructions", - "CPL Qualified Debug Store", - "Virtual Machine Extensions", - "Safer Mode Extensions", - "Enhanced Intel SpeedStep technology", - "Thermal Monitor 2", - "Supplemental Streaming SIMD Extensions 3", - "L1 Context ID", - "", - "Fused Multiply-Add", - "CMPXCHG16B", - "xTPR Update Control", - "Perfmon and Debug Capability", - "", - "Process-context identifiers", - "Direct Cache Access", - "Streaming SIMD extensions 4.1", - "Streaming SIMD extensions 4.2", - "x2APIC", - "MOVBE", - "Popcount instruction", - "TSC-Deadline", - "AESNI", - "XSAVE", - "OSXSAVE", - "AVX", - "F16C", - "RDRAND", - "" -}; - -const char* const VM_Version_Ext::_feature_extended_ecx_id[] = { - "LAHF/SAHF instruction support", - "Core multi-processor legacy mode", - "", - "", - "", - "Advanced Bit Manipulations: LZCNT", - "SSE4A: MOVNTSS, MOVNTSD, EXTRQ, INSERTQ", - "Misaligned SSE mode", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" -}; diff --git a/src/hotspot/cpu/x86/vm_version_ext_x86.hpp b/src/hotspot/cpu/x86/vm_version_ext_x86.hpp deleted file mode 100644 index c81ebead23ca52d0a4691529cccc898292fa4358..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/x86/vm_version_ext_x86.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_X86_VM_VERSION_EXT_X86_HPP -#define CPU_X86_VM_VERSION_EXT_X86_HPP - -#include "runtime/vm_version.hpp" -#include "utilities/macros.hpp" -#include "utilities/sizes.hpp" - -class VM_Version_Ext : public VM_Version { - - enum { - ExtendedFamilyIdLength_INTEL = 16, - ExtendedFamilyIdLength_AMD = 24 - }; - - private: - static const size_t VENDOR_LENGTH; - static const size_t CPU_EBS_MAX_LENGTH; - static const size_t CPU_TYPE_DESC_BUF_SIZE; - static const size_t CPU_DETAILED_DESC_BUF_SIZE; - - static const char* const _family_id_intel[ExtendedFamilyIdLength_INTEL]; - static const char* const _family_id_amd[ExtendedFamilyIdLength_AMD]; - static const char* const _brand_id[]; - static const char* const _model_id_pentium_pro[]; - - static const char* const _feature_edx_id[]; - static const char* const _feature_extended_edx_id[]; - static const char* const _feature_ecx_id[]; - static const char* const _feature_extended_ecx_id[]; - - static int _no_of_threads; - static int _no_of_cores; - static int _no_of_packages; - static char* _cpu_brand_string; - static int64_t _max_qualified_cpu_frequency; - - static const char* cpu_family_description(void); - static const char* cpu_model_description(void); - static const char* cpu_brand(void); - static const char* cpu_brand_string(void); - - static int cpu_type_description(char* const buf, size_t buf_len); - static int cpu_detailed_description(char* const buf, size_t buf_len); - static int cpu_extended_brand_string(char* const buf, size_t buf_len); - - static bool cpu_is_em64t(void); - static bool is_netburst(void); - - // Returns bytes written excluding termninating null byte. - static size_t cpu_write_support_string(char* const buf, size_t buf_len); - static void resolve_cpu_information_details(void); - static int64_t max_qualified_cpu_freq_from_brand_string(void); - - public: - // Offsets for cpuid asm stub brand string - static ByteSize proc_name_0_offset() { return byte_offset_of(CpuidInfo, proc_name_0); } - static ByteSize proc_name_1_offset() { return byte_offset_of(CpuidInfo, proc_name_1); } - static ByteSize proc_name_2_offset() { return byte_offset_of(CpuidInfo, proc_name_2); } - static ByteSize proc_name_3_offset() { return byte_offset_of(CpuidInfo, proc_name_3); } - static ByteSize proc_name_4_offset() { return byte_offset_of(CpuidInfo, proc_name_4); } - static ByteSize proc_name_5_offset() { return byte_offset_of(CpuidInfo, proc_name_5); } - static ByteSize proc_name_6_offset() { return byte_offset_of(CpuidInfo, proc_name_6); } - static ByteSize proc_name_7_offset() { return byte_offset_of(CpuidInfo, proc_name_7); } - static ByteSize proc_name_8_offset() { return byte_offset_of(CpuidInfo, proc_name_8); } - static ByteSize proc_name_9_offset() { return byte_offset_of(CpuidInfo, proc_name_9); } - static ByteSize proc_name_10_offset() { return byte_offset_of(CpuidInfo, proc_name_10); } - static ByteSize proc_name_11_offset() { return byte_offset_of(CpuidInfo, proc_name_11); } - - static int number_of_threads(void); - static int number_of_cores(void); - static int number_of_sockets(void); - - static int64_t maximum_qualified_cpu_frequency(void); - - static bool supports_tscinv_ext(void); - - static const char* cpu_name(void); - static const char* cpu_description(void); - - static void initialize(); -}; - -#endif // CPU_X86_VM_VERSION_EXT_X86_HPP diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index e20a1c2bae1ca2dc3f57958932de071bae39bf3f..93613850a5e299c819486e1b953bfba250a80961 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -83,6 +83,19 @@ bool VM_Version::supports_clflush() { } #endif +#define CPUID_STANDARD_FN 0x0 +#define CPUID_STANDARD_FN_1 0x1 +#define CPUID_STANDARD_FN_4 0x4 +#define CPUID_STANDARD_FN_B 0xb + +#define CPUID_EXTENDED_FN 0x80000000 +#define CPUID_EXTENDED_FN_1 0x80000001 +#define CPUID_EXTENDED_FN_2 0x80000002 +#define CPUID_EXTENDED_FN_3 0x80000003 +#define CPUID_EXTENDED_FN_4 0x80000004 +#define CPUID_EXTENDED_FN_7 0x80000007 +#define CPUID_EXTENDED_FN_8 0x80000008 + class VM_Version_StubGenerator: public StubCodeGenerator { public: @@ -626,6 +639,149 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ pop(rbp); __ ret(0); +# undef __ + + return start; + }; + + + address generate_getCPUIDBrandString(void) { + // Flags to test CPU type. + const uint32_t HS_EFL_AC = 0x40000; + const uint32_t HS_EFL_ID = 0x200000; + // Values for when we don't have a CPUID instruction. + const int CPU_FAMILY_SHIFT = 8; + const uint32_t CPU_FAMILY_386 = (3 << CPU_FAMILY_SHIFT); + const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT); + + Label detect_486, cpu486, detect_586, done, ext_cpuid; + + StubCodeMark mark(this, "VM_Version", "getCPUIDNameInfo_stub"); +# define __ _masm-> + + address start = __ pc(); + + // + // void getCPUIDBrandString(VM_Version::CpuidInfo* cpuid_info); + // + // LP64: rcx and rdx are first and second argument registers on windows + + __ push(rbp); +#ifdef _LP64 + __ mov(rbp, c_rarg0); // cpuid_info address +#else + __ movptr(rbp, Address(rsp, 8)); // cpuid_info address +#endif + __ push(rbx); + __ push(rsi); + __ pushf(); // preserve rbx, and flags + __ pop(rax); + __ push(rax); + __ mov(rcx, rax); + // + // if we are unable to change the AC flag, we have a 386 + // + __ xorl(rax, HS_EFL_AC); + __ push(rax); + __ popf(); + __ pushf(); + __ pop(rax); + __ cmpptr(rax, rcx); + __ jccb(Assembler::notEqual, detect_486); + + __ movl(rax, CPU_FAMILY_386); + __ jmp(done); + + // + // If we are unable to change the ID flag, we have a 486 which does + // not support the "cpuid" instruction. + // + __ bind(detect_486); + __ mov(rax, rcx); + __ xorl(rax, HS_EFL_ID); + __ push(rax); + __ popf(); + __ pushf(); + __ pop(rax); + __ cmpptr(rcx, rax); + __ jccb(Assembler::notEqual, detect_586); + + __ bind(cpu486); + __ movl(rax, CPU_FAMILY_486); + __ jmp(done); + + // + // At this point, we have a chip which supports the "cpuid" instruction + // + __ bind(detect_586); + __ xorl(rax, rax); + __ cpuid(); + __ orl(rax, rax); + __ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input + // value of at least 1, we give up and + // assume a 486 + + // + // Extended cpuid(0x80000000) for processor brand string detection + // + __ bind(ext_cpuid); + __ movl(rax, CPUID_EXTENDED_FN); + __ cpuid(); + __ cmpl(rax, CPUID_EXTENDED_FN_4); + __ jcc(Assembler::below, done); + + // + // Extended cpuid(0x80000002) // first 16 bytes in brand string + // + __ movl(rax, CPUID_EXTENDED_FN_2); + __ cpuid(); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_0_offset()))); + __ movl(Address(rsi, 0), rax); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_1_offset()))); + __ movl(Address(rsi, 0), rbx); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_2_offset()))); + __ movl(Address(rsi, 0), rcx); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_3_offset()))); + __ movl(Address(rsi,0), rdx); + + // + // Extended cpuid(0x80000003) // next 16 bytes in brand string + // + __ movl(rax, CPUID_EXTENDED_FN_3); + __ cpuid(); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_4_offset()))); + __ movl(Address(rsi, 0), rax); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_5_offset()))); + __ movl(Address(rsi, 0), rbx); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_6_offset()))); + __ movl(Address(rsi, 0), rcx); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_7_offset()))); + __ movl(Address(rsi,0), rdx); + + // + // Extended cpuid(0x80000004) // last 16 bytes in brand string + // + __ movl(rax, CPUID_EXTENDED_FN_4); + __ cpuid(); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_8_offset()))); + __ movl(Address(rsi, 0), rax); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_9_offset()))); + __ movl(Address(rsi, 0), rbx); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_10_offset()))); + __ movl(Address(rsi, 0), rcx); + __ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_11_offset()))); + __ movl(Address(rsi,0), rdx); + + // + // return + // + __ bind(done); + __ popf(); + __ pop(rsi); + __ pop(rbx); + __ pop(rbp); + __ ret(0); + # undef __ return start; @@ -1889,6 +2045,8 @@ int VM_Version::avx3_threshold() { FLAG_IS_DEFAULT(AVX3Threshold)) ? 0 : AVX3Threshold; } +static bool _vm_version_initialized = false; + void VM_Version::initialize() { ResourceMark rm; // Making this stub must be FIRST use of assembler @@ -1911,4 +2069,757 @@ void VM_Version::initialize() { if (VM_Version::supports_hv()) { // Supports hypervisor check_virtualizations(); } + _vm_version_initialized = true; +} + +typedef enum { + CPU_FAMILY_8086_8088 = 0, + CPU_FAMILY_INTEL_286 = 2, + CPU_FAMILY_INTEL_386 = 3, + CPU_FAMILY_INTEL_486 = 4, + CPU_FAMILY_PENTIUM = 5, + CPU_FAMILY_PENTIUMPRO = 6, // Same family several models + CPU_FAMILY_PENTIUM_4 = 0xF +} FamilyFlag; + +typedef enum { + RDTSCP_FLAG = 0x08000000, // bit 27 + INTEL64_FLAG = 0x20000000 // bit 29 +} _featureExtendedEdxFlag; + +typedef enum { + FPU_FLAG = 0x00000001, + VME_FLAG = 0x00000002, + DE_FLAG = 0x00000004, + PSE_FLAG = 0x00000008, + TSC_FLAG = 0x00000010, + MSR_FLAG = 0x00000020, + PAE_FLAG = 0x00000040, + MCE_FLAG = 0x00000080, + CX8_FLAG = 0x00000100, + APIC_FLAG = 0x00000200, + SEP_FLAG = 0x00000800, + MTRR_FLAG = 0x00001000, + PGE_FLAG = 0x00002000, + MCA_FLAG = 0x00004000, + CMOV_FLAG = 0x00008000, + PAT_FLAG = 0x00010000, + PSE36_FLAG = 0x00020000, + PSNUM_FLAG = 0x00040000, + CLFLUSH_FLAG = 0x00080000, + DTS_FLAG = 0x00200000, + ACPI_FLAG = 0x00400000, + MMX_FLAG = 0x00800000, + FXSR_FLAG = 0x01000000, + SSE_FLAG = 0x02000000, + SSE2_FLAG = 0x04000000, + SS_FLAG = 0x08000000, + HTT_FLAG = 0x10000000, + TM_FLAG = 0x20000000 +} FeatureEdxFlag; + +static BufferBlob* cpuid_brand_string_stub_blob; +static const int cpuid_brand_string_stub_size = 550; + +extern "C" { + typedef void (*getCPUIDBrandString_stub_t)(void*); +} + +static getCPUIDBrandString_stub_t getCPUIDBrandString_stub = NULL; + +// VM_Version statics +enum { + ExtendedFamilyIdLength_INTEL = 16, + ExtendedFamilyIdLength_AMD = 24 +}; + +const size_t VENDOR_LENGTH = 13; +const size_t CPU_EBS_MAX_LENGTH = (3 * 4 * 4 + 1); +static char* _cpu_brand_string = NULL; +static int64_t _max_qualified_cpu_frequency = 0; + +static int _no_of_threads = 0; +static int _no_of_cores = 0; + +const char* const _family_id_intel[ExtendedFamilyIdLength_INTEL] = { + "8086/8088", + "", + "286", + "386", + "486", + "Pentium", + "Pentium Pro", //or Pentium-M/Woodcrest depeding on model + "", + "", + "", + "", + "", + "", + "", + "", + "Pentium 4" +}; + +const char* const _family_id_amd[ExtendedFamilyIdLength_AMD] = { + "", + "", + "", + "", + "5x86", + "K5/K6", + "Athlon/AthlonXP", + "", + "", + "", + "", + "", + "", + "", + "", + "Opteron/Athlon64", + "Opteron QC/Phenom", // Barcelona et.al. + "", + "", + "", + "", + "", + "", + "Zen" +}; +// Partially from Intel 64 and IA-32 Architecture Software Developer's Manual, +// September 2013, Vol 3C Table 35-1 +const char* const _model_id_pentium_pro[] = { + "", + "Pentium Pro", + "", + "Pentium II model 3", + "", + "Pentium II model 5/Xeon/Celeron", + "Celeron", + "Pentium III/Pentium III Xeon", + "Pentium III/Pentium III Xeon", + "Pentium M model 9", // Yonah + "Pentium III, model A", + "Pentium III, model B", + "", + "Pentium M model D", // Dothan + "", + "Core 2", // 0xf Woodcrest/Conroe/Merom/Kentsfield/Clovertown + "", + "", + "", + "", + "", + "", + "Celeron", // 0x16 Celeron 65nm + "Core 2", // 0x17 Penryn / Harpertown + "", + "", + "Core i7", // 0x1A CPU_MODEL_NEHALEM_EP + "Atom", // 0x1B Z5xx series Silverthorn + "", + "Core 2", // 0x1D Dunnington (6-core) + "Nehalem", // 0x1E CPU_MODEL_NEHALEM + "", + "", + "", + "", + "", + "", + "Westmere", // 0x25 CPU_MODEL_WESTMERE + "", + "", + "", // 0x28 + "", + "Sandy Bridge", // 0x2a "2nd Generation Intel Core i7, i5, i3" + "", + "Westmere-EP", // 0x2c CPU_MODEL_WESTMERE_EP + "Sandy Bridge-EP", // 0x2d CPU_MODEL_SANDYBRIDGE_EP + "Nehalem-EX", // 0x2e CPU_MODEL_NEHALEM_EX + "Westmere-EX", // 0x2f CPU_MODEL_WESTMERE_EX + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "Ivy Bridge", // 0x3a + "", + "Haswell", // 0x3c "4th Generation Intel Core Processor" + "", // 0x3d "Next Generation Intel Core Processor" + "Ivy Bridge-EP", // 0x3e "Next Generation Intel Xeon Processor E7 Family" + "", // 0x3f "Future Generation Intel Xeon Processor" + "", + "", + "", + "", + "", + "Haswell", // 0x45 "4th Generation Intel Core Processor" + "Haswell", // 0x46 "4th Generation Intel Core Processor" + NULL +}; + +/* Brand ID is for back compability + * Newer CPUs uses the extended brand string */ +const char* const _brand_id[] = { + "", + "Celeron processor", + "Pentium III processor", + "Intel Pentium III Xeon processor", + "", + "", + "", + "", + "Intel Pentium 4 processor", + NULL +}; + + +const char* const _feature_edx_id[] = { + "On-Chip FPU", + "Virtual Mode Extensions", + "Debugging Extensions", + "Page Size Extensions", + "Time Stamp Counter", + "Model Specific Registers", + "Physical Address Extension", + "Machine Check Exceptions", + "CMPXCHG8B Instruction", + "On-Chip APIC", + "", + "Fast System Call", + "Memory Type Range Registers", + "Page Global Enable", + "Machine Check Architecture", + "Conditional Mov Instruction", + "Page Attribute Table", + "36-bit Page Size Extension", + "Processor Serial Number", + "CLFLUSH Instruction", + "", + "Debug Trace Store feature", + "ACPI registers in MSR space", + "Intel Architecture MMX Technology", + "Fast Float Point Save and Restore", + "Streaming SIMD extensions", + "Streaming SIMD extensions 2", + "Self-Snoop", + "Hyper Threading", + "Thermal Monitor", + "", + "Pending Break Enable" +}; + +const char* const _feature_extended_edx_id[] = { + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "SYSCALL/SYSRET", + "", + "", + "", + "", + "", + "", + "", + "", + "Execute Disable Bit", + "", + "", + "", + "", + "", + "", + "RDTSCP", + "", + "Intel 64 Architecture", + "", + "" +}; + +const char* const _feature_ecx_id[] = { + "Streaming SIMD Extensions 3", + "PCLMULQDQ", + "64-bit DS Area", + "MONITOR/MWAIT instructions", + "CPL Qualified Debug Store", + "Virtual Machine Extensions", + "Safer Mode Extensions", + "Enhanced Intel SpeedStep technology", + "Thermal Monitor 2", + "Supplemental Streaming SIMD Extensions 3", + "L1 Context ID", + "", + "Fused Multiply-Add", + "CMPXCHG16B", + "xTPR Update Control", + "Perfmon and Debug Capability", + "", + "Process-context identifiers", + "Direct Cache Access", + "Streaming SIMD extensions 4.1", + "Streaming SIMD extensions 4.2", + "x2APIC", + "MOVBE", + "Popcount instruction", + "TSC-Deadline", + "AESNI", + "XSAVE", + "OSXSAVE", + "AVX", + "F16C", + "RDRAND", + "" +}; + +const char* const _feature_extended_ecx_id[] = { + "LAHF/SAHF instruction support", + "Core multi-processor legacy mode", + "", + "", + "", + "Advanced Bit Manipulations: LZCNT", + "SSE4A: MOVNTSS, MOVNTSD, EXTRQ, INSERTQ", + "Misaligned SSE mode", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" +}; + +void VM_Version::initialize_tsc(void) { + ResourceMark rm; + + cpuid_brand_string_stub_blob = BufferBlob::create("getCPUIDBrandString_stub", cpuid_brand_string_stub_size); + if (cpuid_brand_string_stub_blob == NULL) { + vm_exit_during_initialization("Unable to allocate getCPUIDBrandString_stub"); + } + CodeBuffer c(cpuid_brand_string_stub_blob); + VM_Version_StubGenerator g(&c); + getCPUIDBrandString_stub = CAST_TO_FN_PTR(getCPUIDBrandString_stub_t, + g.generate_getCPUIDBrandString()); +} + +const char* VM_Version::cpu_model_description(void) { + uint32_t cpu_family = extended_cpu_family(); + uint32_t cpu_model = extended_cpu_model(); + const char* model = NULL; + + if (cpu_family == CPU_FAMILY_PENTIUMPRO) { + for (uint32_t i = 0; i <= cpu_model; i++) { + model = _model_id_pentium_pro[i]; + if (model == NULL) { + break; + } + } + } + return model; } + +const char* VM_Version::cpu_brand_string(void) { + if (_cpu_brand_string == NULL) { + _cpu_brand_string = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_EBS_MAX_LENGTH, mtInternal); + if (NULL == _cpu_brand_string) { + return NULL; + } + int ret_val = cpu_extended_brand_string(_cpu_brand_string, CPU_EBS_MAX_LENGTH); + if (ret_val != OS_OK) { + FREE_C_HEAP_ARRAY(char, _cpu_brand_string); + _cpu_brand_string = NULL; + } + } + return _cpu_brand_string; +} + +const char* VM_Version::cpu_brand(void) { + const char* brand = NULL; + + if ((_cpuid_info.std_cpuid1_ebx.value & 0xFF) > 0) { + int brand_num = _cpuid_info.std_cpuid1_ebx.value & 0xFF; + brand = _brand_id[0]; + for (int i = 0; brand != NULL && i <= brand_num; i += 1) { + brand = _brand_id[i]; + } + } + return brand; +} + +bool VM_Version::cpu_is_em64t(void) { + return ((_cpuid_info.ext_cpuid1_edx.value & INTEL64_FLAG) == INTEL64_FLAG); +} + +bool VM_Version::is_netburst(void) { + return (is_intel() && (extended_cpu_family() == CPU_FAMILY_PENTIUM_4)); +} + +bool VM_Version::supports_tscinv_ext(void) { + if (!supports_tscinv_bit()) { + return false; + } + + if (is_intel()) { + return true; + } + + if (is_amd()) { + return !is_amd_Barcelona(); + } + + if (is_hygon()) { + return true; + } + + return false; +} + +void VM_Version::resolve_cpu_information_details(void) { + + // in future we want to base this information on proper cpu + // and cache topology enumeration such as: + // Intel 64 Architecture Processor Topology Enumeration + // which supports system cpu and cache topology enumeration + // either using 2xAPICIDs or initial APICIDs + + // currently only rough cpu information estimates + // which will not necessarily reflect the exact configuration of the system + + // this is the number of logical hardware threads + // visible to the operating system + _no_of_threads = os::processor_count(); + + // find out number of threads per cpu package + int threads_per_package = threads_per_core() * cores_per_cpu(); + + // use amount of threads visible to the process in order to guess number of sockets + _no_of_sockets = _no_of_threads / threads_per_package; + + // process might only see a subset of the total number of threads + // from a single processor package. Virtualization/resource management for example. + // If so then just write a hard 1 as num of pkgs. + if (0 == _no_of_sockets) { + _no_of_sockets = 1; + } + + // estimate the number of cores + _no_of_cores = cores_per_cpu() * _no_of_sockets; +} + + +const char* VM_Version::cpu_family_description(void) { + int cpu_family_id = extended_cpu_family(); + if (is_amd()) { + if (cpu_family_id < ExtendedFamilyIdLength_AMD) { + return _family_id_amd[cpu_family_id]; + } + } + if (is_intel()) { + if (cpu_family_id == CPU_FAMILY_PENTIUMPRO) { + return cpu_model_description(); + } + if (cpu_family_id < ExtendedFamilyIdLength_INTEL) { + return _family_id_intel[cpu_family_id]; + } + } + if (is_hygon()) { + return "Dhyana"; + } + return "Unknown x86"; +} + +int VM_Version::cpu_type_description(char* const buf, size_t buf_len) { + assert(buf != NULL, "buffer is NULL!"); + assert(buf_len >= CPU_TYPE_DESC_BUF_SIZE, "buffer len should at least be == CPU_TYPE_DESC_BUF_SIZE!"); + + const char* cpu_type = NULL; + const char* x64 = NULL; + + if (is_intel()) { + cpu_type = "Intel"; + x64 = cpu_is_em64t() ? " Intel64" : ""; + } else if (is_amd()) { + cpu_type = "AMD"; + x64 = cpu_is_em64t() ? " AMD64" : ""; + } else if (is_hygon()) { + cpu_type = "Hygon"; + x64 = cpu_is_em64t() ? " AMD64" : ""; + } else { + cpu_type = "Unknown x86"; + x64 = cpu_is_em64t() ? " x86_64" : ""; + } + + jio_snprintf(buf, buf_len, "%s %s%s SSE SSE2%s%s%s%s%s%s%s%s", + cpu_type, + cpu_family_description(), + supports_ht() ? " (HT)" : "", + supports_sse3() ? " SSE3" : "", + supports_ssse3() ? " SSSE3" : "", + supports_sse4_1() ? " SSE4.1" : "", + supports_sse4_2() ? " SSE4.2" : "", + supports_sse4a() ? " SSE4A" : "", + is_netburst() ? " Netburst" : "", + is_intel_family_core() ? " Core" : "", + x64); + + return OS_OK; +} + +int VM_Version::cpu_extended_brand_string(char* const buf, size_t buf_len) { + assert(buf != NULL, "buffer is NULL!"); + assert(buf_len >= CPU_EBS_MAX_LENGTH, "buffer len should at least be == CPU_EBS_MAX_LENGTH!"); + assert(getCPUIDBrandString_stub != NULL, "not initialized"); + + // invoke newly generated asm code to fetch CPU Brand String + getCPUIDBrandString_stub(&_cpuid_info); + + // fetch results into buffer + *((uint32_t*) &buf[0]) = _cpuid_info.proc_name_0; + *((uint32_t*) &buf[4]) = _cpuid_info.proc_name_1; + *((uint32_t*) &buf[8]) = _cpuid_info.proc_name_2; + *((uint32_t*) &buf[12]) = _cpuid_info.proc_name_3; + *((uint32_t*) &buf[16]) = _cpuid_info.proc_name_4; + *((uint32_t*) &buf[20]) = _cpuid_info.proc_name_5; + *((uint32_t*) &buf[24]) = _cpuid_info.proc_name_6; + *((uint32_t*) &buf[28]) = _cpuid_info.proc_name_7; + *((uint32_t*) &buf[32]) = _cpuid_info.proc_name_8; + *((uint32_t*) &buf[36]) = _cpuid_info.proc_name_9; + *((uint32_t*) &buf[40]) = _cpuid_info.proc_name_10; + *((uint32_t*) &buf[44]) = _cpuid_info.proc_name_11; + + return OS_OK; +} + +size_t VM_Version::cpu_write_support_string(char* const buf, size_t buf_len) { + guarantee(buf != NULL, "buffer is NULL!"); + guarantee(buf_len > 0, "buffer len not enough!"); + + unsigned int flag = 0; + unsigned int fi = 0; + size_t written = 0; + const char* prefix = ""; + +#define WRITE_TO_BUF(string) \ + { \ + int res = jio_snprintf(&buf[written], buf_len - written, "%s%s", prefix, string); \ + if (res < 0) { \ + return buf_len - 1; \ + } \ + written += res; \ + if (prefix[0] == '\0') { \ + prefix = ", "; \ + } \ + } + + for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) { + if (flag == HTT_FLAG && (((_cpuid_info.std_cpuid1_ebx.value >> 16) & 0xff) <= 1)) { + continue; /* no hyperthreading */ + } else if (flag == SEP_FLAG && (cpu_family() == CPU_FAMILY_PENTIUMPRO && ((_cpuid_info.std_cpuid1_eax.value & 0xff) < 0x33))) { + continue; /* no fast system call */ + } + if ((_cpuid_info.std_cpuid1_edx.value & flag) && strlen(_feature_edx_id[fi]) > 0) { + WRITE_TO_BUF(_feature_edx_id[fi]); + } + } + + for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) { + if ((_cpuid_info.std_cpuid1_ecx.value & flag) && strlen(_feature_ecx_id[fi]) > 0) { + WRITE_TO_BUF(_feature_ecx_id[fi]); + } + } + + for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) { + if ((_cpuid_info.ext_cpuid1_ecx.value & flag) && strlen(_feature_extended_ecx_id[fi]) > 0) { + WRITE_TO_BUF(_feature_extended_ecx_id[fi]); + } + } + + for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) { + if ((_cpuid_info.ext_cpuid1_edx.value & flag) && strlen(_feature_extended_edx_id[fi]) > 0) { + WRITE_TO_BUF(_feature_extended_edx_id[fi]); + } + } + + if (supports_tscinv_bit()) { + WRITE_TO_BUF("Invariant TSC"); + } + + return written; +} + +/** + * Write a detailed description of the cpu to a given buffer, including + * feature set. + */ +int VM_Version::cpu_detailed_description(char* const buf, size_t buf_len) { + assert(buf != NULL, "buffer is NULL!"); + assert(buf_len >= CPU_DETAILED_DESC_BUF_SIZE, "buffer len should at least be == CPU_DETAILED_DESC_BUF_SIZE!"); + + static const char* unknown = ""; + char vendor_id[VENDOR_LENGTH]; + const char* family = NULL; + const char* model = NULL; + const char* brand = NULL; + int outputLen = 0; + + family = cpu_family_description(); + if (family == NULL) { + family = unknown; + } + + model = cpu_model_description(); + if (model == NULL) { + model = unknown; + } + + brand = cpu_brand_string(); + + if (brand == NULL) { + brand = cpu_brand(); + if (brand == NULL) { + brand = unknown; + } + } + + *((uint32_t*) &vendor_id[0]) = _cpuid_info.std_vendor_name_0; + *((uint32_t*) &vendor_id[4]) = _cpuid_info.std_vendor_name_2; + *((uint32_t*) &vendor_id[8]) = _cpuid_info.std_vendor_name_1; + vendor_id[VENDOR_LENGTH-1] = '\0'; + + outputLen = jio_snprintf(buf, buf_len, "Brand: %s, Vendor: %s\n" + "Family: %s (0x%x), Model: %s (0x%x), Stepping: 0x%x\n" + "Ext. family: 0x%x, Ext. model: 0x%x, Type: 0x%x, Signature: 0x%8.8x\n" + "Features: ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n" + "Ext. features: eax: 0x%8.8x, ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n" + "Supports: ", + brand, + vendor_id, + family, + extended_cpu_family(), + model, + extended_cpu_model(), + cpu_stepping(), + _cpuid_info.std_cpuid1_eax.bits.ext_family, + _cpuid_info.std_cpuid1_eax.bits.ext_model, + _cpuid_info.std_cpuid1_eax.bits.proc_type, + _cpuid_info.std_cpuid1_eax.value, + _cpuid_info.std_cpuid1_ebx.value, + _cpuid_info.std_cpuid1_ecx.value, + _cpuid_info.std_cpuid1_edx.value, + _cpuid_info.ext_cpuid1_eax, + _cpuid_info.ext_cpuid1_ebx, + _cpuid_info.ext_cpuid1_ecx, + _cpuid_info.ext_cpuid1_edx); + + if (outputLen < 0 || (size_t) outputLen >= buf_len - 1) { + if (buf_len > 0) { buf[buf_len-1] = '\0'; } + return OS_ERR; + } + + cpu_write_support_string(&buf[outputLen], buf_len - outputLen); + + return OS_OK; +} + + +// Fill in Abstract_VM_Version statics +void VM_Version::initialize_cpu_information() { + assert(_vm_version_initialized, "should have initialized VM_Version long ago"); + assert(!_initialized, "shouldn't be initialized yet"); + resolve_cpu_information_details(); + + // initialize cpu_name and cpu_desc + cpu_type_description(_cpu_name, CPU_TYPE_DESC_BUF_SIZE); + cpu_detailed_description(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE); + _initialized = true; +} + +/** + * For information about extracting the frequency from the cpu brand string, please see: + * + * Intel Processor Identification and the CPUID Instruction + * Application Note 485 + * May 2012 + * + * The return value is the frequency in Hz. + */ +int64_t VM_Version::max_qualified_cpu_freq_from_brand_string(void) { + const char* const brand_string = cpu_brand_string(); + if (brand_string == NULL) { + return 0; + } + const int64_t MEGA = 1000000; + int64_t multiplier = 0; + int64_t frequency = 0; + uint8_t idx = 0; + // The brand string buffer is at most 48 bytes. + // -2 is to prevent buffer overrun when looking for y in yHz, as z is +2 from y. + for (; idx < 48-2; ++idx) { + // Format is either "x.xxyHz" or "xxxxyHz", where y=M, G, T and x are digits. + // Search brand string for "yHz" where y is M, G, or T. + if (brand_string[idx+1] == 'H' && brand_string[idx+2] == 'z') { + if (brand_string[idx] == 'M') { + multiplier = MEGA; + } else if (brand_string[idx] == 'G') { + multiplier = MEGA * 1000; + } else if (brand_string[idx] == 'T') { + multiplier = MEGA * MEGA; + } + break; + } + } + if (multiplier > 0) { + // Compute freqency (in Hz) from brand string. + if (brand_string[idx-3] == '.') { // if format is "x.xx" + frequency = (brand_string[idx-4] - '0') * multiplier; + frequency += (brand_string[idx-2] - '0') * multiplier / 10; + frequency += (brand_string[idx-1] - '0') * multiplier / 100; + } else { // format is "xxxx" + frequency = (brand_string[idx-4] - '0') * 1000; + frequency += (brand_string[idx-3] - '0') * 100; + frequency += (brand_string[idx-2] - '0') * 10; + frequency += (brand_string[idx-1] - '0'); + frequency *= multiplier; + } + } + return frequency; +} + + +int64_t VM_Version::maximum_qualified_cpu_frequency(void) { + if (_max_qualified_cpu_frequency == 0) { + _max_qualified_cpu_frequency = max_qualified_cpu_freq_from_brand_string(); + } + return _max_qualified_cpu_frequency; +} + diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp index d32daec89fbaf980dbfb8771a35c18b6cc17af55..2fd1bbc9617002e6c84cb8f5e76fe090ef1b438c 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.hpp +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,12 +148,11 @@ class VM_Version : public Abstract_VM_Version { uint32_t LahfSahf : 1, CmpLegacy : 1, : 3, - lzcnt_intel : 1, lzcnt : 1, sse4a : 1, misalignsse : 1, prefetchw : 1, - : 22; + : 23; } bits; }; @@ -371,7 +370,7 @@ protected: static const char* _features_names[]; -enum Extended_Family { + enum Extended_Family { // AMD CPU_FAMILY_AMD_11H = 0x11, // ZX @@ -640,10 +639,10 @@ enum Extended_Family { // Intel features. if (is_intel()) { - if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) + if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) { result |= CPU_LZCNT; - // for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw - if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { + } + if (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0) { result |= CPU_3DNOW_PREFETCH; } if (_cpuid_info.sef_cpuid7_ebx.bits.clwb != 0) { @@ -655,10 +654,10 @@ enum Extended_Family { // ZX features. if (is_zx()) { - if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) + if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) { result |= CPU_LZCNT; - // for ZX, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw - if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { + } + if (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0) { result |= CPU_3DNOW_PREFETCH; } } @@ -1053,6 +1052,45 @@ public: // support functions for virtualization detection private: static void check_virtualizations(); + + static const char* cpu_family_description(void); + static const char* cpu_model_description(void); + static const char* cpu_brand(void); + static const char* cpu_brand_string(void); + + static int cpu_type_description(char* const buf, size_t buf_len); + static int cpu_detailed_description(char* const buf, size_t buf_len); + static int cpu_extended_brand_string(char* const buf, size_t buf_len); + + static bool cpu_is_em64t(void); + static bool is_netburst(void); + + // Returns bytes written excluding termninating null byte. + static size_t cpu_write_support_string(char* const buf, size_t buf_len); + static void resolve_cpu_information_details(void); + static int64_t max_qualified_cpu_freq_from_brand_string(void); + + public: + // Offsets for cpuid asm stub brand string + static ByteSize proc_name_0_offset() { return byte_offset_of(CpuidInfo, proc_name_0); } + static ByteSize proc_name_1_offset() { return byte_offset_of(CpuidInfo, proc_name_1); } + static ByteSize proc_name_2_offset() { return byte_offset_of(CpuidInfo, proc_name_2); } + static ByteSize proc_name_3_offset() { return byte_offset_of(CpuidInfo, proc_name_3); } + static ByteSize proc_name_4_offset() { return byte_offset_of(CpuidInfo, proc_name_4); } + static ByteSize proc_name_5_offset() { return byte_offset_of(CpuidInfo, proc_name_5); } + static ByteSize proc_name_6_offset() { return byte_offset_of(CpuidInfo, proc_name_6); } + static ByteSize proc_name_7_offset() { return byte_offset_of(CpuidInfo, proc_name_7); } + static ByteSize proc_name_8_offset() { return byte_offset_of(CpuidInfo, proc_name_8); } + static ByteSize proc_name_9_offset() { return byte_offset_of(CpuidInfo, proc_name_9); } + static ByteSize proc_name_10_offset() { return byte_offset_of(CpuidInfo, proc_name_10); } + static ByteSize proc_name_11_offset() { return byte_offset_of(CpuidInfo, proc_name_11); } + + static int64_t maximum_qualified_cpu_frequency(void); + + static bool supports_tscinv_ext(void); + + static void initialize_tsc(); + static void initialize_cpu_information(void); }; #endif // CPU_X86_VM_VERSION_X86_HPP diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index c7e396e2637d2f853c4ca1ed8aec81b39c6c0f04..a9dc2997e218b9a41271808a060f221f5cc216d0 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1,5 +1,5 @@ // -// Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -1405,6 +1405,7 @@ const bool Matcher::match_rule_supported(int opcode) { } break; case Op_PopCountVI: + case Op_PopCountVL: if (!UsePopCountInstruction || !VM_Version::supports_avx512_vpopcntdq()) { return false; } @@ -1601,6 +1602,21 @@ const bool Matcher::match_rule_supported(int opcode) { return false; } break; + case Op_SqrtF: + if (UseSSE < 1) { + return false; + } + break; + case Op_SqrtD: +#ifdef _LP64 + if (UseSSE < 2) { + return false; + } +#else + // x86_32.ad has a special match rule for SqrtD. + // Together with common x86 rules, this handles all UseSSE cases. +#endif + break; } return true; // Match rules are supported by default. } @@ -1773,17 +1789,9 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType } break; case Op_VectorCastB2X: - if (size_in_bits == 256 && UseAVX < 2) { - return false; // Implementation limitation - } - break; case Op_VectorCastS2X: - if (is_integral_type(bt) && size_in_bits == 256 && UseAVX < 2) { - return false; - } - break; case Op_VectorCastI2X: - if (is_integral_type(bt) && size_in_bits == 256 && UseAVX < 2) { + if (bt != T_DOUBLE && size_in_bits == 256 && UseAVX < 2) { return false; } break; @@ -1827,7 +1835,7 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType } break; case Op_MaskAll: - if (!is_LP64 || !VM_Version::supports_evex()) { + if (!VM_Version::supports_evex()) { return false; } if ((vlen > 16 || is_subword_type(bt)) && !VM_Version::supports_avx512bw()) { @@ -1842,6 +1850,14 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType return false; } break; + case Op_VectorLongToMask: + if (UseAVX < 1 || !is_LP64) { + return false; + } + if (UseAVX < 3 && !VM_Version::supports_bmi2()) { + return false; + } + break; } return true; // Per default match rules are supported. } @@ -1878,6 +1894,12 @@ const bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, Bas case Op_FmaVD: return true; + case Op_MacroLogicV: + if(bt != T_INT && bt != T_LONG) { + return false; + } + return true; + // Binary masked operations case Op_AddVB: case Op_AddVS: @@ -2051,7 +2073,7 @@ const RegMask* Matcher::predicate_reg_mask(void) { return &_VECTMASK_REG_mask; } -const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { +const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { return new TypeVectMask(elemTy, length); } @@ -2543,6 +2565,18 @@ static inline jlong replicate8_imm(int con, int width) { return val; } +static inline jlong high_bit_set(BasicType bt) { + switch (bt) { + case T_BYTE: return 0x8080808080808080; + case T_SHORT: return 0x8000800080008000; + case T_INT: return 0x8000000080000000; + case T_LONG: return 0x8000000000000000; + default: + ShouldNotReachHere(); + return 0; + } +} + #ifndef PRODUCT void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { st->print("nop \t# %d bytes pad for loops and calls", _count); @@ -4572,7 +4606,8 @@ instruct insertF(vec dst, regF val, immU8 idx) %{ assert(Matcher::vector_element_basic_type(this) == T_FLOAT, "sanity"); assert($idx$$constant < (int)Matcher::vector_length(this), "out of bounds"); - __ insertps($dst$$XMMRegister, $val$$XMMRegister, $idx$$constant); + uint x_idx = $idx$$constant & right_n_bits(2); + __ insertps($dst$$XMMRegister, $val$$XMMRegister, x_idx << 4); %} ins_pipe( pipe_slow ); %} @@ -4592,13 +4627,13 @@ instruct vinsertF(vec dst, vec src, regF val, immU8 idx, vec vtmp) %{ uint y_idx = ($idx$$constant >> 2) & 1; int vlen_enc = Assembler::AVX_256bit; __ vextracti128($vtmp$$XMMRegister, $src$$XMMRegister, y_idx); - __ vinsertps($vtmp$$XMMRegister, $vtmp$$XMMRegister, $val$$XMMRegister, x_idx); + __ vinsertps($vtmp$$XMMRegister, $vtmp$$XMMRegister, $val$$XMMRegister, x_idx << 4); __ vinserti128($dst$$XMMRegister, $src$$XMMRegister, $vtmp$$XMMRegister, y_idx); } else { assert(vlen == 16, "sanity"); uint y_idx = ($idx$$constant >> 2) & 3; __ vextracti32x4($vtmp$$XMMRegister, $src$$XMMRegister, y_idx); - __ vinsertps($vtmp$$XMMRegister, $vtmp$$XMMRegister, $val$$XMMRegister, x_idx); + __ vinsertps($vtmp$$XMMRegister, $vtmp$$XMMRegister, $val$$XMMRegister, x_idx << 4); __ vinserti32x4($dst$$XMMRegister, $src$$XMMRegister, $vtmp$$XMMRegister, y_idx); } %} @@ -6895,11 +6930,12 @@ instruct vcastBtoX(vec dst, vec src) %{ case T_LONG: __ vpmovsxbq($dst$$XMMRegister, $src$$XMMRegister, vlen_enc); break; - case T_DOUBLE: - __ vpmovsxbd($dst$$XMMRegister, $src$$XMMRegister, vlen_enc); + case T_DOUBLE: { + int mid_vlen_enc = (vlen_enc == Assembler::AVX_512bit) ? Assembler::AVX_256bit : Assembler::AVX_128bit; + __ vpmovsxbd($dst$$XMMRegister, $src$$XMMRegister, mid_vlen_enc); __ vcvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); break; - + } default: assert(false, "%s", type2name(to_elem_bt)); } %} @@ -6966,10 +7002,12 @@ instruct vcastStoX_evex(vec dst, vec src) %{ case T_LONG: __ vpmovsxwq($dst$$XMMRegister, $src$$XMMRegister, vlen_enc); break; - case T_DOUBLE: - __ vpmovsxwd($dst$$XMMRegister, $src$$XMMRegister, vlen_enc); + case T_DOUBLE: { + int mid_vlen_enc = (vlen_enc == Assembler::AVX_512bit) ? Assembler::AVX_256bit : Assembler::AVX_128bit; + __ vpmovsxwd($dst$$XMMRegister, $src$$XMMRegister, mid_vlen_enc); __ vcvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); break; + } default: ShouldNotReachHere(); } @@ -7292,62 +7330,75 @@ instruct evcmpFD(kReg dst, vec src1, vec src2, immI8 cond) %{ ins_pipe( pipe_slow ); %} -instruct vcmp(legVec dst, legVec src1, legVec src2, immI8 cond, rRegP scratch) %{ +instruct vcmp_direct(legVec dst, legVec src1, legVec src2, immI8 cond) %{ predicate(n->bottom_type()->isa_vectmask() == NULL && !is_unsigned_booltest_pred(n->in(2)->get_int()) && Matcher::vector_length_in_bytes(n->in(1)->in(1)) >= 4 && // src1 Matcher::vector_length_in_bytes(n->in(1)->in(1)) <= 32 && // src1 - is_integral_type(Matcher::vector_element_basic_type(n->in(1)->in(1)))); // src1 + is_integral_type(Matcher::vector_element_basic_type(n->in(1)->in(1))) && + (n->in(2)->get_int() == BoolTest::eq || + n->in(2)->get_int() == BoolTest::lt || + n->in(2)->get_int() == BoolTest::gt)); // cond match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); - effect(TEMP scratch); - format %{ "vector_compare $dst,$src1,$src2,$cond\t! using $scratch as TEMP" %} + format %{ "vector_compare $dst,$src1,$src2,$cond\t!" %} ins_encode %{ int vlen_enc = vector_length_encoding(this, $src1); Assembler::ComparisonPredicate cmp = booltest_pred_to_comparison_pred($cond$$constant); Assembler::Width ww = widthForType(Matcher::vector_element_basic_type(this, $src1)); - __ vpcmpCCW($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, cmp, ww, vlen_enc, $scratch$$Register); + __ vpcmpCCW($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, xnoreg, cmp, ww, vlen_enc); %} ins_pipe( pipe_slow ); %} -instruct vcmpu(legVec dst, legVec src1, legVec src2, immI8 cond, legVec vtmp1, legVec vtmp2, rRegP scratch) %{ +instruct vcmp_negate(legVec dst, legVec src1, legVec src2, immI8 cond, legVec xtmp) %{ predicate(n->bottom_type()->isa_vectmask() == NULL && - is_unsigned_booltest_pred(n->in(2)->get_int()) && - Matcher::vector_length_in_bytes(n->in(1)->in(1)) >= 8 && // src1 - Matcher::vector_length_in_bytes(n->in(1)->in(1)) <= 16 && // src1 - is_integral_type(Matcher::vector_element_basic_type(n->in(1)->in(1)))); // src1 + !is_unsigned_booltest_pred(n->in(2)->get_int()) && + Matcher::vector_length_in_bytes(n->in(1)->in(1)) >= 4 && // src1 + Matcher::vector_length_in_bytes(n->in(1)->in(1)) <= 32 && // src1 + is_integral_type(Matcher::vector_element_basic_type(n->in(1)->in(1))) && + (n->in(2)->get_int() == BoolTest::ne || + n->in(2)->get_int() == BoolTest::le || + n->in(2)->get_int() == BoolTest::ge)); // cond match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); - effect(TEMP vtmp1, TEMP vtmp2, TEMP scratch); - format %{ "vector_compareu $dst,$src1,$src2,$cond\t! using $scratch as TEMP" %} + effect(TEMP dst, TEMP xtmp); + format %{ "vector_compare $dst,$src1,$src2,$cond\t! using $xtmp as TEMP" %} ins_encode %{ - int vlen = Matcher::vector_length_in_bytes(this, $src1); + int vlen_enc = vector_length_encoding(this, $src1); Assembler::ComparisonPredicate cmp = booltest_pred_to_comparison_pred($cond$$constant); - BasicType bt = Matcher::vector_element_basic_type(this, $src1); - __ vpcmpu(bt, $dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, cmp, vlen, $vtmp1$$XMMRegister, - $vtmp2$$XMMRegister, $scratch$$Register); + Assembler::Width ww = widthForType(Matcher::vector_element_basic_type(this, $src1)); + __ vpcmpCCW($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, $xtmp$$XMMRegister, cmp, ww, vlen_enc); %} ins_pipe( pipe_slow ); %} -instruct vcmpu32(legVec dst, legVec src1, legVec src2, immI8 cond, legVec vtmp1, legVec vtmp2, legVec vtmp3, rRegP scratch) %{ +instruct vcmpu(legVec dst, legVec src1, legVec src2, immI8 cond, legVec xtmp) %{ predicate(n->bottom_type()->isa_vectmask() == NULL && is_unsigned_booltest_pred(n->in(2)->get_int()) && - Matcher::vector_length_in_bytes(n->in(1)->in(1)) == 32 && // src1 + Matcher::vector_length_in_bytes(n->in(1)->in(1)) >= 4 && // src1 + Matcher::vector_length_in_bytes(n->in(1)->in(1)) <= 32 && // src1 is_integral_type(Matcher::vector_element_basic_type(n->in(1)->in(1)))); // src1 match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); - effect(TEMP dst, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP scratch); - format %{ "vector_compareu $dst,$src1,$src2,$cond\t! using $scratch as TEMP" %} + effect(TEMP dst, TEMP xtmp); + format %{ "vector_compareu $dst,$src1,$src2,$cond\t! using $xtmp as TEMP" %} ins_encode %{ - int vlen = Matcher::vector_length_in_bytes(this, $src1); + InternalAddress flip_bit = $constantaddress(high_bit_set(Matcher::vector_element_basic_type(this, $src1))); + int vlen_enc = vector_length_encoding(this, $src1); Assembler::ComparisonPredicate cmp = booltest_pred_to_comparison_pred($cond$$constant); - BasicType bt = Matcher::vector_element_basic_type(this, $src1); - __ vpcmpu32(bt, $dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, cmp, vlen, $vtmp1$$XMMRegister, - $vtmp2$$XMMRegister, $vtmp3$$XMMRegister, $scratch$$Register); + Assembler::Width ww = widthForType(Matcher::vector_element_basic_type(this, $src1)); + + if (vlen_enc == Assembler::AVX_128bit) { + __ vmovddup($xtmp$$XMMRegister, flip_bit, vlen_enc, noreg); + } else { + __ vbroadcastsd($xtmp$$XMMRegister, flip_bit, vlen_enc, noreg); + } + __ vpxor($dst$$XMMRegister, $xtmp$$XMMRegister, $src1$$XMMRegister, vlen_enc); + __ vpxor($xtmp$$XMMRegister, $xtmp$$XMMRegister, $src2$$XMMRegister, vlen_enc); + __ vpcmpCCW($dst$$XMMRegister, $dst$$XMMRegister, $xtmp$$XMMRegister, $xtmp$$XMMRegister, cmp, ww, vlen_enc); %} ins_pipe( pipe_slow ); %} -instruct vcmpu64(vec dst, vec src1, vec src2, immI8 cond, rRegP scratch, kReg ktmp) %{ +instruct vcmp64(vec dst, vec src1, vec src2, immI8 cond, rRegP scratch, kReg ktmp) %{ predicate((n->bottom_type()->isa_vectmask() == NULL && Matcher::vector_length_in_bytes(n->in(1)->in(1)) == 64) && // src1 is_integral_type(Matcher::vector_element_basic_type(n->in(1)->in(1)))); // src1 @@ -8570,6 +8621,20 @@ instruct vpopcountI(vec dst, vec src) %{ ins_pipe( pipe_slow ); %} +instruct vpopcountL(vec dst, vec src) %{ + match(Set dst (PopCountVL src)); + format %{ "vpopcntq $dst,$src\t! vector popcount packedL" %} + ins_encode %{ + assert(UsePopCountInstruction, "not enabled"); + + int vlen_enc = vector_length_encoding(this, $src); + __ vpopcntq($dst$$XMMRegister, $src$$XMMRegister, vlen_enc); + __ evpmovqd($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); + + %} + ins_pipe( pipe_slow ); +%} + // --------------------------------- Bitwise Ternary Logic ---------------------------------- instruct vpternlog(vec dst, vec src2, vec src3, immU8 func) %{ @@ -9451,64 +9516,18 @@ instruct evcmp_masked(kReg dst, vec src1, vec src2, immI8 cond, kReg mask, rRegP ins_pipe( pipe_slow ); %} -#ifdef _LP64 -instruct mask_all_evexI_imm(kReg dst, immI cnt, rRegL tmp) %{ - match(Set dst (MaskAll cnt)); - effect(TEMP_DEF dst, TEMP tmp); - format %{ "mask_all_evexI $dst, $cnt \t! using $tmp as TEMP" %} - ins_encode %{ - int vec_len = Matcher::vector_length(this); - if (VM_Version::supports_avx512bw()) { - __ movq($tmp$$Register, $cnt$$constant); - __ kmovql($dst$$KRegister, $tmp$$Register); - __ kshiftrql($dst$$KRegister, $dst$$KRegister, 64 - vec_len); - } else { - assert(vec_len <= 16, ""); - __ movq($tmp$$Register, $cnt$$constant); - __ kmovwl($dst$$KRegister, $tmp$$Register); - __ kshiftrwl($dst$$KRegister, $dst$$KRegister, 16 - vec_len); - } - %} - ins_pipe( pipe_slow ); -%} - -instruct mask_all_evexI(kReg dst, rRegI src, rRegL tmp) %{ - match(Set dst (MaskAll src)); - effect(TEMP_DEF dst, TEMP tmp); - format %{ "mask_all_evexI $dst, $src \t! using $tmp as TEMP" %} - ins_encode %{ - int vec_len = Matcher::vector_length(this); - if (VM_Version::supports_avx512bw()) { - __ movslq($tmp$$Register, $src$$Register); - __ kmovql($dst$$KRegister, $tmp$$Register); - __ kshiftrql($dst$$KRegister, $dst$$KRegister, 64 - vec_len); - } else { - assert(vec_len <= 16, ""); - __ kmovwl($dst$$KRegister, $src$$Register); - __ kshiftrwl($dst$$KRegister, $dst$$KRegister, 16 - vec_len); - } - %} - ins_pipe( pipe_slow ); -%} - -instruct mask_all_evexL(kReg dst, rRegL src) %{ +instruct mask_all_evexI_LE32(kReg dst, rRegI src) %{ + predicate(Matcher::vector_length(n) <= 32); match(Set dst (MaskAll src)); - effect(TEMP_DEF dst); - format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} + format %{ "mask_all_evexI_LE32 $dst, $src \t" %} ins_encode %{ - int vec_len = Matcher::vector_length(this); - if (VM_Version::supports_avx512bw()) { - __ kmovql($dst$$KRegister, $src$$Register); - __ kshiftrql($dst$$KRegister, $dst$$KRegister, 64 - vec_len); - } else { - assert(vec_len <= 16, ""); - __ kmovwl($dst$$KRegister, $src$$Register); - __ kshiftrwl($dst$$KRegister, $dst$$KRegister, 16 - vec_len); - } + int mask_len = Matcher::vector_length(this); + __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); %} ins_pipe( pipe_slow ); %} +#ifdef _LP64 instruct mask_not_immLT8(kReg dst, kReg src, rRegI rtmp, kReg ktmp, immI_M1 cnt) %{ predicate(Matcher::vector_length(n) < 8 && VM_Version::supports_avx512dq()); match(Set dst (XorVMask src (MaskAll cnt))); @@ -9533,6 +9552,46 @@ instruct mask_not_imm(kReg dst, kReg src, immI_M1 cnt) %{ %} ins_pipe( pipe_slow ); %} + +instruct long_to_maskLE8_avx(vec dst, rRegL src, rRegL rtmp1, rRegL rtmp2, vec xtmp) %{ + predicate(n->bottom_type()->isa_vectmask() == NULL && Matcher::vector_length(n) <= 8); + match(Set dst (VectorLongToMask src)); + effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, TEMP xtmp); + format %{ "long_to_mask_avx $dst, $src\t! using $rtmp1, $rtmp2, $xtmp as TEMP" %} + ins_encode %{ + int mask_len = Matcher::vector_length(this); + int vec_enc = vector_length_encoding(mask_len); + __ vector_long_to_maskvec($dst$$XMMRegister, $src$$Register, $rtmp1$$Register, + $rtmp2$$Register, xnoreg, mask_len, vec_enc); + %} + ins_pipe( pipe_slow ); +%} + + +instruct long_to_maskGT8_avx(vec dst, rRegL src, rRegL rtmp1, rRegL rtmp2, vec xtmp1, rFlagsReg cr) %{ + predicate(n->bottom_type()->isa_vectmask() == NULL && Matcher::vector_length(n) > 8); + match(Set dst (VectorLongToMask src)); + effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, TEMP xtmp1, KILL cr); + format %{ "long_to_mask_avx $dst, $src\t! using $rtmp1, $rtmp2, $xtmp1, as TEMP" %} + ins_encode %{ + int mask_len = Matcher::vector_length(this); + assert(mask_len <= 32, "invalid mask length"); + int vec_enc = vector_length_encoding(mask_len); + __ vector_long_to_maskvec($dst$$XMMRegister, $src$$Register, $rtmp1$$Register, + $rtmp2$$Register, $xtmp1$$XMMRegister, mask_len, vec_enc); + %} + ins_pipe( pipe_slow ); +%} + +instruct long_to_mask_evex(kReg dst, rRegL src) %{ + predicate(n->bottom_type()->isa_vectmask()); + match(Set dst (VectorLongToMask src)); + format %{ "long_to_mask_evex $dst, $src\t!" %} + ins_encode %{ + __ kmov($dst$$KRegister, $src$$Register); + %} + ins_pipe( pipe_slow ); +%} #endif instruct mask_opers_evex(kReg dst, kReg src1, kReg src2, kReg kscratch) %{ @@ -9552,6 +9611,30 @@ instruct mask_opers_evex(kReg dst, kReg src1, kReg src2, kReg kscratch) %{ ins_pipe( pipe_slow ); %} +instruct vternlog_reg_masked(vec dst, vec src2, vec src3, immU8 func, kReg mask) %{ + match(Set dst (MacroLogicV dst (Binary src2 (Binary src3 (Binary func mask))))); + format %{ "vternlog_masked $dst,$src2,$src3,$func,$mask\t! vternlog masked operation" %} + ins_encode %{ + int vlen_enc = vector_length_encoding(this); + BasicType bt = Matcher::vector_element_basic_type(this); + __ evpternlog($dst$$XMMRegister, $func$$constant, $mask$$KRegister, + $src2$$XMMRegister, $src3$$XMMRegister, true, bt, vlen_enc); + %} + ins_pipe( pipe_slow ); +%} + +instruct vternlogd_mem_masked(vec dst, vec src2, memory src3, immU8 func, kReg mask) %{ + match(Set dst (MacroLogicV dst (Binary src2 (Binary src3 (Binary func mask))))); + format %{ "vternlog_masked $dst,$src2,$src3,$func,$mask\t! vternlog masked operation" %} + ins_encode %{ + int vlen_enc = vector_length_encoding(this); + BasicType bt = Matcher::vector_element_basic_type(this); + __ evpternlog($dst$$XMMRegister, $func$$constant, $mask$$KRegister, + $src2$$XMMRegister, $src3$$Address, true, bt, vlen_enc); + %} + ins_pipe( pipe_slow ); +%} + instruct castMM(kReg dst) %{ match(Set dst (CastVV dst)); diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 611206fa9fae15cb297ab1facaa1c31d2cba7b40..a31a38a384fe54e6b2964dafcea7729eea487928 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -13130,6 +13130,24 @@ instruct cmovLL_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, load_lo ins_pipe( pipe_cmov_reg_long ); %} +instruct cmovLL_reg_LTGE_U(cmpOpU cmp, flagsReg_ulong_LTGE flags, eRegL dst, eRegL src) %{ + match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); + predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge )); + ins_cost(400); + expand %{ + cmovLL_reg_LTGE(cmp, flags, dst, src); + %} +%} + +instruct cmovLL_mem_LTGE_U(cmpOpU cmp, flagsReg_ulong_LTGE flags, eRegL dst, load_long_memory src) %{ + match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src)))); + predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge )); + ins_cost(500); + expand %{ + cmovLL_mem_LTGE(cmp, flags, dst, src); + %} +%} + // Compare 2 longs and CMOVE ints. instruct cmovII_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, rRegI dst, rRegI src) %{ predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge )); @@ -13829,7 +13847,40 @@ instruct cmpFastUnlock(eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{ ins_pipe(pipe_slow); %} +instruct mask_all_evexL_LT32(kReg dst, eRegL src) %{ + predicate(Matcher::vector_length(n) <= 32); + match(Set dst (MaskAll src)); + format %{ "mask_all_evexL_LE32 $dst, $src \t" %} + ins_encode %{ + int mask_len = Matcher::vector_length(this); + __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); + %} + ins_pipe( pipe_slow ); +%} +instruct mask_all_evexL_GT32(kReg dst, eRegL src, kReg ktmp) %{ + predicate(Matcher::vector_length(n) > 32); + match(Set dst (MaskAll src)); + effect(TEMP ktmp); + format %{ "mask_all_evexL_GT32 $dst, $src \t! using $ktmp as TEMP " %} + ins_encode %{ + int mask_len = Matcher::vector_length(this); + __ vector_maskall_operation32($dst$$KRegister, $src$$Register, $ktmp$$KRegister, mask_len); + %} + ins_pipe( pipe_slow ); +%} + +instruct mask_all_evexI_GT32(kReg dst, rRegI src, kReg ktmp) %{ + predicate(Matcher::vector_length(n) > 32); + match(Set dst (MaskAll src)); + effect(TEMP ktmp); + format %{ "mask_all_evexI_GT32 $dst, $src \t! using $ktmp as TEMP" %} + ins_encode %{ + int mask_len = Matcher::vector_length(this); + __ vector_maskall_operation32($dst$$KRegister, $src$$Register, $ktmp$$KRegister, mask_len); + %} + ins_pipe( pipe_slow ); +%} // ============================================================================ // Safepoint Instruction diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 6a764fd62a19b4403350b6e6f986937eb4b35690..fbf71300dcd6b6da8a0dc4b034f0c152dfdcdaae 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -13011,6 +13011,29 @@ instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) ins_pipe(ialu_reg_mem); %} +instruct mask_all_evexL(kReg dst, rRegL src) %{ + match(Set dst (MaskAll src)); + format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} + ins_encode %{ + int mask_len = Matcher::vector_length(this); + __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); + %} + ins_pipe( pipe_slow ); +%} + +instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ + predicate(Matcher::vector_length(n) > 32); + match(Set dst (MaskAll src)); + effect(TEMP tmp); + format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} + ins_encode %{ + int mask_len = Matcher::vector_length(this); + __ movslq($tmp$$Register, $src$$Register); + __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); + %} + ins_pipe( pipe_slow ); +%} + // ============================================================================ // Procedure Call/Return Instructions // Call Java Static Instruction diff --git a/src/hotspot/cpu/zero/bytes_zero.hpp b/src/hotspot/cpu/zero/bytes_zero.hpp index 9acd9dd2430e2782d8744fc2e11a04333119b06b..93d49b8a28d06fe2ce475aee078065f08f037247 100644 --- a/src/hotspot/cpu/zero/bytes_zero.hpp +++ b/src/hotspot/cpu/zero/bytes_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ #ifndef CPU_ZERO_BYTES_ZERO_HPP #define CPU_ZERO_BYTES_ZERO_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" typedef union unaligned { u4 u; diff --git a/src/hotspot/cpu/zero/frame_zero.cpp b/src/hotspot/cpu/zero/frame_zero.cpp index 19970cfb82bc20cc2e4b6729e080aaaa2f7d29e3..2e00d703377cc89597762cc9d5bd36c11f4d4edb 100644 --- a/src/hotspot/cpu/zero/frame_zero.cpp +++ b/src/hotspot/cpu/zero/frame_zero.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. + * Copyright (c) 2007, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,13 +116,67 @@ void frame::patch_pc(Thread* thread, address pc) { } bool frame::safe_for_sender(JavaThread *thread) { - ShouldNotCallThis(); - return false; + address sp = (address)_sp; + + // consider stack guards when trying to determine "safe" stack pointers + // sp must be within the usable part of the stack (not in guards) + if (!thread->is_in_usable_stack(sp)) { + return false; + } + + // an fp must be within the stack and above (but not equal) sp + if (!thread->is_in_stack_range_excl((address)fp(), sp)) { + return false; + } + + // All good. + return true; } bool frame::is_interpreted_frame_valid(JavaThread *thread) const { - ShouldNotCallThis(); - return false; + assert(is_interpreted_frame(), "Not an interpreted frame"); + // These are reasonable sanity checks + if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) { + return false; + } + if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { + return false; + } + // These are hacks to keep us out of trouble. + // The problem with these is that they mask other problems + if (fp() <= sp()) { // this attempts to deal with unsigned comparison above + return false; + } + + // do some validation of frame elements + // first the method + + Method* m = *interpreter_frame_method_addr(); + + // validate the method we'd find in this potential sender + if (!Method::is_valid_method(m)) { + return false; + } + + // validate bci/bcp + address bcp = interpreter_frame_bcp(); + if (m->validate_bci_from_bcp(bcp) < 0) { + return false; + } + + // validate ConstantPoolCache* + ConstantPoolCache* cp = *interpreter_frame_cache_addr(); + if (MetaspaceObj::is_valid(cp) == false) { + return false; + } + + // validate locals + address locals = (address) *interpreter_frame_locals_addr(); + if (!thread->is_in_stack_range_incl(locals, (address)fp())) { + return false; + } + + return true; } BasicType frame::interpreter_frame_result(oop* oop_result, diff --git a/src/hotspot/cpu/zero/jniTypes_zero.hpp b/src/hotspot/cpu/zero/jniTypes_zero.hpp index 8d5a6bee7fa32059d8b49e985019693bae35182a..9f6fe78005b9efb63d909bb43881930525192d2c 100644 --- a/src/hotspot/cpu/zero/jniTypes_zero.hpp +++ b/src/hotspot/cpu/zero/jniTypes_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define CPU_ZERO_JNITYPES_ZERO_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive jni diff --git a/src/hotspot/cpu/zero/vm_version_ext_zero.cpp b/src/hotspot/cpu/zero/vm_version_ext_zero.cpp deleted file mode 100644 index 9e4f45fd679e49d89520be4da442eece8e254e4a..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/zero/vm_version_ext_zero.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" -#include "runtime/os.hpp" -#include "vm_version_ext_zero.hpp" - -// VM_Version_Ext statics -int VM_Version_Ext::_no_of_threads = 0; -int VM_Version_Ext::_no_of_cores = 0; -int VM_Version_Ext::_no_of_sockets = 0; -bool VM_Version_Ext::_initialized = false; -char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0}; -char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0}; - -void VM_Version_Ext::initialize_cpu_information(void) { - // do nothing if cpu info has been initialized - if (_initialized) { - return; - } - - int core_id = -1; - int chip_id = -1; - int len = 0; - char* src_string = NULL; - - _no_of_cores = os::processor_count(); - _no_of_threads = _no_of_cores; - _no_of_sockets = _no_of_cores; - snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "Zero VM"); - snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string); - _initialized = true; -} - -int VM_Version_Ext::number_of_threads(void) { - initialize_cpu_information(); - return _no_of_threads; -} - -int VM_Version_Ext::number_of_cores(void) { - initialize_cpu_information(); - return _no_of_cores; -} - -int VM_Version_Ext::number_of_sockets(void) { - initialize_cpu_information(); - return _no_of_sockets; -} - -const char* VM_Version_Ext::cpu_name(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE); - return tmp; -} - -const char* VM_Version_Ext::cpu_description(void) { - initialize_cpu_information(); - char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing); - if (NULL == tmp) { - return NULL; - } - strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE); - return tmp; -} diff --git a/src/hotspot/cpu/zero/vm_version_ext_zero.hpp b/src/hotspot/cpu/zero/vm_version_ext_zero.hpp deleted file mode 100644 index 2c6580d5f1f20cd60598ec2af7871b869410b3be..0000000000000000000000000000000000000000 --- a/src/hotspot/cpu/zero/vm_version_ext_zero.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_ZERO_VM_VERSION_EXT_ZERO_HPP -#define CPU_ZERO_VM_VERSION_EXT_ZERO_HPP - -#include "runtime/vm_version.hpp" -#include "utilities/macros.hpp" - -class VM_Version_Ext : public VM_Version { - private: - static const size_t CPU_TYPE_DESC_BUF_SIZE = 256; - static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096; - - static int _no_of_threads; - static int _no_of_cores; - static int _no_of_sockets; - static bool _initialized; - static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE]; - static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE]; - - public: - static int number_of_threads(void); - static int number_of_cores(void); - static int number_of_sockets(void); - - static const char* cpu_name(void); - static const char* cpu_description(void); - static void initialize_cpu_information(void); - -}; - -#endif // CPU_ZERO_VM_VERSION_EXT_ZERO_HPP diff --git a/src/hotspot/cpu/zero/vm_version_zero.cpp b/src/hotspot/cpu/zero/vm_version_zero.cpp index 6fa56c24cce14c265ab5324e97f3f00c1536d781..5c2a0a3d5d2304b798d992ab5ae03138c4d899a9 100644 --- a/src/hotspot/cpu/zero/vm_version_zero.cpp +++ b/src/hotspot/cpu/zero/vm_version_zero.cpp @@ -121,3 +121,17 @@ void VM_Version::initialize() { UNSUPPORTED_OPTION(CountCompiledCalls); #endif } + +void VM_Version::initialize_cpu_information(void) { + // do nothing if cpu info has been initialized + if (_initialized) { + return; + } + + _no_of_cores = os::processor_count(); + _no_of_threads = _no_of_cores; + _no_of_sockets = _no_of_cores; + snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "Zero VM"); + snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string); + _initialized = true; +} diff --git a/src/hotspot/cpu/zero/vm_version_zero.hpp b/src/hotspot/cpu/zero/vm_version_zero.hpp index c63a47719e50d592d7db088fa0f9c04a77e901d4..1cfe57b11c2463b45ad9507affadd6a203b9a4f6 100644 --- a/src/hotspot/cpu/zero/vm_version_zero.hpp +++ b/src/hotspot/cpu/zero/vm_version_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright 2007 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -34,6 +34,8 @@ class VM_Version : public Abstract_VM_Version { static void initialize(); constexpr static bool supports_stack_watermark_barrier() { return true; } + + static void initialize_cpu_information(void); }; #endif // CPU_ZERO_VM_VERSION_ZERO_HPP diff --git a/src/hotspot/os/aix/osThread_aix.hpp b/src/hotspot/os/aix/osThread_aix.hpp index 0c8706d4add55aa6c4c5dfda0e30141bf675cb24..79e60b82e4cf6df2d3be7080426414cca3944714 100644 --- a/src/hotspot/os/aix/osThread_aix.hpp +++ b/src/hotspot/os/aix/osThread_aix.hpp @@ -63,13 +63,6 @@ // Used for debugging, return a unique integer for each thread. int thread_identifier() const { return _thread_id; } #endif -#ifdef ASSERT - // We expect no reposition failures so kill vm if we get one. - // - bool valid_reposition_failure() { - return false; - } -#endif // ASSERT tid_t kernel_thread_id() const { return _kernel_thread_id; } diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index df8563067e43e7d103d52a64e581b23e9e8bbec0..419e2ce92fd0be424f557c82832dd146edd1b91c 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -741,7 +741,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, assert(thread->osthread() == NULL, "caller responsible"); // Allocate the OSThread object. - OSThread* osthread = new OSThread(NULL, NULL); + OSThread* osthread = new OSThread(); if (osthread == NULL) { return false; } @@ -855,7 +855,7 @@ bool os::create_attached_thread(JavaThread* thread) { #endif // Allocate the OSThread object - OSThread* osthread = new OSThread(NULL, NULL); + OSThread* osthread = new OSThread(); if (osthread == NULL) { return false; diff --git a/src/hotspot/os/aix/os_perf_aix.cpp b/src/hotspot/os/aix/os_perf_aix.cpp index 15eca737fdf9ae8044cd7619f30c73c52bb41f43..bdccca0c1c55f61086bf2bcd775ca432eabca688 100644 --- a/src/hotspot/os/aix/os_perf_aix.cpp +++ b/src/hotspot/os/aix/os_perf_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,10 +28,9 @@ #include "os_aix.inline.hpp" #include "runtime/os.hpp" #include "runtime/os_perf.hpp" +#include "runtime/vm_version.hpp" #include "utilities/globalDefinitions.hpp" -#include CPU_HEADER(vm_version_ext) - #include #include #include @@ -240,7 +239,7 @@ static int SCANF_ARGS(2, 0) vread_statdata(const char* procfile, _SCANFMT_ const int n; char buf[2048]; - if ((f = fopen(procfile, "r")) == NULL) { + if ((f = os::fopen(procfile, "r")) == NULL) { return -1; } @@ -663,7 +662,7 @@ void SystemProcessInterface::SystemProcesses::ProcessIterator::get_exe_name() { jio_snprintf(buffer, PATH_MAX, "/proc/%s/stat", _entry->d_name); buffer[PATH_MAX - 1] = '\0'; - if ((fp = fopen(buffer, "r")) != NULL) { + if ((fp = os::fopen(buffer, "r")) != NULL) { if (fgets(buffer, PATH_MAX, fp) != NULL) { char* start, *end; // exe-name is between the first pair of ( and ) @@ -691,7 +690,7 @@ char* SystemProcessInterface::SystemProcesses::ProcessIterator::get_cmdline() { jio_snprintf(buffer, PATH_MAX, "/proc/%s/cmdline", _entry->d_name); buffer[PATH_MAX - 1] = '\0'; - if ((fp = fopen(buffer, "r")) != NULL) { + if ((fp = os::fopen(buffer, "r")) != NULL) { size_t size = 0; char dummy; @@ -863,11 +862,12 @@ CPUInformationInterface::CPUInformationInterface() { bool CPUInformationInterface::initialize() { _cpu_info = new CPUInformation(); - _cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads()); - _cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores()); - _cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets()); - _cpu_info->set_cpu_name(VM_Version_Ext::cpu_name()); - _cpu_info->set_cpu_description(VM_Version_Ext::cpu_description()); + VM_Version::initialize_cpu_information(); + _cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads()); + _cpu_info->set_number_of_cores(VM_Version::number_of_cores()); + _cpu_info->set_number_of_sockets(VM_Version::number_of_sockets()); + _cpu_info->set_cpu_name(VM_Version::cpu_name()); + _cpu_info->set_cpu_description(VM_Version::cpu_description()); return true; } diff --git a/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp b/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp index a0fe34c65041e9c60cdb14fadbdf0d66805a9477..e5b3895c44e6df677f612889573ff869abc2c66a 100644 --- a/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp +++ b/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp @@ -23,6 +23,7 @@ #include "precompiled.hpp" #include "gc/z/zNUMA.hpp" +#include "utilities/globalDefinitions.hpp" void ZNUMA::pd_initialize() { _enabled = false; diff --git a/src/hotspot/os/bsd/osThread_bsd.hpp b/src/hotspot/os/bsd/osThread_bsd.hpp index 8e7375d714566628a9c813d5c941d20a97a51790..731e046e529917743ff2f8f45d6e3e0b772b825c 100644 --- a/src/hotspot/os/bsd/osThread_bsd.hpp +++ b/src/hotspot/os/bsd/osThread_bsd.hpp @@ -67,14 +67,6 @@ intptr_t thread_identifier() const { return (intptr_t)_pthread_id; } #endif -#ifdef ASSERT - // We expect no reposition failures so kill vm if we get one. - // - bool valid_reposition_failure() { - return false; - } -#endif // ASSERT - pthread_t pthread_id() const { return _pthread_id; } diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index ef7e6e3e3a1c24076b90200b1475424feba95915..89e6aed8ec828c49f319389b26bca239ada199c8 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -589,7 +589,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, assert(thread->osthread() == NULL, "caller responsible"); // Allocate the OSThread object - OSThread* osthread = new OSThread(NULL, NULL); + OSThread* osthread = new OSThread(); if (osthread == NULL) { return false; } @@ -682,7 +682,7 @@ bool os::create_attached_thread(JavaThread* thread) { #endif // Allocate the OSThread object - OSThread* osthread = new OSThread(NULL, NULL); + OSThread* osthread = new OSThread(); if (osthread == NULL) { return false; diff --git a/src/hotspot/os/bsd/os_perf_bsd.cpp b/src/hotspot/os/bsd/os_perf_bsd.cpp index e69bfc79558c3fb5cebf3a8451b98f1fd0ecad80..9b80e74954284ab602e538e9d6cfb1a812ab85f7 100644 --- a/src/hotspot/os/bsd/os_perf_bsd.cpp +++ b/src/hotspot/os/bsd/os_perf_bsd.cpp @@ -26,8 +26,8 @@ #include "memory/resourceArea.hpp" #include "runtime/os.hpp" #include "runtime/os_perf.hpp" +#include "runtime/vm_version.hpp" #include "utilities/globalDefinitions.hpp" -#include CPU_HEADER(vm_version_ext) #ifdef __APPLE__ #import @@ -371,11 +371,12 @@ CPUInformationInterface::CPUInformationInterface() { bool CPUInformationInterface::initialize() { _cpu_info = new CPUInformation(); - _cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads()); - _cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores()); - _cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets()); - _cpu_info->set_cpu_name(VM_Version_Ext::cpu_name()); - _cpu_info->set_cpu_description(VM_Version_Ext::cpu_description()); + VM_Version::initialize_cpu_information(); + _cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads()); + _cpu_info->set_number_of_cores(VM_Version::number_of_cores()); + _cpu_info->set_number_of_sockets(VM_Version::number_of_sockets()); + _cpu_info->set_cpu_name(VM_Version::cpu_name()); + _cpu_info->set_cpu_description(VM_Version::cpu_description()); return true; } diff --git a/src/hotspot/os/linux/attachListener_linux.cpp b/src/hotspot/os/linux/attachListener_linux.cpp index 628c3f1c462b158362502077c7f14f4330149cf9..eb723603b5f19e509bc1f0f9e2035805e714b8c9 100644 --- a/src/hotspot/os/linux/attachListener_linux.cpp +++ b/src/hotspot/os/linux/attachListener_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -385,7 +385,7 @@ LinuxAttachOperation* LinuxAttachListener::dequeue() { // write the given buffer to the socket int LinuxAttachListener::write_fully(int s, char* buf, int len) { do { - int n = ::write(s, buf, len); + ssize_t n = ::write(s, buf, len); if (n == -1) { if (errno != EINTR) return -1; } else { diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.cpp b/src/hotspot/os/linux/cgroupSubsystem_linux.cpp index 1593a701e67991e41b8a4d010b4a44b86803cd75..dd858a30e4cdf3b7354d02d59a2a434ec4a3d97c 100644 --- a/src/hotspot/os/linux/cgroupSubsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupSubsystem_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,7 +146,7 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos, * Conversely, for cgroups v2 (unified hierarchy), cpu, cpuacct, cpuset, memory * controllers must have hierarchy ID 0 and the unified controller mounted. */ - cgroups = fopen(proc_cgroups, "r"); + cgroups = os::fopen(proc_cgroups, "r"); if (cgroups == NULL) { log_debug(os, container)("Can't open %s, %s", proc_cgroups, os::strerror(errno)); *flags = INVALID_CGROUPS_GENERIC; @@ -214,7 +214,7 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos, * - on a cgroups v1 system, collect info for mapping * the host mount point to the local one via /proc/self/mountinfo below. */ - cgroup = fopen(proc_self_cgroup, "r"); + cgroup = os::fopen(proc_self_cgroup, "r"); if (cgroup == NULL) { log_debug(os, container)("Can't open %s, %s", proc_self_cgroup, os::strerror(errno)); @@ -269,7 +269,7 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos, // Find various mount points by reading /proc/self/mountinfo // mountinfo format is documented at https://www.kernel.org/doc/Documentation/filesystems/proc.txt - mntinfo = fopen(proc_self_mountinfo, "r"); + mntinfo = os::fopen(proc_self_mountinfo, "r"); if (mntinfo == NULL) { log_debug(os, container)("Can't open %s, %s", proc_self_mountinfo, os::strerror(errno)); diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp index 754629714492911a7a20601a49fcad10873b31b1..5fc376a304e65d2b96c6083204a4f936ae62883b 100644 --- a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp +++ b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,7 +108,7 @@ template int subsystem_file_line_contents(CgroupController* c, } strncat(file, filename, MAXPATHLEN-filelen); log_trace(os, container)("Path to %s is %s", filename, file); - fp = fopen(file, "r"); + fp = os::fopen(file, "r"); if (fp != NULL) { int err = 0; while ((p = fgets(buf, MAXPATHLEN, fp)) != NULL) { @@ -157,8 +157,10 @@ PRAGMA_DIAG_POP NULL, \ scan_fmt, \ &variable); \ - if (err != 0) \ + if (err != 0) { \ + log_trace(os, container)(logstring, (return_type) OSCONTAINER_ERROR); \ return (return_type) OSCONTAINER_ERROR; \ + } \ \ log_trace(os, container)(logstring, variable); \ } diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp index 25146373532c6b13b641c973025c97320b503128..0b1bc9c6cddd83e9704215a5bb09e2aada28ca9a 100644 --- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Red Hat Inc. + * Copyright (c) 2020, 2022, Red Hat Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ */ int CgroupV2Subsystem::cpu_shares() { GET_CONTAINER_INFO(int, _unified, "/cpu.weight", - "Raw value for CPU shares is: %d", "%d", shares); + "Raw value for CPU Shares is: %d", "%d", shares); // Convert default value of 100 to no shares setup if (shares == 100) { log_debug(os, container)("CPU Shares is: %d", -1); diff --git a/src/hotspot/os/linux/decoder_linux.cpp b/src/hotspot/os/linux/decoder_linux.cpp index daa12ec6f6d7caa2331c188fc9503334eef3c99c..0fc0daf98e7b9ee89a635e9317905bb865142caa 100644 --- a/src/hotspot/os/linux/decoder_linux.cpp +++ b/src/hotspot/os/linux/decoder_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) { bool ElfFile::specifies_noexecstack(const char* filepath) { if (filepath == NULL) return true; - FILE* file = fopen(filepath, "r"); + FILE* file = os::fopen(filepath, "r"); if (file == NULL) return true; // AARCH64 defaults to noexecstack. All others default to execstack. diff --git a/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp b/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp index d3c5ef3fd7d7d831b1a06e0e0c1dbb9b18bd3fd2..b0fa227ef7c05cd30d3a34fedabc422246061889 100644 --- a/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "gc/z/zErrno.hpp" #include "gc/z/zMountPoint_linux.hpp" #include "runtime/globals.hpp" +#include "runtime/os.hpp" #include #include @@ -70,7 +71,7 @@ char* ZMountPoint::get_mountpoint(const char* line, const char* filesystem) cons } void ZMountPoint::get_mountpoints(const char* filesystem, ZArray* mountpoints) const { - FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r"); + FILE* fd = os::fopen(PROC_SELF_MOUNTINFO, "r"); if (fd == NULL) { ZErrno err; log_error_p(gc)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string()); diff --git a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp index 951b98d6cce40ba9d751cc3cc9ce3bba7f65c88c..b434acc3215eb3548c160491d0839bb52f99271c 100644 --- a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -329,7 +329,7 @@ void ZPhysicalMemoryBacking::warn_available_space(size_t max_capacity) const { void ZPhysicalMemoryBacking::warn_max_map_count(size_t max_capacity) const { const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT; - FILE* const file = fopen(filename, "r"); + FILE* const file = os::fopen(filename, "r"); if (file == NULL) { // Failed to open file, skip check log_debug_p(gc, init)("Failed to open %s", filename); diff --git a/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp b/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp index 95b13841b2a8f244ef7badeea45749f01f0d223d..1e1becf5a140f5db0666e659b764f2a254b25e90 100644 --- a/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp +++ b/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ #ifndef OS_LINUX_GC_Z_ZSYSCALL_LINUX_HPP #define OS_LINUX_GC_Z_ZSYSCALL_LINUX_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" // Flags for get_mempolicy() #ifndef MPOL_F_NODE diff --git a/src/hotspot/os/linux/osContainer_linux.hpp b/src/hotspot/os/linux/osContainer_linux.hpp index 940bc0e3874bf00048722622e99e3defee97a211..1ba4a9dabdc88eecd613920db168b6968f0d86b7 100644 --- a/src/hotspot/os/linux/osContainer_linux.hpp +++ b/src/hotspot/os/linux/osContainer_linux.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #define OSCONTAINER_ERROR (-2) diff --git a/src/hotspot/os/linux/osThread_linux.hpp b/src/hotspot/os/linux/osThread_linux.hpp index 01c93f6eb9a8df29443b35ea8e41c36129fe23e4..7dbe92b415eae840f2cc7b1139a46b25e565ff74 100644 --- a/src/hotspot/os/linux/osThread_linux.hpp +++ b/src/hotspot/os/linux/osThread_linux.hpp @@ -55,13 +55,7 @@ // Used for debugging, return a unique integer for each thread. int thread_identifier() const { return _thread_id; } #endif -#ifdef ASSERT - // We expect no reposition failures so kill vm if we get one. - // - bool valid_reposition_failure() { - return false; - } -#endif // ASSERT + pthread_t pthread_id() const { return _pthread_id; } diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index e75e2e51b0e467b99b16e4904e551185b933a22b..28477ba8bcb334097043b0413e9f6502496fef9a 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -258,7 +258,7 @@ bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu memset(pticks, 0, sizeof(CPUPerfTicks)); - if ((fh = fopen("/proc/stat", "r")) == NULL) { + if ((fh = os::fopen("/proc/stat", "r")) == NULL) { return false; } @@ -352,7 +352,7 @@ void os::Linux::initialize_system_info() { pid_t pid = os::Linux::gettid(); char fname[32]; jio_snprintf(fname, sizeof(fname), "/proc/%d", pid); - FILE *fp = fopen(fname, "r"); + FILE *fp = os::fopen(fname, "r"); if (fp == NULL) { unsafe_chroot_detected = true; } else { @@ -786,7 +786,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, assert(thread->osthread() == NULL, "caller responsible"); // Allocate the OSThread object - OSThread* osthread = new OSThread(NULL, NULL); + OSThread* osthread = new OSThread(); if (osthread == NULL) { return false; } @@ -806,7 +806,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, // Calculate stack size if it's not specified by caller. size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size); - // In glibc versions prior to 2.7 the guard size mechanism + // In glibc versions prior to 2.27 the guard size mechanism // is not implemented properly. The posix standard requires adding // the size of the guard pages to the stack size, instead Linux // takes the space out of 'stacksize'. Thus we adapt the requested @@ -915,7 +915,7 @@ bool os::create_attached_thread(JavaThread* thread) { #endif // Allocate the OSThread object - OSThread* osthread = new OSThread(NULL, NULL); + OSThread* osthread = new OSThread(); if (osthread == NULL) { return false; @@ -1027,7 +1027,7 @@ bool os::is_primordial_thread(void) { // Find the virtual memory area that contains addr static bool find_vma(address addr, address* vma_low, address* vma_high) { - FILE *fp = fopen("/proc/self/maps", "r"); + FILE *fp = os::fopen("/proc/self/maps", "r"); if (fp) { address low, high; while (!feof(fp)) { @@ -1139,7 +1139,7 @@ void os::Linux::capture_initial_stack(size_t max_size) { char stat[2048]; int statlen; - fp = fopen("/proc/self/stat", "r"); + fp = os::fopen("/proc/self/stat", "r"); if (fp) { statlen = fread(stat, 1, 2047, fp); stat[statlen] = '\0'; @@ -2004,7 +2004,7 @@ static void parse_os_info_helper(FILE* fp, char* distro, size_t length, bool get } static void parse_os_info(char* distro, size_t length, const char* file) { - FILE* fp = fopen(file, "r"); + FILE* fp = os::fopen(file, "r"); if (fp != NULL) { // if suse format, print out first line bool get_first_line = (strcmp(file, "/etc/SuSE-release") == 0); @@ -2065,7 +2065,7 @@ void os::Linux::print_system_memory_info(outputStream* st) { } bool os::Linux::query_process_memory_info(os::Linux::meminfo_t* info) { - FILE* f = ::fopen("/proc/self/status", "r"); + FILE* f = os::fopen("/proc/self/status", "r"); const int num_values = sizeof(os::Linux::meminfo_t) / sizeof(size_t); int num_found = 0; char buf[256]; @@ -2312,7 +2312,7 @@ void os::print_memory_info(outputStream* st) { static bool print_model_name_and_flags(outputStream* st, char* buf, size_t buflen) { #if defined(IA32) || defined(AMD64) // Other platforms have less repetitive cpuinfo files - FILE *fp = fopen("/proc/cpuinfo", "r"); + FILE *fp = os::fopen("/proc/cpuinfo", "r"); if (fp) { bool model_name_printed = false; while (!feof(fp)) { @@ -2416,7 +2416,7 @@ const char* search_string = "Processor"; // Parses the cpuinfo file for string representing the model name. void os::get_summary_cpu_info(char* cpuinfo, size_t length) { - FILE* fp = fopen("/proc/cpuinfo", "r"); + FILE* fp = os::fopen("/proc/cpuinfo", "r"); if (fp != NULL) { while (!feof(fp)) { char buf[256]; @@ -3551,7 +3551,7 @@ static void set_coredump_filter(CoredumpFilterBit bit) { FILE *f; long cdm; - if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) { + if ((f = os::fopen("/proc/self/coredump_filter", "r+")) == NULL) { return; } @@ -3590,7 +3590,7 @@ static size_t scan_default_large_page_size() { // If we can't determine the value (e.g. /proc is not mounted, or the text // format has been changed), we'll set largest page size to 0 - FILE *fp = fopen("/proc/meminfo", "r"); + FILE *fp = os::fopen("/proc/meminfo", "r"); if (fp) { while (!feof(fp)) { int x = 0; @@ -4268,7 +4268,7 @@ int os::Linux::get_namespace_pid(int vmid) { int retpid = -1; snprintf(fname, sizeof(fname), "/proc/%d/status", vmid); - FILE *fp = fopen(fname, "r"); + FILE *fp = os::fopen(fname, "r"); if (fp) { int pid, nspid; @@ -5077,7 +5077,7 @@ static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { FILE *fp; snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid); - fp = fopen(proc_name, "r"); + fp = os::fopen(proc_name, "r"); if (fp == NULL) return -1; statlen = fread(stat, 1, 2047, fp); stat[statlen] = '\0'; @@ -5380,21 +5380,20 @@ bool os::supports_map_sync() { } void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) { + // Note: all ranges are "[..)" unsigned long long start = (unsigned long long)addr; unsigned long long end = start + bytes; - FILE* f = ::fopen("/proc/self/maps", "r"); + FILE* f = os::fopen("/proc/self/maps", "r"); int num_found = 0; if (f != NULL) { - st->print("Range [%llx-%llx) contains: ", start, end); + st->print_cr("Range [%llx-%llx) contains: ", start, end); char line[512]; while(fgets(line, sizeof(line), f) == line) { - unsigned long long a1 = 0; - unsigned long long a2 = 0; - if (::sscanf(line, "%llx-%llx", &a1, &a2) == 2) { + unsigned long long segment_start = 0; + unsigned long long segment_end = 0; + if (::sscanf(line, "%llx-%llx", &segment_start, &segment_end) == 2) { // Lets print out every range which touches ours. - if ((a1 >= start && a1 < end) || // left leg in - (a2 >= start && a2 < end) || // right leg in - (a1 < start && a2 >= end)) { // superimposition + if (segment_start < end && segment_end > start) { num_found ++; st->print("%s", line); // line includes \n } @@ -5402,7 +5401,7 @@ void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) { } ::fclose(f); if (num_found == 0) { - st->print("nothing."); + st->print_cr("nothing."); } st->cr(); } diff --git a/src/hotspot/os/linux/os_perf_linux.cpp b/src/hotspot/os/linux/os_perf_linux.cpp index 7c42379a0a710de20b2f2f53c82d2fab45434d85..8d244887d4bdb8bd35cea8134c3941ddcb59b34a 100644 --- a/src/hotspot/os/linux/os_perf_linux.cpp +++ b/src/hotspot/os/linux/os_perf_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,10 +28,9 @@ #include "os_linux.inline.hpp" #include "runtime/os.hpp" #include "runtime/os_perf.hpp" +#include "runtime/vm_version.hpp" #include "utilities/globalDefinitions.hpp" -#include CPU_HEADER(vm_version_ext) - #include #include #include @@ -235,7 +234,7 @@ static int SCANF_ARGS(2, 0) vread_statdata(const char* procfile, _SCANFMT_ const int n; char buf[2048]; - if ((f = fopen(procfile, "r")) == NULL) { + if ((f = os::fopen(procfile, "r")) == NULL) { return -1; } @@ -272,7 +271,7 @@ static int SCANF_ARGS(2, 3) read_statdata(const char* procfile, _SCANFMT_ const static FILE* open_statfile(void) { FILE *f; - if ((f = fopen("/proc/stat", "r")) == NULL) { + if ((f = os::fopen("/proc/stat", "r")) == NULL) { static int haveWarned = 0; if (!haveWarned) { haveWarned = 1; @@ -723,7 +722,7 @@ void SystemProcessInterface::SystemProcesses::ProcessIterator::get_exe_name() { jio_snprintf(buffer, PATH_MAX, "/proc/%s/stat", _entry->d_name); buffer[PATH_MAX - 1] = '\0'; - if ((fp = fopen(buffer, "r")) != NULL) { + if ((fp = os::fopen(buffer, "r")) != NULL) { if (fgets(buffer, PATH_MAX, fp) != NULL) { char* start, *end; // exe-name is between the first pair of ( and ) @@ -751,7 +750,7 @@ char* SystemProcessInterface::SystemProcesses::ProcessIterator::get_cmdline() { jio_snprintf(buffer, PATH_MAX, "/proc/%s/cmdline", _entry->d_name); buffer[PATH_MAX - 1] = '\0'; - if ((fp = fopen(buffer, "r")) != NULL) { + if ((fp = os::fopen(buffer, "r")) != NULL) { size_t size = 0; char dummy; @@ -927,11 +926,12 @@ CPUInformationInterface::CPUInformationInterface() { bool CPUInformationInterface::initialize() { _cpu_info = new CPUInformation(); - _cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads()); - _cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores()); - _cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets()); - _cpu_info->set_cpu_name(VM_Version_Ext::cpu_name()); - _cpu_info->set_cpu_description(VM_Version_Ext::cpu_description()); + VM_Version::initialize_cpu_information(); + _cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads()); + _cpu_info->set_number_of_cores(VM_Version::number_of_cores()); + _cpu_info->set_number_of_sockets(VM_Version::number_of_sockets()); + _cpu_info->set_cpu_name(VM_Version::cpu_name()); + _cpu_info->set_cpu_description(VM_Version::cpu_description()); return true; } diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 8ec5b152d34d26871aba02f6c90be03484e42080..31c1cbc3d4faacffa7e051ac4b7f415b9bafc2af 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -675,13 +675,13 @@ const char* os::get_current_directory(char *buf, size_t buflen) { return getcwd(buf, buflen); } -FILE* os::open(int fd, const char* mode) { +FILE* os::fdopen(int fd, const char* mode) { return ::fdopen(fd, mode); } -size_t os::write(int fd, const void *buf, unsigned int nBytes) { - size_t res; - RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res); +ssize_t os::write(int fd, const void *buf, unsigned int nBytes) { + ssize_t res; + RESTARTABLE(::write(fd, buf, (size_t) nBytes), res); return res; } @@ -689,10 +689,6 @@ ssize_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) { return ::pread(fd, buf, nBytes, offset); } -int os::close(int fd) { - return ::close(fd); -} - void os::flockfile(FILE* fp) { ::flockfile(fp); } @@ -720,10 +716,6 @@ int os::socket_close(int fd) { return ::close(fd); } -int os::socket(int domain, int type, int protocol) { - return ::socket(domain, type, protocol); -} - int os::recv(int fd, char* buf, size_t nBytes, uint flags) { RESTARTABLE_RETURN_INT(::recv(fd, buf, nBytes, flags)); } @@ -1610,9 +1602,7 @@ int os::PlatformEvent::park(jlong millis) { status = pthread_cond_timedwait(_cond, _mutex, &abst); assert_status(status == 0 || status == ETIMEDOUT, status, "cond_timedwait"); - // OS-level "spurious wakeups" are ignored unless the archaic - // FilterSpuriousWakeups is set false. That flag should be obsoleted. - if (!FilterSpuriousWakeups) break; + // OS-level "spurious wakeups" are ignored if (status == ETIMEDOUT) break; } --_nParked; diff --git a/src/hotspot/os/posix/perfMemory_posix.cpp b/src/hotspot/os/posix/perfMemory_posix.cpp index a89947f32edc1da75a7d9622b8163ae7b5151757..7fcf867b3f86a6cdae6bb9a49bce15a8f9baf3c0 100644 --- a/src/hotspot/os/posix/perfMemory_posix.cpp +++ b/src/hotspot/os/posix/perfMemory_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -98,21 +98,20 @@ static void save_memory_to_file(char* addr, size_t size) { const char* destfile = PerfMemory::get_perfdata_file_path(); assert(destfile[0] != '\0', "invalid PerfData file path"); - int result; + int fd; - RESTARTABLE(os::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR), - result); - if (result == OS_ERR) { + RESTARTABLE(os::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR), fd); + if (fd == OS_ERR) { if (PrintMiscellaneous && Verbose) { warning("Could not create Perfdata save file: %s: %s\n", destfile, os::strerror(errno)); } } else { - int fd = result; + ssize_t result; for (size_t remaining = size; remaining > 0;) { - RESTARTABLE(::write(fd, addr, remaining), result); + result = os::write(fd, addr, remaining); if (result == OS_ERR) { if (PrintMiscellaneous && Verbose) { warning("Could not write Perfdata save file: %s: %s\n", @@ -331,7 +330,7 @@ static DIR *open_directory_secure(const char* dirname) { // Determine if the open directory is secure. if (!is_dirfd_secure(fd)) { // The directory is not a secure directory. - os::close(fd); + ::close(fd); return dirp; } @@ -339,21 +338,21 @@ static DIR *open_directory_secure(const char* dirname) { dirp = ::opendir(dirname); if (dirp == NULL) { // The directory doesn't exist, close fd and return. - os::close(fd); + ::close(fd); return dirp; } // Check to make sure fd and dirp are referencing the same file system object. if (!is_same_fsobject(fd, AIX_ONLY(dirp->dd_fd) NOT_AIX(dirfd(dirp)))) { // The directory is not secure. - os::close(fd); + ::close(fd); os::closedir(dirp); dirp = NULL; return dirp; } // Close initial open now that we know directory is secure - os::close(fd); + ::close(fd); return dirp; } @@ -842,9 +841,9 @@ static int create_sharedmem_resources(const char* dirname, const char* filename, // Open the filename in the current directory. // Cannot use O_TRUNC here; truncation of an existing file has to happen // after the is_file_secure() check below. - int result; - RESTARTABLE(os::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR), result); - if (result == OS_ERR) { + int fd; + RESTARTABLE(os::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR), fd); + if (fd == OS_ERR) { if (PrintMiscellaneous && Verbose) { if (errno == ELOOP) { warning("file %s is a symlink and is not secure\n", filename); @@ -860,15 +859,14 @@ static int create_sharedmem_resources(const char* dirname, const char* filename, // close the directory and reset the current working directory close_directory_secure_cwd(dirp, saved_cwd_fd); - // save the file descriptor - int fd = result; - // check to see if the file is secure if (!is_file_secure(fd, filename)) { ::close(fd); return -1; } + ssize_t result; + // truncate the file to get rid of any existing data RESTARTABLE(::ftruncate(fd, (off_t)0), result); if (result == OS_ERR) { @@ -895,7 +893,7 @@ static int create_sharedmem_resources(const char* dirname, const char* filename, int zero_int = 0; result = (int)os::seek_to_file_offset(fd, (jlong)(seekpos)); if (result == -1 ) break; - RESTARTABLE(::write(fd, &zero_int, 1), result); + result = os::write(fd, &zero_int, 1); if (result != 1) { if (errno == ENOSPC) { warning("Insufficient space for shared memory file:\n %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename); @@ -1028,7 +1026,7 @@ static char* mmap_create_shared(size_t size) { // static void unmap_shared(char* addr, size_t bytes) { int res; - if (MemTracker::tracking_level() > NMT_minimal) { + if (MemTracker::enabled()) { // Note: Tracker contains a ThreadCritical. Tracker tkr(Tracker::release); res = ::munmap(addr, bytes); diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index 2c020a79408049797d5c2f1fcc1e5de8d968323e..895c3cc09ae88c5d7ec04c57e8716062b46a707a 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -562,6 +562,11 @@ int JVM_HANDLE_XXX_SIGNAL(int sig, siginfo_t* info, { assert(info != NULL && ucVoid != NULL, "sanity"); + if (sig == BREAK_SIGNAL) { + assert(!ReduceSignalUsage, "Should not happen with -Xrs/-XX:+ReduceSignalUsage"); + return true; // ignore it + } + // Note: it's not uncommon that JNI code uses signal/sigset to install, // then restore certain signal handler (e.g. to temporarily block SIGPIPE, // or have a SIGILL handler when detecting CPU type). When that happens, @@ -1197,7 +1202,7 @@ int os::get_signal_number(const char* signal_name) { return -1; } -void set_signal_handler(int sig) { +void set_signal_handler(int sig, bool do_check = true) { // Check for overwrite. struct sigaction oldAct; sigaction(sig, (struct sigaction*)NULL, &oldAct); @@ -1241,7 +1246,7 @@ void set_signal_handler(int sig) { // Save handler setup for later checking vm_handlers.set(sig, &sigAct); - do_check_signal_periodically[sig] = true; + do_check_signal_periodically[sig] = do_check; int ret = sigaction(sig, &sigAct, &oldAct); assert(ret == 0, "check"); @@ -1279,7 +1284,12 @@ void install_signal_handlers() { set_signal_handler(SIGFPE); PPC64_ONLY(set_signal_handler(SIGTRAP);) set_signal_handler(SIGXFSZ); - + if (!ReduceSignalUsage) { + // This is just for early initialization phase. Intercepting the signal here reduces the risk + // that an attach client accidentally forces HotSpot to quit prematurely. We skip the periodic + // check because late initialization will overwrite it to UserHandler. + set_signal_handler(BREAK_SIGNAL, false); + } #if defined(__APPLE__) // lldb (gdb) installs both standard BSD signal handlers, and mach exception // handlers. By replacing the existing task exception handler, we disable lldb's mach diff --git a/src/hotspot/os/posix/signals_posix.hpp b/src/hotspot/os/posix/signals_posix.hpp index 373a02ff3a31475e9ca05865b9651ce001b01263..2efdb374c4eb2e1ed9750882831f144b6de070f2 100644 --- a/src/hotspot/os/posix/signals_posix.hpp +++ b/src/hotspot/os/posix/signals_posix.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_POSIX_SIGNALS_POSIX_HPP #define OS_POSIX_SIGNALS_POSIX_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class outputStream; diff --git a/src/hotspot/os/posix/threadLocalStorage_posix.cpp b/src/hotspot/os/posix/threadLocalStorage_posix.cpp index cc703ef811f94fe140bece77f8da533ddb0f9f71..25bbbe2244f788d6302235e1517c367b45906712 100644 --- a/src/hotspot/os/posix/threadLocalStorage_posix.cpp +++ b/src/hotspot/os/posix/threadLocalStorage_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ */ #include "runtime/threadLocalStorage.hpp" +#include "utilities/debug.hpp" #include static pthread_key_t _thread_key; diff --git a/src/hotspot/os/windows/gc/z/zMapper_windows.hpp b/src/hotspot/os/windows/gc/z/zMapper_windows.hpp index 4db80c899561d51cb1227cbd76b5e7b80c52bb4d..3e47b470f5f28445f5dbe56e83ab447a971ceb6c 100644 --- a/src/hotspot/os/windows/gc/z/zMapper_windows.hpp +++ b/src/hotspot/os/windows/gc/z/zMapper_windows.hpp @@ -24,7 +24,7 @@ #ifndef OS_WINDOWS_GC_Z_ZMAPPER_WINDOWS_HPP #define OS_WINDOWS_GC_Z_ZMAPPER_WINDOWS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" #include diff --git a/src/hotspot/os/windows/iphlp_interface.hpp b/src/hotspot/os/windows/iphlp_interface.hpp index 0ebe971a5f17947ca346a49aea0f517f880b00de..3e7e0adef6500d7f25716127f81e8cc4df99eb91 100644 --- a/src/hotspot/os/windows/iphlp_interface.hpp +++ b/src/hotspot/os/windows/iphlp_interface.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_WINDOWS_IPHLP_INTERFACE_HPP #define OS_WINDOWS_IPHLP_INTERFACE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" #include #include diff --git a/src/hotspot/os/windows/osThread_windows.hpp b/src/hotspot/os/windows/osThread_windows.hpp index 74b50100663396c3a9b3b981914241617a48ef0b..5bd07646b1718b51e3f201c7ad938493d4cf33e8 100644 --- a/src/hotspot/os/windows/osThread_windows.hpp +++ b/src/hotspot/os/windows/osThread_windows.hpp @@ -49,13 +49,6 @@ // Used for debugging, return a unique integer for each thread. int thread_identifier() const { return _thread_id; } #endif -#ifdef ASSERT - // We expect no reposition failures so kill vm if we get one - // - bool valid_reposition_failure() { - return false; - } -#endif // ASSERT private: void pd_initialize(); diff --git a/src/hotspot/os/windows/os_perf_windows.cpp b/src/hotspot/os/windows/os_perf_windows.cpp index 3ce1137f37d780dab850841bef7de849bcd6acca..fc2a5631b706ec96ae25b2c729d13c01d5be9a09 100644 --- a/src/hotspot/os/windows/os_perf_windows.cpp +++ b/src/hotspot/os/windows/os_perf_windows.cpp @@ -32,9 +32,9 @@ #include "runtime/os_perf.hpp" #include "runtime/os.hpp" #include "runtime/semaphore.inline.hpp" +#include "runtime/vm_version.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -#include CPU_HEADER(vm_version_ext) #include #include #include @@ -1434,11 +1434,12 @@ CPUInformationInterface::CPUInformationInterface() : _cpu_info(NULL) {} bool CPUInformationInterface::initialize() { _cpu_info = new CPUInformation(); - _cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads()); - _cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores()); - _cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets()); - _cpu_info->set_cpu_name(VM_Version_Ext::cpu_name()); - _cpu_info->set_cpu_description(VM_Version_Ext::cpu_description()); + VM_Version::initialize_cpu_information(); + _cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads()); + _cpu_info->set_number_of_cores(VM_Version::number_of_cores()); + _cpu_info->set_number_of_sockets(VM_Version::number_of_sockets()); + _cpu_info->set_cpu_name(VM_Version::cpu_name()); + _cpu_info->set_cpu_description(VM_Version::cpu_description()); return true; } diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 6f8c88d764da645dda82dcec3df6867efbcf4fcd..ed4ba3e1fc2ce3074c31fbd2dc7d9e31d8bc5e8c 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -529,7 +529,7 @@ static unsigned __stdcall thread_native_entry(Thread* thread) { res = 20115; // java thread } - log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id()); + log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", stacksize: " SIZE_FORMAT "k).", os::current_thread_id(), thread->stack_size() / 1024); #ifdef USE_VECTORED_EXCEPTION_HANDLING // Any exception is caught by the Vectored Exception Handler, so VM can @@ -568,7 +568,7 @@ static unsigned __stdcall thread_native_entry(Thread* thread) { static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle, int thread_id) { // Allocate the OSThread object - OSThread* osthread = new OSThread(NULL, NULL); + OSThread* osthread = new OSThread(); if (osthread == NULL) return NULL; // Initialize the JDK library's interrupt event. @@ -671,11 +671,14 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, unsigned thread_id; // Allocate the OSThread object - OSThread* osthread = new OSThread(NULL, NULL); + OSThread* osthread = new OSThread(); if (osthread == NULL) { return false; } + // Initial state is ALLOCATED but not INITIALIZED + osthread->set_state(ALLOCATED); + // Initialize the JDK library's interrupt event. // This should really be done when OSThread is constructed, // but there is no way for a constructor to report failure to @@ -777,7 +780,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, osthread->set_thread_handle(thread_handle); osthread->set_thread_id(thread_id); - // Initial thread state is INITIALIZED, not SUSPENDED + // Thread state now is INITIALIZED, not SUSPENDED osthread->set_state(INITIALIZED); // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain @@ -1550,7 +1553,7 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) { || // Read location of signature (sizeof(signature_offset) != - (os::read(fd, (void*)&signature_offset, sizeof(signature_offset)))) + (::read(fd, (void*)&signature_offset, sizeof(signature_offset)))) || // Go to COFF File Header in dll // that is located after "signature" (4 bytes long) @@ -1559,7 +1562,7 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) { || // Read field that contains code of architecture // that dll was built for - (sizeof(lib_arch) != (os::read(fd, (void*)&lib_arch, sizeof(lib_arch)))) + (sizeof(lib_arch) != (::read(fd, (void*)&lib_arch, sizeof(lib_arch)))) ); ::close(fd); @@ -4751,18 +4754,14 @@ int os::open(const char *path, int oflag, int mode) { return fd; } -FILE* os::open(int fd, const char* mode) { +FILE* os::fdopen(int fd, const char* mode) { return ::_fdopen(fd, mode); } -size_t os::write(int fd, const void *buf, unsigned int nBytes) { +ssize_t os::write(int fd, const void *buf, unsigned int nBytes) { return ::write(fd, buf, nBytes); } -int os::close(int fd) { - return ::close(fd); -} - void os::exit(int num) { win32::exit_process_or_thread(win32::EPT_PROCESS, num); } @@ -5722,10 +5721,6 @@ int os::socket_close(int fd) { return ::closesocket(fd); } -int os::socket(int domain, int type, int protocol) { - return ::socket(domain, type, protocol); -} - int os::connect(int fd, struct sockaddr* him, socklen_t len) { return ::connect(fd, him, len); } diff --git a/src/hotspot/os/windows/pdh_interface.hpp b/src/hotspot/os/windows/pdh_interface.hpp index 743c737d9982c6f1fca37eac2637ff4a37c6da72..151f9edd0e94906b1e56473a69337b7e3e8b9231 100644 --- a/src/hotspot/os/windows/pdh_interface.hpp +++ b/src/hotspot/os/windows/pdh_interface.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_WINDOWS_PDH_INTERFACE_HPP #define OS_WINDOWS_PDH_INTERFACE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include #include diff --git a/src/hotspot/os/windows/perfMemory_windows.cpp b/src/hotspot/os/windows/perfMemory_windows.cpp index 600eb8882f9e4a51be91aa440713f0ff3dd29f36..0a53a94957c3d6d98db7dbe76637ed526be759ff 100644 --- a/src/hotspot/os/windows/perfMemory_windows.cpp +++ b/src/hotspot/os/windows/perfMemory_windows.cpp @@ -1834,7 +1834,7 @@ void PerfMemory::detach(char* addr, size_t bytes) { return; } - if (MemTracker::tracking_level() > NMT_minimal) { + if (MemTracker::enabled()) { // it does not go through os api, the operation has to record from here Tracker tkr(Tracker::release); remove_file_mapping(addr); diff --git a/src/hotspot/os/windows/threadLocalStorage_windows.cpp b/src/hotspot/os/windows/threadLocalStorage_windows.cpp index 5648a672d71667ec946e491c2de6f1f7cf03d37c..7d809518aab33f3d958465de61be07b39d49a491 100644 --- a/src/hotspot/os/windows/threadLocalStorage_windows.cpp +++ b/src/hotspot/os/windows/threadLocalStorage_windows.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "runtime/threadLocalStorage.hpp" +#include "utilities/debug.hpp" #include static DWORD _thread_key; diff --git a/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.hpp index 6f08cb351252dbc92dd240104e45f119020de8ae..580daec9ebf2ecce47736a166e180d0440a9e547 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.hpp +++ b/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -27,163 +27,6 @@ #ifndef OS_CPU_BSD_AARCH64_COPY_BSD_AARCH64_HPP #define OS_CPU_BSD_AARCH64_COPY_BSD_AARCH64_HPP -#define COPY_SMALL(from, to, count) \ -{ \ - long tmp0, tmp1, tmp2, tmp3; \ - long tmp4, tmp5, tmp6, tmp7; \ - __asm volatile( \ -" adr %[t0], 0f;\n" \ -" add %[t0], %[t0], %[cnt], lsl #5;\n" \ -" br %[t0];\n" \ -" .align 5;\n" \ -"0:" \ -" b 1f;\n" \ -" .align 5;\n" \ -" ldr %[t0], [%[s], #0];\n" \ -" str %[t0], [%[d], #0];\n" \ -" b 1f;\n" \ -" .align 5;\n" \ -" ldp %[t0], %[t1], [%[s], #0];\n" \ -" stp %[t0], %[t1], [%[d], #0];\n" \ -" b 1f;\n" \ -" .align 5;\n" \ -" ldp %[t0], %[t1], [%[s], #0];\n" \ -" ldr %[t2], [%[s], #16];\n" \ -" stp %[t0], %[t1], [%[d], #0];\n" \ -" str %[t2], [%[d], #16];\n" \ -" b 1f;\n" \ -" .align 5;\n" \ -" ldp %[t0], %[t1], [%[s], #0];\n" \ -" ldp %[t2], %[t3], [%[s], #16];\n" \ -" stp %[t0], %[t1], [%[d], #0];\n" \ -" stp %[t2], %[t3], [%[d], #16];\n" \ -" b 1f;\n" \ -" .align 5;\n" \ -" ldp %[t0], %[t1], [%[s], #0];\n" \ -" ldp %[t2], %[t3], [%[s], #16];\n" \ -" ldr %[t4], [%[s], #32];\n" \ -" stp %[t0], %[t1], [%[d], #0];\n" \ -" stp %[t2], %[t3], [%[d], #16];\n" \ -" str %[t4], [%[d], #32];\n" \ -" b 1f;\n" \ -" .align 5;\n" \ -" ldp %[t0], %[t1], [%[s], #0];\n" \ -" ldp %[t2], %[t3], [%[s], #16];\n" \ -" ldp %[t4], %[t5], [%[s], #32];\n" \ -"2:" \ -" stp %[t0], %[t1], [%[d], #0];\n" \ -" stp %[t2], %[t3], [%[d], #16];\n" \ -" stp %[t4], %[t5], [%[d], #32];\n" \ -" b 1f;\n" \ -" .align 5;\n" \ -" ldr %[t6], [%[s], #0];\n" \ -" ldp %[t0], %[t1], [%[s], #8];\n" \ -" ldp %[t2], %[t3], [%[s], #24];\n" \ -" ldp %[t4], %[t5], [%[s], #40];\n" \ -" str %[t6], [%[d]], #8;\n" \ -" b 2b;\n" \ -" .align 5;\n" \ -" ldp %[t0], %[t1], [%[s], #0];\n" \ -" ldp %[t2], %[t3], [%[s], #16];\n" \ -" ldp %[t4], %[t5], [%[s], #32];\n" \ -" ldp %[t6], %[t7], [%[s], #48];\n" \ -" stp %[t0], %[t1], [%[d], #0];\n" \ -" stp %[t2], %[t3], [%[d], #16];\n" \ -" stp %[t4], %[t5], [%[d], #32];\n" \ -" stp %[t6], %[t7], [%[d], #48];\n" \ -"1:" \ - \ - : [s]"+r"(from), [d]"+r"(to), [cnt]"+r"(count), \ - [t0]"=&r"(tmp0), [t1]"=&r"(tmp1), [t2]"=&r"(tmp2), [t3]"=&r"(tmp3), \ - [t4]"=&r"(tmp4), [t5]"=&r"(tmp5), [t6]"=&r"(tmp6), [t7]"=&r"(tmp7) \ - : \ - : "memory", "cc"); \ -} - -static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); - if (__builtin_expect(count <= 8, 1)) { - COPY_SMALL(from, to, count); - return; - } - _Copy_conjoint_words(from, to, count); -} - -static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - if (__builtin_constant_p(count)) { - memcpy(to, from, count * sizeof(HeapWord)); - return; - } - __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); - if (__builtin_expect(count <= 8, 1)) { - COPY_SMALL(from, to, count); - return; - } - _Copy_disjoint_words(from, to, count); -} - -static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { - __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); - if (__builtin_expect(count <= 8, 1)) { - COPY_SMALL(from, to, count); - return; - } - _Copy_disjoint_words(from, to, count); -} - -static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_conjoint_words(from, to, count); -} - -static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_disjoint_words(from, to, count); -} - -static void pd_conjoint_bytes(const void* from, void* to, size_t count) { - (void)memmove(to, from, count); -} - -static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { - pd_conjoint_bytes(from, to, count); -} - -static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { - _Copy_conjoint_jshorts_atomic(from, to, count); -} - -static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { - _Copy_conjoint_jints_atomic(from, to, count); -} - -static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { - _Copy_conjoint_jlongs_atomic(from, to, count); -} - -static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { - assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); - _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); -} - -static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_bytes(from, to, count); -} - -static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_jshorts(from, to, count); -} - -static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_jints(from, to, count); -} - -static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_jlongs(from, to, count); -} - -static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { - assert(!UseCompressedOops, "foo!"); - assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); - _Copy_arrayof_conjoint_jlongs(from, to, count); -} +// Empty for build system #endif // OS_CPU_BSD_AARCH64_COPY_BSD_AARCH64_HPP diff --git a/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp index d8b1a0b20ef3287cb65acb47686f17b9c1a07e70..f07f22bc0cd7a3e8977883bc62f214f4e3ad942f 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp +++ b/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -32,7 +32,9 @@ frame JavaThread::pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); vmassert(_anchor.last_Java_pc() != NULL, "not walkable"); - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + frame f = frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + f.set_sp_is_trusted(); + return f; } // For Forte Analyzer AsyncGetCallTrace profiling support - thread is diff --git a/src/hotspot/os_cpu/bsd_x86/bsd_x86_32.S b/src/hotspot/os_cpu/bsd_x86/bsd_x86_32.S index 0d22a6a6790237637484b70ac27dad913ae0de50..02231040e15bda886acc2c0024f404c458b1b1d6 100644 --- a/src/hotspot/os_cpu/bsd_x86/bsd_x86_32.S +++ b/src/hotspot/os_cpu/bsd_x86/bsd_x86_32.S @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,6 @@ # point or use it in the same manner as does the server # compiler. - .globl SYMBOL(_Copy_conjoint_bytes) .globl SYMBOL(_Copy_arrayof_conjoint_bytes) .globl SYMBOL(_Copy_conjoint_jshorts_atomic) .globl SYMBOL(_Copy_arrayof_conjoint_jshorts) @@ -72,117 +71,10 @@ SYMBOL(SpinPause): movl $1, %eax ret - # Support for void Copy::conjoint_bytes(void* from, - # void* to, - # size_t count) - .p2align 4,,15 - ELF_TYPE(_Copy_conjoint_bytes,@function) -SYMBOL(_Copy_conjoint_bytes): - pushl %esi - movl 4+12(%esp),%ecx # count - pushl %edi - movl 8+ 4(%esp),%esi # from - movl 8+ 8(%esp),%edi # to - cmpl %esi,%edi - leal -1(%esi,%ecx),%eax # from + count - 1 - jbe cb_CopyRight - cmpl %eax,%edi - jbe cb_CopyLeft - # copy from low to high -cb_CopyRight: - cmpl $3,%ecx - jbe 5f # <= 3 bytes - # align source address at dword address boundary - movl %ecx,%eax # original count - movl $4,%ecx - subl %esi,%ecx - andl $3,%ecx # prefix byte count - jz 1f # no prefix - subl %ecx,%eax # byte count less prefix - # copy prefix - subl %esi,%edi -0: movb (%esi),%dl - movb %dl,(%edi,%esi,1) - addl $1,%esi - subl $1,%ecx - jnz 0b - addl %esi,%edi -1: movl %eax,%ecx # byte count less prefix - shrl $2,%ecx # dword count - jz 4f # no dwords to move - cmpl $32,%ecx - jbe 2f # <= 32 dwords - # copy aligned dwords - rep; smovl - jmp 4f - # copy aligned dwords -2: subl %esi,%edi - .p2align 4,,15 -3: movl (%esi),%edx - movl %edx,(%edi,%esi,1) - addl $4,%esi - subl $1,%ecx - jnz 3b - addl %esi,%edi -4: movl %eax,%ecx # byte count less prefix -5: andl $3,%ecx # suffix byte count - jz 7f # no suffix - # copy suffix - xorl %eax,%eax -6: movb (%esi,%eax,1),%dl - movb %dl,(%edi,%eax,1) - addl $1,%eax - subl $1,%ecx - jnz 6b -7: popl %edi - popl %esi - ret - # copy from high to low -cb_CopyLeft: - std - leal -4(%edi,%ecx),%edi # to + count - 4 - movl %eax,%esi # from + count - 1 - movl %ecx,%eax - subl $3,%esi # from + count - 4 - cmpl $3,%ecx - jbe 5f # <= 3 bytes -1: shrl $2,%ecx # dword count - jz 4f # no dwords to move - cmpl $32,%ecx - ja 3f # > 32 dwords - # copy dwords, aligned or not - subl %esi,%edi - .p2align 4,,15 -2: movl (%esi),%edx - movl %edx,(%edi,%esi,1) - subl $4,%esi - subl $1,%ecx - jnz 2b - addl %esi,%edi - jmp 4f - # copy dwords, aligned or not -3: rep; smovl -4: movl %eax,%ecx # byte count -5: andl $3,%ecx # suffix byte count - jz 7f # no suffix - # copy suffix - subl %esi,%edi - addl $3,%esi -6: movb (%esi),%dl - movb %dl,(%edi,%esi,1) - subl $1,%esi - subl $1,%ecx - jnz 6b -7: cld - popl %edi - popl %esi - ret - # Support for void Copy::arrayof_conjoint_bytes(void* from, # void* to, # size_t count) # - # Same as _Copy_conjoint_bytes, except no source alignment check. .p2align 4,,15 ELF_TYPE(_Copy_arrayof_conjoint_bytes,@function) SYMBOL(_Copy_arrayof_conjoint_bytes): diff --git a/src/hotspot/os_cpu/bsd_x86/copy_bsd_x86.hpp b/src/hotspot/os_cpu/bsd_x86/copy_bsd_x86.hpp index 2a5498d8541aae88922896e8c2c6343616924fd4..e95c18c48a24632de6d2a337f4b5fa238a2e9b43 100644 --- a/src/hotspot/os_cpu/bsd_x86/copy_bsd_x86.hpp +++ b/src/hotspot/os_cpu/bsd_x86/copy_bsd_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,285 +25,6 @@ #ifndef OS_CPU_BSD_X86_COPY_BSD_X86_HPP #define OS_CPU_BSD_X86_COPY_BSD_X86_HPP -static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - (void)memmove(to, from, count * HeapWordSize); -#else - // Includes a zero-count check. - intx temp; - __asm__ volatile(" testl %6,%6 ;" - " jz 7f ;" - " cmpl %4,%5 ;" - " leal -4(%4,%6,4),%3;" - " jbe 1f ;" - " cmpl %7,%5 ;" - " jbe 4f ;" - "1: cmpl $32,%6 ;" - " ja 3f ;" - " subl %4,%1 ;" - "2: movl (%4),%3 ;" - " movl %7,(%5,%4,1) ;" - " addl $4,%0 ;" - " subl $1,%2 ;" - " jnz 2b ;" - " jmp 7f ;" - "3: rep; smovl ;" - " jmp 7f ;" - "4: cmpl $32,%2 ;" - " movl %7,%0 ;" - " leal -4(%5,%6,4),%1;" - " ja 6f ;" - " subl %4,%1 ;" - "5: movl (%4),%3 ;" - " movl %7,(%5,%4,1) ;" - " subl $4,%0 ;" - " subl $1,%2 ;" - " jnz 5b ;" - " jmp 7f ;" - "6: std ;" - " rep; smovl ;" - " cld ;" - "7: nop " - : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) - : "0" (from), "1" (to), "2" (count), "3" (temp) - : "memory", "flags"); -#endif // AMD64 -} - -static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - switch (count) { - case 8: to[7] = from[7]; - case 7: to[6] = from[6]; - case 6: to[5] = from[5]; - case 5: to[4] = from[4]; - case 4: to[3] = from[3]; - case 3: to[2] = from[2]; - case 2: to[1] = from[1]; - case 1: to[0] = from[0]; - case 0: break; - default: - (void)memcpy(to, from, count * HeapWordSize); - break; - } -#else - // Includes a zero-count check. - intx temp; - __asm__ volatile(" testl %6,%6 ;" - " jz 3f ;" - " cmpl $32,%6 ;" - " ja 2f ;" - " subl %4,%1 ;" - "1: movl (%4),%3 ;" - " movl %7,(%5,%4,1);" - " addl $4,%0 ;" - " subl $1,%2 ;" - " jnz 1b ;" - " jmp 3f ;" - "2: rep; smovl ;" - "3: nop " - : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) - : "0" (from), "1" (to), "2" (count), "3" (temp) - : "memory", "cc"); -#endif // AMD64 -} - -static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - switch (count) { - case 8: to[7] = from[7]; - case 7: to[6] = from[6]; - case 6: to[5] = from[5]; - case 5: to[4] = from[4]; - case 4: to[3] = from[3]; - case 3: to[2] = from[2]; - case 2: to[1] = from[1]; - case 1: to[0] = from[0]; - case 0: break; - default: - while (count-- > 0) { - *to++ = *from++; - } - break; - } -#else - // pd_disjoint_words is word-atomic in this implementation. - pd_disjoint_words(from, to, count); -#endif // AMD64 -} - -static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_conjoint_words(from, to, count); -} - -static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_disjoint_words(from, to, count); -} - -static void pd_conjoint_bytes(const void* from, void* to, size_t count) { -#ifdef AMD64 - (void)memmove(to, from, count); -#else - // Includes a zero-count check. - intx temp; - __asm__ volatile(" testl %6,%6 ;" - " jz 13f ;" - " cmpl %4,%5 ;" - " leal -1(%4,%6),%3 ;" - " jbe 1f ;" - " cmpl %7,%5 ;" - " jbe 8f ;" - "1: cmpl $3,%6 ;" - " jbe 6f ;" - " movl %6,%3 ;" - " movl $4,%2 ;" - " subl %4,%2 ;" - " andl $3,%2 ;" - " jz 2f ;" - " subl %6,%3 ;" - " rep; smovb ;" - "2: movl %7,%2 ;" - " shrl $2,%2 ;" - " jz 5f ;" - " cmpl $32,%2 ;" - " ja 4f ;" - " subl %4,%1 ;" - "3: movl (%4),%%edx ;" - " movl %%edx,(%5,%4,1);" - " addl $4,%0 ;" - " subl $1,%2 ;" - " jnz 3b ;" - " addl %4,%1 ;" - " jmp 5f ;" - "4: rep; smovl ;" - "5: movl %7,%2 ;" - " andl $3,%2 ;" - " jz 13f ;" - "6: xorl %7,%3 ;" - "7: movb (%4,%7,1),%%dl ;" - " movb %%dl,(%5,%7,1) ;" - " addl $1,%3 ;" - " subl $1,%2 ;" - " jnz 7b ;" - " jmp 13f ;" - "8: std ;" - " cmpl $12,%2 ;" - " ja 9f ;" - " movl %7,%0 ;" - " leal -1(%6,%5),%1 ;" - " jmp 11f ;" - "9: xchgl %3,%2 ;" - " movl %6,%0 ;" - " addl $1,%2 ;" - " leal -1(%7,%5),%1 ;" - " andl $3,%2 ;" - " jz 10f ;" - " subl %6,%3 ;" - " rep; smovb ;" - "10: movl %7,%2 ;" - " subl $3,%0 ;" - " shrl $2,%2 ;" - " subl $3,%1 ;" - " rep; smovl ;" - " andl $3,%3 ;" - " jz 12f ;" - " movl %7,%2 ;" - " addl $3,%0 ;" - " addl $3,%1 ;" - "11: rep; smovb ;" - "12: cld ;" - "13: nop ;" - : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) - : "0" (from), "1" (to), "2" (count), "3" (temp) - : "memory", "flags", "%edx"); -#endif // AMD64 -} - -static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { - pd_conjoint_bytes(from, to, count); -} - -static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { - _Copy_conjoint_jshorts_atomic(from, to, count); -} - -static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { -#ifdef AMD64 - _Copy_conjoint_jints_atomic(from, to, count); -#else - assert(HeapWordSize == BytesPerInt, "heapwords and jints must be the same size"); - // pd_conjoint_words is word-atomic in this implementation. - pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count); -#endif // AMD64 -} - -static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { -#ifdef AMD64 - _Copy_conjoint_jlongs_atomic(from, to, count); -#else - // Guarantee use of fild/fistp or xmm regs via some asm code, because compilers won't. - if (from > to) { - while (count-- > 0) { - __asm__ volatile("fildll (%0); fistpll (%1)" - : - : "r" (from), "r" (to) - : "memory" ); - ++from; - ++to; - } - } else { - while (count-- > 0) { - __asm__ volatile("fildll (%0,%2,8); fistpll (%1,%2,8)" - : - : "r" (from), "r" (to), "r" (count) - : "memory" ); - } - } -#endif // AMD64 -} - -static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { -#ifdef AMD64 - assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); - _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); -#else - assert(HeapWordSize == BytesPerOop, "heapwords and oops must be the same size"); - // pd_conjoint_words is word-atomic in this implementation. - pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count); -#endif // AMD64 -} - -static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_bytes(from, to, count); -} - -static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_jshorts(from, to, count); -} - -static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - _Copy_arrayof_conjoint_jints(from, to, count); -#else - pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count); -#endif // AMD64 -} - -static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - _Copy_arrayof_conjoint_jlongs(from, to, count); -#else - pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); -#endif // AMD64 -} - -static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); - _Copy_arrayof_conjoint_jlongs(from, to, count); -#else - pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count); -#endif // AMD64 -} +// Empty for build system #endif // OS_CPU_BSD_X86_COPY_BSD_X86_HPP diff --git a/src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.hpp index f50d80022ae16db558d5c706039457028cc3e9ef..302929d85750daccd1dc099d510331cdcac72d4a 100644 --- a/src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.hpp +++ b/src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,163 +26,6 @@ #ifndef OS_CPU_LINUX_AARCH64_COPY_LINUX_AARCH64_HPP #define OS_CPU_LINUX_AARCH64_COPY_LINUX_AARCH64_HPP -#define COPY_SMALL(from, to, count) \ -{ \ - long tmp0, tmp1, tmp2, tmp3; \ - long tmp4, tmp5, tmp6, tmp7; \ - __asm volatile( \ -" adr %[t0], 0f;" \ -" add %[t0], %[t0], %[cnt], lsl #5;" \ -" br %[t0];" \ -" .align 5;" \ -"0:" \ -" b 1f;" \ -" .align 5;" \ -" ldr %[t0], [%[s], #0];" \ -" str %[t0], [%[d], #0];" \ -" b 1f;" \ -" .align 5;" \ -" ldp %[t0], %[t1], [%[s], #0];" \ -" stp %[t0], %[t1], [%[d], #0];" \ -" b 1f;" \ -" .align 5;" \ -" ldp %[t0], %[t1], [%[s], #0];" \ -" ldr %[t2], [%[s], #16];" \ -" stp %[t0], %[t1], [%[d], #0];" \ -" str %[t2], [%[d], #16];" \ -" b 1f;" \ -" .align 5;" \ -" ldp %[t0], %[t1], [%[s], #0];" \ -" ldp %[t2], %[t3], [%[s], #16];" \ -" stp %[t0], %[t1], [%[d], #0];" \ -" stp %[t2], %[t3], [%[d], #16];" \ -" b 1f;" \ -" .align 5;" \ -" ldp %[t0], %[t1], [%[s], #0];" \ -" ldp %[t2], %[t3], [%[s], #16];" \ -" ldr %[t4], [%[s], #32];" \ -" stp %[t0], %[t1], [%[d], #0];" \ -" stp %[t2], %[t3], [%[d], #16];" \ -" str %[t4], [%[d], #32];" \ -" b 1f;" \ -" .align 5;" \ -" ldp %[t0], %[t1], [%[s], #0];" \ -" ldp %[t2], %[t3], [%[s], #16];" \ -" ldp %[t4], %[t5], [%[s], #32];" \ -"2:" \ -" stp %[t0], %[t1], [%[d], #0];" \ -" stp %[t2], %[t3], [%[d], #16];" \ -" stp %[t4], %[t5], [%[d], #32];" \ -" b 1f;" \ -" .align 5;" \ -" ldr %[t6], [%[s], #0];" \ -" ldp %[t0], %[t1], [%[s], #8];" \ -" ldp %[t2], %[t3], [%[s], #24];" \ -" ldp %[t4], %[t5], [%[s], #40];" \ -" str %[t6], [%[d]], #8;" \ -" b 2b;" \ -" .align 5;" \ -" ldp %[t0], %[t1], [%[s], #0];" \ -" ldp %[t2], %[t3], [%[s], #16];" \ -" ldp %[t4], %[t5], [%[s], #32];" \ -" ldp %[t6], %[t7], [%[s], #48];" \ -" stp %[t0], %[t1], [%[d], #0];" \ -" stp %[t2], %[t3], [%[d], #16];" \ -" stp %[t4], %[t5], [%[d], #32];" \ -" stp %[t6], %[t7], [%[d], #48];" \ -"1:" \ - \ - : [s]"+r"(from), [d]"+r"(to), [cnt]"+r"(count), \ - [t0]"=&r"(tmp0), [t1]"=&r"(tmp1), [t2]"=&r"(tmp2), [t3]"=&r"(tmp3), \ - [t4]"=&r"(tmp4), [t5]"=&r"(tmp5), [t6]"=&r"(tmp6), [t7]"=&r"(tmp7) \ - : \ - : "memory", "cc"); \ -} - -static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); - if (__builtin_expect(count <= 8, 1)) { - COPY_SMALL(from, to, count); - return; - } - _Copy_conjoint_words(from, to, count); -} - -static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - if (__builtin_constant_p(count)) { - memcpy(to, from, count * sizeof(HeapWord)); - return; - } - __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); - if (__builtin_expect(count <= 8, 1)) { - COPY_SMALL(from, to, count); - return; - } - _Copy_disjoint_words(from, to, count); -} - -static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { - __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); - if (__builtin_expect(count <= 8, 1)) { - COPY_SMALL(from, to, count); - return; - } - _Copy_disjoint_words(from, to, count); -} - -static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_conjoint_words(from, to, count); -} - -static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_disjoint_words(from, to, count); -} - -static void pd_conjoint_bytes(const void* from, void* to, size_t count) { - (void)memmove(to, from, count); -} - -static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { - pd_conjoint_bytes(from, to, count); -} - -static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { - _Copy_conjoint_jshorts_atomic(from, to, count); -} - -static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { - _Copy_conjoint_jints_atomic(from, to, count); -} - -static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { - _Copy_conjoint_jlongs_atomic(from, to, count); -} - -static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { - assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); - _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); -} - -static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_bytes(from, to, count); -} - -static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_jshorts(from, to, count); -} - -static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_jints(from, to, count); -} - -static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_jlongs(from, to, count); -} - -static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { - assert(!UseCompressedOops, "foo!"); - assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); - _Copy_arrayof_conjoint_jlongs(from, to, count); -} +// Empty for build system #endif // OS_CPU_LINUX_AARCH64_COPY_LINUX_AARCH64_HPP diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp index b3c60b6e6248241b6321b3090ce4fe03622842d0..6b09069e09dd71a03002722f5a285d2f62ae1dbd 100644 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp @@ -382,7 +382,20 @@ int os::extra_bang_size_in_bytes() { extern "C" { int SpinPause() { - return 0; + using spin_wait_func_ptr_t = void (*)(); + spin_wait_func_ptr_t func = CAST_TO_FN_PTR(spin_wait_func_ptr_t, StubRoutines::aarch64::spin_wait()); + assert(func != nullptr, "StubRoutines::aarch64::spin_wait must not be null."); + (*func)(); + // If StubRoutines::aarch64::spin_wait consists of only a RET, + // SpinPause can be considered as implemented. There will be a sequence + // of instructions for: + // - call of SpinPause + // - load of StubRoutines::aarch64::spin_wait stub pointer + // - indirect call of the stub + // - return from the stub + // - return from SpinPause + // So '1' always is returned. + return 1; } void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { diff --git a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp index fca22629bc5651dfb40e4e59f5a0453aa8611552..f584da5814a684ecec06ef93ba4cccb9a0b3ff71 100644 --- a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,7 +29,9 @@ frame JavaThread::pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + frame f = frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + f.set_sp_is_trusted(); + return f; } // For Forte Analyzer AsyncGetCallTrace profiling support - thread is diff --git a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp index 3497ae2ce73a59c4c3a74e85d2686a580fb131f0..b5f5a0787e91ab611b1f9dbe0cb383c5796cec9e 100644 --- a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -143,7 +143,7 @@ void VM_Version::get_os_cpu_info() { _zva_length = 4 << (dczid_el0 & 0xf); } - if (FILE *f = fopen("/proc/cpuinfo", "r")) { + if (FILE *f = os::fopen("/proc/cpuinfo", "r")) { // need a large buffer as the flags line may include lots of text char buf[1024], *p; while (fgets(buf, sizeof (buf), f) != NULL) { @@ -174,8 +174,8 @@ static bool read_fully(const char *fname, char *buf, size_t buflen) { assert(buflen >= 1, "invalid argument"); int fd = os::open(fname, O_RDONLY, 0); if (fd != -1) { - ssize_t read_sz = os::read(fd, buf, buflen); - os::close(fd); + ssize_t read_sz = ::read(fd, buf, buflen); + ::close(fd); // Skip if the contents is just "\n" because some machine only sets // '\n' to the board name. diff --git a/src/hotspot/os_cpu/linux_arm/linux_arm_32.S b/src/hotspot/os_cpu/linux_arm/linux_arm_32.S index c1c8fd428154ea929b1b58916b6d6aa65b6a87de..eb560d8f0c78b7bb904d77c28900ecb5e3836912 100644 --- a/src/hotspot/os_cpu/linux_arm/linux_arm_32.S +++ b/src/hotspot/os_cpu/linux_arm/linux_arm_32.S @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -58,12 +58,6 @@ to .req r1 SpinPause: bx LR - # Support for void Copy::conjoint_bytes(void* from, - # void* to, - # size_t count) -_Copy_conjoint_bytes: - swi 0x9f0001 - # Support for void Copy::arrayof_conjoint_bytes(void* from, # void* to, # size_t count) diff --git a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp index d09608c6aa763ff7f0b9cefea44f7871c5e95660..15f6220fc81dc37ed8cf177e2c829d278d8a2737 100644 --- a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2019 SAP SE. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,14 +58,15 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, // if we were running Java code when SIGPROF came in. if (isInJava) { ucontext_t* uc = (ucontext_t*) ucontext; - frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], - (address)uc->uc_mcontext.regs->nip); + address pc = (address)uc->uc_mcontext.regs->nip; - if (ret_frame.pc() == NULL) { + if (pc == NULL) { // ucontext wasn't useful return false; } + frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], pc); + if (ret_frame.fp() == NULL) { // The found frame does not have a valid frame pointer. // Bail out because this will create big trouble later on, either diff --git a/src/hotspot/os_cpu/linux_x86/copy_linux_x86.hpp b/src/hotspot/os_cpu/linux_x86/copy_linux_x86.hpp index de43d12f4a76f62013d4cddba377bfc0ad68ccd8..ed25d38cbffa07f7cb330117e66d9a2ee8343f56 100644 --- a/src/hotspot/os_cpu/linux_x86/copy_linux_x86.hpp +++ b/src/hotspot/os_cpu/linux_x86/copy_linux_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,285 +25,6 @@ #ifndef OS_CPU_LINUX_X86_COPY_LINUX_X86_HPP #define OS_CPU_LINUX_X86_COPY_LINUX_X86_HPP -static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - (void)memmove(to, from, count * HeapWordSize); -#else - // Includes a zero-count check. - intx temp = 0; - __asm__ volatile(" testl %6,%6 ;" - " jz 7f ;" - " cmpl %4,%5 ;" - " leal -4(%4,%6,4),%3;" - " jbe 1f ;" - " cmpl %7,%5 ;" - " jbe 4f ;" - "1: cmpl $32,%6 ;" - " ja 3f ;" - " subl %4,%1 ;" - "2: movl (%4),%3 ;" - " movl %7,(%5,%4,1) ;" - " addl $4,%0 ;" - " subl $1,%2 ;" - " jnz 2b ;" - " jmp 7f ;" - "3: rep; smovl ;" - " jmp 7f ;" - "4: cmpl $32,%2 ;" - " movl %7,%0 ;" - " leal -4(%5,%6,4),%1;" - " ja 6f ;" - " subl %4,%1 ;" - "5: movl (%4),%3 ;" - " movl %7,(%5,%4,1) ;" - " subl $4,%0 ;" - " subl $1,%2 ;" - " jnz 5b ;" - " jmp 7f ;" - "6: std ;" - " rep; smovl ;" - " cld ;" - "7: nop " - : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) - : "0" (from), "1" (to), "2" (count), "3" (temp) - : "memory", "flags"); -#endif // AMD64 -} - -static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - switch (count) { - case 8: to[7] = from[7]; - case 7: to[6] = from[6]; - case 6: to[5] = from[5]; - case 5: to[4] = from[4]; - case 4: to[3] = from[3]; - case 3: to[2] = from[2]; - case 2: to[1] = from[1]; - case 1: to[0] = from[0]; - case 0: break; - default: - (void)memcpy(to, from, count * HeapWordSize); - break; - } -#else - // Includes a zero-count check. - intx temp = 0; - __asm__ volatile(" testl %6,%6 ;" - " jz 3f ;" - " cmpl $32,%6 ;" - " ja 2f ;" - " subl %4,%1 ;" - "1: movl (%4),%3 ;" - " movl %7,(%5,%4,1);" - " addl $4,%0 ;" - " subl $1,%2 ;" - " jnz 1b ;" - " jmp 3f ;" - "2: rep; smovl ;" - "3: nop " - : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) - : "0" (from), "1" (to), "2" (count), "3" (temp) - : "memory", "cc"); -#endif // AMD64 -} - -static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - switch (count) { - case 8: to[7] = from[7]; - case 7: to[6] = from[6]; - case 6: to[5] = from[5]; - case 5: to[4] = from[4]; - case 4: to[3] = from[3]; - case 3: to[2] = from[2]; - case 2: to[1] = from[1]; - case 1: to[0] = from[0]; - case 0: break; - default: - while (count-- > 0) { - *to++ = *from++; - } - break; - } -#else - // pd_disjoint_words is word-atomic in this implementation. - pd_disjoint_words(from, to, count); -#endif // AMD64 -} - -static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_conjoint_words(from, to, count); -} - -static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_disjoint_words(from, to, count); -} - -static void pd_conjoint_bytes(const void* from, void* to, size_t count) { -#ifdef AMD64 - (void)memmove(to, from, count); -#else - // Includes a zero-count check. - intx temp = 0; - __asm__ volatile(" testl %6,%6 ;" - " jz 13f ;" - " cmpl %4,%5 ;" - " leal -1(%4,%6),%3 ;" - " jbe 1f ;" - " cmpl %7,%5 ;" - " jbe 8f ;" - "1: cmpl $3,%6 ;" - " jbe 6f ;" - " movl %6,%3 ;" - " movl $4,%2 ;" - " subl %4,%2 ;" - " andl $3,%2 ;" - " jz 2f ;" - " subl %6,%3 ;" - " rep; smovb ;" - "2: movl %7,%2 ;" - " shrl $2,%2 ;" - " jz 5f ;" - " cmpl $32,%2 ;" - " ja 4f ;" - " subl %4,%1 ;" - "3: movl (%4),%%edx ;" - " movl %%edx,(%5,%4,1);" - " addl $4,%0 ;" - " subl $1,%2 ;" - " jnz 3b ;" - " addl %4,%1 ;" - " jmp 5f ;" - "4: rep; smovl ;" - "5: movl %7,%2 ;" - " andl $3,%2 ;" - " jz 13f ;" - "6: xorl %7,%3 ;" - "7: movb (%4,%7,1),%%dl ;" - " movb %%dl,(%5,%7,1) ;" - " addl $1,%3 ;" - " subl $1,%2 ;" - " jnz 7b ;" - " jmp 13f ;" - "8: std ;" - " cmpl $12,%2 ;" - " ja 9f ;" - " movl %7,%0 ;" - " leal -1(%6,%5),%1 ;" - " jmp 11f ;" - "9: xchgl %3,%2 ;" - " movl %6,%0 ;" - " addl $1,%2 ;" - " leal -1(%7,%5),%1 ;" - " andl $3,%2 ;" - " jz 10f ;" - " subl %6,%3 ;" - " rep; smovb ;" - "10: movl %7,%2 ;" - " subl $3,%0 ;" - " shrl $2,%2 ;" - " subl $3,%1 ;" - " rep; smovl ;" - " andl $3,%3 ;" - " jz 12f ;" - " movl %7,%2 ;" - " addl $3,%0 ;" - " addl $3,%1 ;" - "11: rep; smovb ;" - "12: cld ;" - "13: nop ;" - : "=S" (from), "=D" (to), "=c" (count), "=r" (temp) - : "0" (from), "1" (to), "2" (count), "3" (temp) - : "memory", "flags", "%edx"); -#endif // AMD64 -} - -static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { - pd_conjoint_bytes(from, to, count); -} - -static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { - _Copy_conjoint_jshorts_atomic(from, to, count); -} - -static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { -#ifdef AMD64 - _Copy_conjoint_jints_atomic(from, to, count); -#else - assert(HeapWordSize == BytesPerInt, "heapwords and jints must be the same size"); - // pd_conjoint_words is word-atomic in this implementation. - pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count); -#endif // AMD64 -} - -static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { -#ifdef AMD64 - _Copy_conjoint_jlongs_atomic(from, to, count); -#else - // Guarantee use of fild/fistp or xmm regs via some asm code, because compilers won't. - if (from > to) { - while (count-- > 0) { - __asm__ volatile("fildll (%0); fistpll (%1)" - : - : "r" (from), "r" (to) - : "memory" ); - ++from; - ++to; - } - } else { - while (count-- > 0) { - __asm__ volatile("fildll (%0,%2,8); fistpll (%1,%2,8)" - : - : "r" (from), "r" (to), "r" (count) - : "memory" ); - } - } -#endif // AMD64 -} - -static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { -#ifdef AMD64 - assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); - _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); -#else - assert(HeapWordSize == BytesPerOop, "heapwords and oops must be the same size"); - // pd_conjoint_words is word-atomic in this implementation. - pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count); -#endif // AMD64 -} - -static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_bytes(from, to, count); -} - -static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { - _Copy_arrayof_conjoint_jshorts(from, to, count); -} - -static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - _Copy_arrayof_conjoint_jints(from, to, count); -#else - pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count); -#endif // AMD64 -} - -static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - _Copy_arrayof_conjoint_jlongs(from, to, count); -#else - pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); -#endif // AMD64 -} - -static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); - _Copy_arrayof_conjoint_jlongs(from, to, count); -#else - pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count); -#endif // AMD64 -} +// Empty for build system #endif // OS_CPU_LINUX_X86_COPY_LINUX_X86_HPP diff --git a/src/hotspot/os_cpu/linux_x86/linux_x86_32.S b/src/hotspot/os_cpu/linux_x86/linux_x86_32.S index 620179d99dda4848920b4855f04732c2df7fd8db..344358172defdc26ff1c27ff8d98cd3f45008796 100644 --- a/src/hotspot/os_cpu/linux_x86/linux_x86_32.S +++ b/src/hotspot/os_cpu/linux_x86/linux_x86_32.S @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ # point or use it in the same manner as does the server # compiler. - .globl _Copy_conjoint_bytes .globl _Copy_arrayof_conjoint_bytes .globl _Copy_conjoint_jshorts_atomic .globl _Copy_arrayof_conjoint_jshorts @@ -51,117 +50,10 @@ SpinPause: movl $1, %eax ret - # Support for void Copy::conjoint_bytes(void* from, - # void* to, - # size_t count) - .p2align 4,,15 - .type _Copy_conjoint_bytes,@function -_Copy_conjoint_bytes: - pushl %esi - movl 4+12(%esp),%ecx # count - pushl %edi - movl 8+ 4(%esp),%esi # from - movl 8+ 8(%esp),%edi # to - cmpl %esi,%edi - leal -1(%esi,%ecx),%eax # from + count - 1 - jbe cb_CopyRight - cmpl %eax,%edi - jbe cb_CopyLeft - # copy from low to high -cb_CopyRight: - cmpl $3,%ecx - jbe 5f # <= 3 bytes - # align source address at dword address boundary - movl %ecx,%eax # original count - movl $4,%ecx - subl %esi,%ecx - andl $3,%ecx # prefix byte count - jz 1f # no prefix - subl %ecx,%eax # byte count less prefix - # copy prefix - subl %esi,%edi -0: movb (%esi),%dl - movb %dl,(%edi,%esi,1) - addl $1,%esi - subl $1,%ecx - jnz 0b - addl %esi,%edi -1: movl %eax,%ecx # byte count less prefix - shrl $2,%ecx # dword count - jz 4f # no dwords to move - cmpl $32,%ecx - jbe 2f # <= 32 dwords - # copy aligned dwords - rep; smovl - jmp 4f - # copy aligned dwords -2: subl %esi,%edi - .p2align 4,,15 -3: movl (%esi),%edx - movl %edx,(%edi,%esi,1) - addl $4,%esi - subl $1,%ecx - jnz 3b - addl %esi,%edi -4: movl %eax,%ecx # byte count less prefix -5: andl $3,%ecx # suffix byte count - jz 7f # no suffix - # copy suffix - xorl %eax,%eax -6: movb (%esi,%eax,1),%dl - movb %dl,(%edi,%eax,1) - addl $1,%eax - subl $1,%ecx - jnz 6b -7: popl %edi - popl %esi - ret - # copy from high to low -cb_CopyLeft: - std - leal -4(%edi,%ecx),%edi # to + count - 4 - movl %eax,%esi # from + count - 1 - movl %ecx,%eax - subl $3,%esi # from + count - 4 - cmpl $3,%ecx - jbe 5f # <= 3 bytes -1: shrl $2,%ecx # dword count - jz 4f # no dwords to move - cmpl $32,%ecx - ja 3f # > 32 dwords - # copy dwords, aligned or not - subl %esi,%edi - .p2align 4,,15 -2: movl (%esi),%edx - movl %edx,(%edi,%esi,1) - subl $4,%esi - subl $1,%ecx - jnz 2b - addl %esi,%edi - jmp 4f - # copy dwords, aligned or not -3: rep; smovl -4: movl %eax,%ecx # byte count -5: andl $3,%ecx # suffix byte count - jz 7f # no suffix - # copy suffix - subl %esi,%edi - addl $3,%esi -6: movb (%esi),%dl - movb %dl,(%edi,%esi,1) - subl $1,%esi - subl $1,%ecx - jnz 6b -7: cld - popl %edi - popl %esi - ret - # Support for void Copy::arrayof_conjoint_bytes(void* from, # void* to, # size_t count) # - # Same as _Copy_conjoint_bytes, except no source alignment check. .p2align 4,,15 .type _Copy_arrayof_conjoint_bytes,@function _Copy_arrayof_conjoint_bytes: diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp index cc71b0d278019bf95142c995b2ac504a9e41c473..5e346efee54e0279d03d4d2a7173600192208bf7 100644 --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -462,7 +462,7 @@ juint os::cpu_microcode_revision() { juint result = 0; char data[2048] = {0}; // lines should fit in 2K buf size_t len = sizeof(data); - FILE *fp = fopen("/proc/cpuinfo", "r"); + FILE *fp = os::fopen("/proc/cpuinfo", "r"); if (fp) { while (!feof(fp)) { if (fgets(data, len, fp)) { diff --git a/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp index 816ca411430cc609615825747f055c2ac0b82935..e4313782613ddab3ed94a56b66553f5089051fa0 100644 --- a/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp +++ b/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright 2009, 2010 Red Hat, Inc. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,3 +35,40 @@ frame JavaThread::pd_last_frame() { void JavaThread::cache_global_variables() { // nothing to do } + +bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, + bool isInJava) { + if (has_last_Java_frame()) { + *fr_addr = pd_last_frame(); + return true; + } + + if (isInJava) { + // We know we are in Java, but there is no frame? + // Try to find the top-most Java frame on Zero stack then. + intptr_t* sp = zero_stack()->sp(); + ZeroFrame* zf = top_zero_frame(); + while (zf != NULL) { + if (zf->is_interpreter_frame()) { + interpreterState istate = zf->as_interpreter_frame()->interpreter_state(); + if (istate->self_link() == istate) { + // Valid interpreter state found, this is our frame. + *fr_addr = frame(zf, sp); + return true; + } + } + sp = ((intptr_t *) zf) + 1; + zf = zf->next(); + } + } + + // No dice. + return false; +} + +bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, + void* ucontext, + bool isInJava) { + return pd_get_top_frame_for_signal_handler(fr_addr, ucontext, isInJava); +} diff --git a/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp b/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp index b180611b2f9e2fcf7fdae9d721a2debe566af203..b915c40c04987a5c303a9ef5eeceeab8dd6542d6 100644 --- a/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp +++ b/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,16 +96,10 @@ public: bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, - bool isInJava) { - ShouldNotCallThis(); - return false; // silence compile warning - } + bool isInJava); bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, - bool isInJava) { - ShouldNotCallThis(); - return false; // silence compile warning - } + bool isInJava); #endif // OS_CPU_LINUX_ZERO_THREAD_LINUX_ZERO_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp index 6512df3e7b9188d76dce3f3260c12bd8828a7a69..c5267d85d377d20f6683d4eb0e271be9dc103249 100644 --- a/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * Copyright (c) 2022, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +30,9 @@ frame JavaThread::pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); vmassert(_anchor.last_Java_pc() != NULL, "not walkable"); - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + frame f = frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + f.set_sp_is_trusted(); + return f; } // For Forte Analyzer AsyncGetCallTrace profiling support - thread is diff --git a/src/hotspot/os_cpu/windows_x86/copy_windows_x86.hpp b/src/hotspot/os_cpu/windows_x86/copy_windows_x86.hpp index 2f0560d89878d0148dd15af6d1493e03ef13f5dd..820ca46cb25d16bb9f34702168d120e87e750163 100644 --- a/src/hotspot/os_cpu/windows_x86/copy_windows_x86.hpp +++ b/src/hotspot/os_cpu/windows_x86/copy_windows_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,64 +25,6 @@ #ifndef OS_CPU_WINDOWS_X86_COPY_WINDOWS_X86_HPP #define OS_CPU_WINDOWS_X86_COPY_WINDOWS_X86_HPP -static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - (void)memmove(to, from, count * HeapWordSize); -} - -static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { -#ifdef AMD64 - switch (count) { - case 8: to[7] = from[7]; - case 7: to[6] = from[6]; - case 6: to[5] = from[5]; - case 5: to[4] = from[4]; - case 4: to[3] = from[3]; - case 3: to[2] = from[2]; - case 2: to[1] = from[1]; - case 1: to[0] = from[0]; - case 0: break; - default: - (void)memcpy(to, from, count * HeapWordSize); - break; - } -#else - (void)memcpy(to, from, count * HeapWordSize); -#endif // AMD64 -} - -static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { - switch (count) { - case 8: to[7] = from[7]; - case 7: to[6] = from[6]; - case 6: to[5] = from[5]; - case 5: to[4] = from[4]; - case 4: to[3] = from[3]; - case 3: to[2] = from[2]; - case 2: to[1] = from[1]; - case 1: to[0] = from[0]; - case 0: break; - default: while (count-- > 0) { - *to++ = *from++; - } - break; - } -} - -static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - (void)memmove(to, from, count * HeapWordSize); -} - -static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { - pd_disjoint_words(from, to, count); -} - -static void pd_conjoint_bytes(const void* from, void* to, size_t count) { - (void)memmove(to, from, count); -} - -static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { - pd_conjoint_bytes(from, to, count); -} static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { if (from > to) { diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp index 651511f375185feff85a4d5b0aee0bb25e2b12ef..f7ff8ccf40b14a0c4bc5be9f31b0edcc89d99097 100644 --- a/src/hotspot/share/adlc/formssel.cpp +++ b/src/hotspot/share/adlc/formssel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4234,8 +4234,8 @@ bool MatchRule::is_vector() const { "VectorRearrange","VectorLoadShuffle", "VectorLoadConst", "VectorCastB2X", "VectorCastS2X", "VectorCastI2X", "VectorCastL2X", "VectorCastF2X", "VectorCastD2X", - "VectorMaskWrapper", "VectorMaskCmp", "VectorReinterpret","LoadVectorMasked","StoreVectorMasked", - "FmaVD", "FmaVF","PopCountVI", + "VectorMaskWrapper","VectorMaskCmp","VectorReinterpret","LoadVectorMasked","StoreVectorMasked", + "FmaVD","FmaVF","PopCountVI", "PopCountVL", "VectorLongToMask", // Next are vector mask ops. "MaskAll", "AndVMask", "OrVMask", "XorVMask", "VectorMaskCast", // Next are not supported currently. diff --git a/src/hotspot/share/asm/register.hpp b/src/hotspot/share/asm/register.hpp index 861c43b2c84128e12b7fa465aadaa6fa73358739..06a8735f52061c05682bfd6158de1049086eb233 100644 --- a/src/hotspot/share/asm/register.hpp +++ b/src/hotspot/share/asm/register.hpp @@ -45,15 +45,48 @@ class AbstractRegisterImpl { int value() const { return (int)(intx)this; } }; + +// Macros to help define all kinds of registers + +#ifndef USE_POINTERS_TO_REGISTER_IMPL_ARRAY + #define AS_REGISTER(type,name) ((type)name##_##type##EnumValue) -#define CONSTANT_REGISTER_DECLARATION(type, name, value) \ -const type name = ((type)value); \ +#define CONSTANT_REGISTER_DECLARATION(type, name, value) \ +const type name = ((type)value); \ enum { name##_##type##EnumValue = (value) } -#define REGISTER_DECLARATION(type, name, value) \ +#else // USE_POINTERS_TO_REGISTER_IMPL_ARRAY + +#define REGISTER_IMPL_DECLARATION(type, impl_type, reg_count) \ +inline constexpr type as_ ## type(int encoding) { \ + return impl_type::first() + encoding; \ +} \ +extern impl_type all_ ## type ## s[reg_count + 1] INTERNAL_VISIBILITY; \ +inline constexpr type impl_type::first() { return all_ ## type ## s + 1; } + +#define REGISTER_IMPL_DEFINITION(type, impl_type, reg_count) \ +impl_type all_ ## type ## s[reg_count + 1]; + +#define CONSTANT_REGISTER_DECLARATION(type, name, value) \ +constexpr type name = as_ ## type(value); + +#endif // USE_POINTERS_TO_REGISTER_IMPL_ARRAY + + +#define REGISTER_DECLARATION(type, name, value) \ const type name = ((type)value) + +// For definitions of RegisterImpl* instances. To be redefined in an +// OS-specific way. +#ifdef __GNUC__ +#define INTERNAL_VISIBILITY __attribute__ ((visibility ("internal"))) +#else +#define INTERNAL_VISIBILITY +#endif + + #define REGISTER_DEFINITION(type, name) #include CPU_HEADER(register) diff --git a/src/hotspot/share/c1/c1_Compilation.cpp b/src/hotspot/share/c1/c1_Compilation.cpp index df4b6bbed54660b578b96d90b5e2c7e4c0780598..27c20a9c5fe4242132a7c5ccf9ccc2f58fa58886 100644 --- a/src/hotspot/share/c1/c1_Compilation.cpp +++ b/src/hotspot/share/c1/c1_Compilation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -703,7 +703,7 @@ void Compilation::print_timers() { #ifndef PRODUCT void Compilation::compile_only_this_method() { ResourceMark rm; - fileStream stream(fopen("c1_compile_only", "wt")); + fileStream stream(os::fopen("c1_compile_only", "wt")); stream.print_cr("# c1 compile only directives"); compile_only_this_scope(&stream, hir()->top_scope()); } @@ -717,7 +717,7 @@ void Compilation::compile_only_this_scope(outputStream* st, IRScope* scope) { } void Compilation::exclude_this_method() { - fileStream stream(fopen(".hotspot_compiler", "at")); + fileStream stream(os::fopen(".hotspot_compiler", "at")); stream.print("exclude "); method()->holder()->name()->print_symbol_on(&stream); stream.print(" "); diff --git a/src/hotspot/share/c1/c1_FrameMap.hpp b/src/hotspot/share/c1/c1_FrameMap.hpp index 5cbb37422dcbbee4b7c5f95f31b21af259853ad9..480a1082f686e7c9ca66e15eb536dff07b646fab 100644 --- a/src/hotspot/share/c1/c1_FrameMap.hpp +++ b/src/hotspot/share/c1/c1_FrameMap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ class CallingConvention; //-------------------------------------------------------- // This class is responsible of mapping items (locals, monitors, spill -// slots and registers to their frame location +// slots and registers) to their frame location // // The monitors are specified by a consecutive index, although each monitor entry // occupies two words. The monitor_index is 0.._num_monitors diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index 2f9355f10991f45ccdeadb94eaccce897ef16ae2..e06251700bded8387405c213c7177c0de95f636d 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -2036,19 +2036,19 @@ void GraphBuilder::invoke(Bytecodes::Code code) { cha_monomorphic_target = target->find_monomorphic_target(calling_klass, declared_interface, singleton); if (cha_monomorphic_target != NULL) { if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) { - // If CHA is able to bind this invoke then update the class - // to match that class, otherwise klass will refer to the - // interface. - klass = cha_monomorphic_target->holder(); + ciInstanceKlass* holder = cha_monomorphic_target->holder(); + ciInstanceKlass* constraint = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts actual_recv = declared_interface; // insert a check it's really the expected class. - CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception()); + CheckCast* c = new CheckCast(constraint, receiver, copy_state_for_exception()); c->set_incompatible_class_change_check(); - c->set_direct_compare(klass->is_final()); + c->set_direct_compare(constraint->is_final()); // pass the result of the checkcast so that the compiler has // more accurate type info in the inlinee better_receiver = append_split(c); + + dependency_recorder()->assert_unique_implementor(declared_interface, singleton); } else { cha_monomorphic_target = NULL; // subtype check against Object is useless } @@ -2072,9 +2072,11 @@ void GraphBuilder::invoke(Bytecodes::Code code) { } // check if we could do inlining - if (!PatchALot && Inline && target->is_loaded() && callee_holder->is_linked() && !patch_for_appendix) { + if (!PatchALot && Inline && target->is_loaded() && !patch_for_appendix && + callee_holder->is_loaded()) { // the effect of symbolic reference resolution + // callee is known => check if we have static binding - if ((code == Bytecodes::_invokestatic && callee_holder->is_initialized()) || // invokestatic involves an initialization barrier on resolved klass + if ((code == Bytecodes::_invokestatic && klass->is_initialized()) || // invokestatic involves an initialization barrier on declaring class code == Bytecodes::_invokespecial || (code == Bytecodes::_invokevirtual && target->is_final_method()) || code == Bytecodes::_invokedynamic) { @@ -3091,7 +3093,7 @@ BlockBegin* GraphBuilder::setup_start_block(int osr_bci, BlockBegin* std_entry, // each method. Previously, each method started with the // start-block created below, and this block was followed by the // header block that was always empty. This header block is only - // necesary if std_entry is also a backward branch target because + // necessary if std_entry is also a backward branch target because // then phi functions may be necessary in the header block. It's // also necessary when profiling so that there's a single block that // can increment the the counters. diff --git a/src/hotspot/share/c1/c1_IR.cpp b/src/hotspot/share/c1/c1_IR.cpp index 53c19c786836597556d468a289ff2c6d6a698ef7..78aef07b4cf0c013d869d4e8b51f6ff359ccc597 100644 --- a/src/hotspot/share/c1/c1_IR.cpp +++ b/src/hotspot/share/c1/c1_IR.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -191,7 +191,8 @@ CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, boo , _oop_map(NULL) , _stack(stack) , _is_method_handle_invoke(false) - , _deoptimize_on_exception(deoptimize_on_exception) { + , _deoptimize_on_exception(deoptimize_on_exception) + , _force_reexecute(false) { assert(_stack != NULL, "must be non null"); } @@ -203,7 +204,8 @@ CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack) , _oop_map(NULL) , _stack(stack == NULL ? info->_stack : stack) , _is_method_handle_invoke(info->_is_method_handle_invoke) - , _deoptimize_on_exception(info->_deoptimize_on_exception) { + , _deoptimize_on_exception(info->_deoptimize_on_exception) + , _force_reexecute(info->_force_reexecute) { // deep copy of exception handlers if (info->_exception_handlers != NULL) { @@ -215,7 +217,8 @@ CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack) void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) { // record the safepoint before recording the debug info for enclosing scopes recorder->add_safepoint(pc_offset, _oop_map->deep_copy()); - _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/, _is_method_handle_invoke); + bool reexecute = _force_reexecute || _scope_debug_info->should_reexecute(); + _scope_debug_info->record_debug_info(recorder, pc_offset, reexecute, _is_method_handle_invoke); recorder->end_safepoint(pc_offset); } @@ -1260,21 +1263,36 @@ void IR::print(bool cfg_only, bool live_only) { tty->print_cr("invalid IR"); } } +#endif // PRODUCT +#ifdef ASSERT class EndNotNullValidator : public BlockClosure { public: - EndNotNullValidator(IR* hir) { - hir->start()->iterate_postorder(this); + virtual void block_do(BlockBegin* block) { + assert(block->end() != NULL, "Expect block end to exist."); } +}; - void block_do(BlockBegin* block) { - assert(block->end() != NULL, "Expect block end to exist."); +class XentryFlagValidator : public BlockClosure { + public: + virtual void block_do(BlockBegin* block) { + for (int i = 0; i < block->end()->number_of_sux(); i++) { + assert(!block->end()->sux_at(i)->is_set(BlockBegin::exception_entry_flag), "must not be xhandler"); + } + for (int i = 0; i < block->number_of_exception_handlers(); i++) { + assert(block->exception_handler_at(i)->is_set(BlockBegin::exception_entry_flag), "must be xhandler"); + } } }; typedef GrowableArray BlockListList; -class PredecessorValidator : public BlockClosure { +// Validation goals: +// - code() length == blocks length +// - code() contents == blocks content +// - Each block's computed predecessors match sux lists (length) +// - Each block's computed predecessors match sux lists (set content) +class PredecessorAndCodeValidator : public BlockClosure { private: BlockListList* _predecessors; // Each index i will hold predecessors of block with id i BlockList* _blocks; @@ -1284,7 +1302,7 @@ class PredecessorValidator : public BlockClosure { } public: - PredecessorValidator(IR* hir) { + PredecessorAndCodeValidator(IR* hir) { ResourceMark rm; _predecessors = new BlockListList(BlockBegin::number_of_blocks(), BlockBegin::number_of_blocks(), NULL); _blocks = new BlockList(BlockBegin::number_of_blocks()); @@ -1305,20 +1323,10 @@ class PredecessorValidator : public BlockClosure { virtual void block_do(BlockBegin* block) { _blocks->append(block); - verify_successor_xentry_flag(block); collect_predecessors(block); } private: - void verify_successor_xentry_flag(const BlockBegin* block) const { - for (int i = 0; i < block->end()->number_of_sux(); i++) { - assert(!block->end()->sux_at(i)->is_set(BlockBegin::exception_entry_flag), "must not be xhandler"); - } - for (int i = 0; i < block->number_of_exception_handlers(); i++) { - assert(block->exception_handler_at(i)->is_set(BlockBegin::exception_entry_flag), "must be xhandler"); - } - } - void collect_predecessors(BlockBegin* block) { for (int i = 0; i < block->end()->number_of_sux(); i++) { collect_predecessor(block, block->end()->sux_at(i)); @@ -1360,26 +1368,87 @@ class PredecessorValidator : public BlockClosure { }; class VerifyBlockBeginField : public BlockClosure { - public: - - virtual void block_do(BlockBegin *block) { - for ( Instruction *cur = block; cur != NULL; cur = cur->next()) { + virtual void block_do(BlockBegin* block) { + for (Instruction* cur = block; cur != NULL; cur = cur->next()) { assert(cur->block() == block, "Block begin is not correct"); } } }; -void IR::verify() { -#ifdef ASSERT - PredecessorValidator pv(this); - EndNotNullValidator(this); +class ValidateEdgeMutuality : public BlockClosure { + public: + virtual void block_do(BlockBegin* block) { + for (int i = 0; i < block->end()->number_of_sux(); i++) { + assert(block->end()->sux_at(i)->is_predecessor(block), "Block's successor should have it as predecessor"); + } + + for (int i = 0; i < block->number_of_exception_handlers(); i++) { + assert(block->exception_handler_at(i)->is_predecessor(block), "Block's exception handler should have it as predecessor"); + } + + for (int i = 0; i < block->number_of_preds(); i++) { + assert(block->pred_at(i) != NULL, "Predecessor must exist"); + assert(block->pred_at(i)->end() != NULL, "Predecessor end must exist"); + bool is_sux = block->pred_at(i)->end()->is_sux(block); + bool is_xhandler = block->pred_at(i)->is_exception_handler(block); + assert(is_sux || is_xhandler, "Block's predecessor should have it as successor or xhandler"); + } + } +}; + +void IR::expand_with_neighborhood(BlockList& blocks) { + int original_size = blocks.length(); + for (int h = 0; h < original_size; h++) { + BlockBegin* block = blocks.at(h); + + for (int i = 0; i < block->end()->number_of_sux(); i++) { + if (!blocks.contains(block->end()->sux_at(i))) { + blocks.append(block->end()->sux_at(i)); + } + } + + for (int i = 0; i < block->number_of_preds(); i++) { + if (!blocks.contains(block->pred_at(i))) { + blocks.append(block->pred_at(i)); + } + } + + for (int i = 0; i < block->number_of_exception_handlers(); i++) { + if (!blocks.contains(block->exception_handler_at(i))) { + blocks.append(block->exception_handler_at(i)); + } + } + } +} + +void IR::verify_local(BlockList& blocks) { + EndNotNullValidator ennv; + blocks.iterate_forward(&ennv); + + ValidateEdgeMutuality vem; + blocks.iterate_forward(&vem); + VerifyBlockBeginField verifier; - this->iterate_postorder(&verifier); -#endif + blocks.iterate_forward(&verifier); } -#endif // PRODUCT +void IR::verify() { + XentryFlagValidator xe; + iterate_postorder(&xe); + + PredecessorAndCodeValidator pv(this); + + EndNotNullValidator ennv; + iterate_postorder(&ennv); + + ValidateEdgeMutuality vem; + iterate_postorder(&vem); + + VerifyBlockBeginField verifier; + iterate_postorder(&verifier); +} +#endif // ASSERT void SubstitutionResolver::visit(Value* v) { Value v0 = *v; diff --git a/src/hotspot/share/c1/c1_IR.hpp b/src/hotspot/share/c1/c1_IR.hpp index f7155c464137d5bafdb78d311a32a84c06a20fdb..1c759a8bee2408b7f3f2663643da4f5158e2cb9c 100644 --- a/src/hotspot/share/c1/c1_IR.hpp +++ b/src/hotspot/share/c1/c1_IR.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -232,16 +232,15 @@ class IRScopeDebugInfo: public CompilationResourceObj { //Whether we should reexecute this bytecode for deopt bool should_reexecute(); - void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost, bool is_method_handle_invoke = false) { + void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool reexecute, bool is_method_handle_invoke = false) { if (caller() != NULL) { // Order is significant: Must record caller first. - caller()->record_debug_info(recorder, pc_offset, false/*topmost*/); + caller()->record_debug_info(recorder, pc_offset, false/*reexecute*/); } DebugToken* locvals = recorder->create_scope_values(locals()); DebugToken* expvals = recorder->create_scope_values(expressions()); DebugToken* monvals = recorder->create_monitor_values(monitors()); // reexecute allowed only for the topmost frame - bool reexecute = topmost ? should_reexecute() : false; bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis. bool rethrow_exception = false; bool is_opt_native = false; @@ -264,6 +263,7 @@ class CodeEmitInfo: public CompilationResourceObj { ValueStack* _stack; // used by deoptimization (contains also monitors bool _is_method_handle_invoke; // true if the associated call site is a MethodHandle call site. bool _deoptimize_on_exception; + bool _force_reexecute; // force the reexecute flag on, used for patching stub FrameMap* frame_map() const { return scope()->compilation()->frame_map(); } Compilation* compilation() const { return scope()->compilation(); } @@ -290,7 +290,11 @@ class CodeEmitInfo: public CompilationResourceObj { bool is_method_handle_invoke() const { return _is_method_handle_invoke; } void set_is_method_handle_invoke(bool x) { _is_method_handle_invoke = x; } + bool force_reexecute() const { return _force_reexecute; } + void set_force_reexecute() { _force_reexecute = true; } + int interpreter_frame_size() const; + }; @@ -338,7 +342,10 @@ class IR: public CompilationResourceObj { // debugging static void print(BlockBegin* start, bool cfg_only, bool live_only = false) PRODUCT_RETURN; void print(bool cfg_only, bool live_only = false) PRODUCT_RETURN; - void verify() PRODUCT_RETURN; + + void expand_with_neighborhood(BlockList& blocks) NOT_DEBUG_RETURN; + void verify_local(BlockList&) NOT_DEBUG_RETURN; + void verify() NOT_DEBUG_RETURN; }; diff --git a/src/hotspot/share/c1/c1_Instruction.cpp b/src/hotspot/share/c1/c1_Instruction.cpp index 801aeb054aa97de515f4a713f22039e34ef80129..4b66796a543f02cb6026b6d1d8d51d08a4b4d434 100644 --- a/src/hotspot/share/c1/c1_Instruction.cpp +++ b/src/hotspot/share/c1/c1_Instruction.cpp @@ -529,9 +529,10 @@ void BlockBegin::set_end(BlockEnd* new_end) { // Assumes that no predecessor of if (new_end == _end) return; // Remove this block as predecessor of its current successors - if (_end != NULL) - for (int i = 0; i < number_of_sux(); i++) { - sux_at(i)->remove_predecessor(this); + if (_end != NULL) { + for (int i = 0; i < number_of_sux(); i++) { + sux_at(i)->remove_predecessor(this); + } } _end = new_end; @@ -801,6 +802,11 @@ bool BlockBegin::try_merge(ValueStack* new_state) { existing_state->invalidate_local(index); TRACE_PHI(tty->print_cr("invalidating local %d because of type mismatch", index)); } + + if (existing_value != new_state->local_at(index) && existing_value->as_Phi() == NULL) { + TRACE_PHI(tty->print_cr("required phi for local %d is missing, irreducible loop?", index)); + return false; // BAILOUT in caller + } } #ifdef ASSERT @@ -890,11 +896,6 @@ void BlockList::iterate_backward(BlockClosure* closure) { } -void BlockList::blocks_do(void f(BlockBegin*)) { - for (int i = length() - 1; i >= 0; i--) f(at(i)); -} - - void BlockList::values_do(ValueVisitor* f) { for (int i = length() - 1; i >= 0; i--) at(i)->block_values_do(f); } diff --git a/src/hotspot/share/c1/c1_Instruction.hpp b/src/hotspot/share/c1/c1_Instruction.hpp index 5b5ea8a863cf7b426eb69ad643e846101b312f0f..1646557018f75496702cafd80b1020cc16fb1995 100644 --- a/src/hotspot/share/c1/c1_Instruction.hpp +++ b/src/hotspot/share/c1/c1_Instruction.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,7 +137,6 @@ class BlockList: public GrowableArray { void iterate_forward(BlockClosure* closure); void iterate_backward(BlockClosure* closure); - void blocks_do(void f(BlockBegin*)); void values_do(ValueVisitor* f); void print(bool cfg_only = false, bool live_only = false) PRODUCT_RETURN; }; @@ -1823,6 +1822,7 @@ BASE(BlockEnd, StateSplit) // successors int number_of_sux() const { return _sux != NULL ? _sux->length() : 0; } BlockBegin* sux_at(int i) const { return _sux->at(i); } + bool is_sux(BlockBegin* sux) const { return _sux == NULL ? false : _sux->contains(sux); } BlockBegin* default_sux() const { return sux_at(number_of_sux() - 1); } void substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux); }; diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index 1dc3981ceaf073f0b816a0abb702d03c203bedbe..1e15c804ce235ba543c8c1e8f4676e83923a0bfb 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -43,6 +43,7 @@ void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_cod while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeGeneralJump::instruction_size) { _masm->nop(); } + info->set_force_reexecute(); patch->install(_masm, patch_code, obj, info); append_code_stub(patch); @@ -606,7 +607,7 @@ void LIR_Assembler::emit_op0(LIR_Op0* op) { check_icache(); } offsets()->set_value(CodeOffsets::Verified_Entry, _masm->offset()); - _masm->verified_entry(); + _masm->verified_entry(compilation()->directive()->BreakAtExecuteOption); if (needs_clinit_barrier_on_entry(compilation()->method())) { clinit_barrier(compilation()->method()); } diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 05aa3587ee2e227de52cac56e4e68728793af407..b386b541f89c6d24b0377b9dbd05af4ade3d79ea 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -620,7 +620,7 @@ void LIRGenerator::monitor_exit(LIR_Opr object, LIR_Opr lock, LIR_Opr new_hdr, L // setup registers LIR_Opr hdr = lock; lock = new_hdr; - CodeStub* slow_path = new MonitorExitStub(lock, UseFastLocking, monitor_no); + CodeStub* slow_path = new MonitorExitStub(lock, !UseHeavyMonitors, monitor_no); __ load_stack_address_monitor(monitor_no, lock); __ unlock_object(hdr, object, lock, scratch, slow_path); } @@ -963,6 +963,14 @@ void LIRGenerator::move_to_phi(PhiResolver* resolver, Value cur_val, Value sux_v Phi* phi = sux_val->as_Phi(); // cur_val can be null without phi being null in conjunction with inlining if (phi != NULL && cur_val != NULL && cur_val != phi && !phi->is_illegal()) { + if (phi->is_local()) { + for (int i = 0; i < phi->operand_count(); i++) { + Value op = phi->operand_at(i); + if (op != NULL && op->type()->is_illegal()) { + bailout("illegal phi operand"); + } + } + } Phi* cur_phi = cur_val->as_Phi(); if (cur_phi != NULL && cur_phi->is_illegal()) { // Phi and local would need to get invalidated diff --git a/src/hotspot/share/c1/c1_MacroAssembler.hpp b/src/hotspot/share/c1/c1_MacroAssembler.hpp index 206eda91e2abfe643ee5d8c8bd4a2b383bd61d33..6a8304bd405fac11a598bf23f21557e276887eca 100644 --- a/src/hotspot/share/c1/c1_MacroAssembler.hpp +++ b/src/hotspot/share/c1/c1_MacroAssembler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ class C1_MacroAssembler: public MacroAssembler { void build_frame(int frame_size_in_bytes, int bang_size_in_bytes); void remove_frame(int frame_size_in_bytes); - void verified_entry(); + void verified_entry(bool breakAtEntry); void verify_stack_oop(int offset) PRODUCT_RETURN; void verify_not_null_oop(Register r) PRODUCT_RETURN; diff --git a/src/hotspot/share/c1/c1_Optimizer.cpp b/src/hotspot/share/c1/c1_Optimizer.cpp index e406a530b73a9531ea9ae785d771a98d97c3acbe..e741cf90f9210f604c8f3335cb1e15505eed73a9 100644 --- a/src/hotspot/share/c1/c1_Optimizer.cpp +++ b/src/hotspot/share/c1/c1_Optimizer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,6 +180,25 @@ void CE_Eliminator::block_do(BlockBegin* block) { return; } +#ifdef ASSERT +#define DO_DELAYED_VERIFICATION + /* + * We need to verify the internal representation after modifying it. + * Verifying only the blocks that have been tampered with is cheaper than verifying the whole graph, but we must + * capture blocks_to_verify_later before making the changes, since they might not be reachable afterwards. + * DO_DELAYED_VERIFICATION ensures that the code for this is either enabled in full, or not at all. + */ +#endif // ASSERT + +#ifdef DO_DELAYED_VERIFICATION + BlockList blocks_to_verify_later; + blocks_to_verify_later.append(block); + blocks_to_verify_later.append(t_block); + blocks_to_verify_later.append(f_block); + blocks_to_verify_later.append(sux); + _hir->expand_with_neighborhood(blocks_to_verify_later); +#endif // DO_DELAYED_VERIFICATION + // 2) substitute conditional expression // with an IfOp followed by a Goto // cut if_ away and get node before @@ -248,7 +267,10 @@ void CE_Eliminator::block_do(BlockBegin* block) { tty->print_cr("%d. IfOp in B%d", ifop_count(), block->block_id()); } - _hir->verify(); +#ifdef DO_DELAYED_VERIFICATION + _hir->verify_local(blocks_to_verify_later); +#endif // DO_DELAYED_VERIFICATION + } Value CE_Eliminator::make_ifop(Value x, Instruction::Condition cond, Value y, Value tval, Value fval) { @@ -312,6 +334,7 @@ void Optimizer::eliminate_conditional_expressions() { CE_Eliminator ce(ir()); } +// This removes others' relation to block, but doesnt empty block's lists void disconnect_from_graph(BlockBegin* block) { for (int p = 0; p < block->number_of_preds(); p++) { BlockBegin* pred = block->pred_at(p); @@ -387,6 +410,12 @@ class BlockMerger: public BlockClosure { assert(sux_state->caller_state() == end_state->caller_state(), "caller not equal"); #endif +#ifdef DO_DELAYED_VERIFICATION + BlockList blocks_to_verify_later; + blocks_to_verify_later.append(block); + _hir->expand_with_neighborhood(blocks_to_verify_later); +#endif // DO_DELAYED_VERIFICATION + // find instruction before end & append first instruction of sux block Instruction* prev = end->prev(); Instruction* next = sux->next(); @@ -396,6 +425,9 @@ class BlockMerger: public BlockClosure { // disconnect this block from all other blocks disconnect_from_graph(sux); +#ifdef DO_DELAYED_VERIFICATION + blocks_to_verify_later.remove(sux); // Sux is not part of graph anymore +#endif // DO_DELAYED_VERIFICATION block->set_end(sux->end()); // TODO Should this be done in set_end universally? @@ -404,6 +436,7 @@ class BlockMerger: public BlockClosure { BlockBegin* xhandler = sux->exception_handler_at(k); block->add_exception_handler(xhandler); + // TODO This should be in disconnect from graph... // also substitute predecessor of exception handler assert(xhandler->is_predecessor(sux), "missing predecessor"); xhandler->remove_predecessor(sux); @@ -419,7 +452,9 @@ class BlockMerger: public BlockClosure { _merge_count, block->block_id(), sux->block_id(), sux->state()->stack_size()); } - _hir->verify(); +#ifdef DO_DELAYED_VERIFICATION + _hir->verify_local(blocks_to_verify_later); +#endif // DO_DELAYED_VERIFICATION If* if_ = block->end()->as_If(); if (if_) { @@ -469,7 +504,9 @@ class BlockMerger: public BlockClosure { tty->print_cr("%d. replaced If and IfOp at end of B%d with single If", _merge_count, block->block_id()); } - _hir->verify(); +#ifdef DO_DELAYED_VERIFICATION + _hir->verify_local(blocks_to_verify_later); +#endif // DO_DELAYED_VERIFICATION } } } @@ -485,6 +522,9 @@ class BlockMerger: public BlockClosure { } }; +#ifdef ASSERT +#undef DO_DELAYED_VERIFICATION +#endif // ASSERT void Optimizer::eliminate_blocks() { // merge blocks if possible diff --git a/src/hotspot/share/c1/c1_RangeCheckElimination.cpp b/src/hotspot/share/c1/c1_RangeCheckElimination.cpp index fc5df4a420133f139b97ba55a0a7d425fb0ea59e..f5275eb9d5c5341a3ecf4ef18ec979d12d5306c8 100644 --- a/src/hotspot/share/c1/c1_RangeCheckElimination.cpp +++ b/src/hotspot/share/c1/c1_RangeCheckElimination.cpp @@ -365,7 +365,12 @@ void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instructi bool RangeCheckEliminator::loop_invariant(BlockBegin *loop_header, Instruction *instruction) { assert(loop_header, "Loop header must not be null!"); if (!instruction) return true; - return instruction->dominator_depth() < loop_header->dominator_depth(); + for (BlockBegin *d = loop_header->dominator(); d != NULL; d = d->dominator()) { + if (d == instruction->block()) { + return true; + } + } + return false; } // Update bound. Pushes a new bound onto the stack. Tries to do a conjunction with the current bound. diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index d7e0df012e575b3b50dbb7f9c820f07eac647704..68e77c823c80630e93443363376597ff5663bd35 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -736,7 +736,7 @@ JRT_BLOCK_ENTRY(void, Runtime1::monitorenter(JavaThread* current, oopDesc* obj, _monitorenter_slowcase_cnt++; } #endif - if (!UseFastLocking) { + if (UseHeavyMonitors) { lock->set_obj(obj); } assert(obj == lock->obj(), "must match"); diff --git a/src/hotspot/share/c1/c1_Runtime1.hpp b/src/hotspot/share/c1/c1_Runtime1.hpp index 9212a4fb2498eac533e638611a185e33aa670151..3dcb27476a6f9b8d342461d2032248d94ab9c8fe 100644 --- a/src/hotspot/share/c1/c1_Runtime1.hpp +++ b/src/hotspot/share/c1/c1_Runtime1.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ #include "c1/c1_FrameMap.hpp" #include "code/stubs.hpp" #include "interpreter/interpreter.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/deoptimization.hpp" class StubAssembler; diff --git a/src/hotspot/share/c1/c1_ValueMap.cpp b/src/hotspot/share/c1/c1_ValueMap.cpp index f1961663179b547211a2b6389a36f7fe826d1624..2e2f883bae5a9b5491ddc6dde3bccbad2819ddaf 100644 --- a/src/hotspot/share/c1/c1_ValueMap.cpp +++ b/src/hotspot/share/c1/c1_ValueMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -505,7 +505,7 @@ GlobalValueNumbering::GlobalValueNumbering(IR* ir) assert(start_block == ir->start() && start_block->number_of_preds() == 0 && start_block->dominator() == NULL, "must be start block"); assert(start_block->next()->as_Base() != NULL && start_block->next()->next() == NULL, "start block must not have instructions"); - // method parameters are not linked in instructions list, so process them separateley + // method parameters are not linked in instructions list, so process them separately for_each_state_value(start_block->state(), value, assert(value->as_Local() != NULL, "only method parameters allowed"); set_processed(value); diff --git a/src/hotspot/share/c1/c1_ValueMap.hpp b/src/hotspot/share/c1/c1_ValueMap.hpp index 00034c24ed16aa5c2886d6a596ca0866c873a95a..3ada748c67af3eb0808504c4d8b636c097ed843e 100644 --- a/src/hotspot/share/c1/c1_ValueMap.hpp +++ b/src/hotspot/share/c1/c1_ValueMap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,7 +116,6 @@ class ValueMap: public CompilationResourceObj { void kill_memory(); void kill_field(ciField* field, bool all_offsets); void kill_array(ValueType* type); - void kill_exception(); void kill_map(ValueMap* map); void kill_all(); diff --git a/src/hotspot/share/c1/c1_globals.hpp b/src/hotspot/share/c1/c1_globals.hpp index 2b5de079a0c9410e490dafb9d2bb9d60ad21c056..e90aaf6536d4470fb51b6422454ebcc51f03f1be 100644 --- a/src/hotspot/share/c1/c1_globals.hpp +++ b/src/hotspot/share/c1/c1_globals.hpp @@ -242,9 +242,6 @@ develop(bool, UseFastNewObjectArray, true, \ "Use fast inlined object array allocation") \ \ - develop(bool, UseFastLocking, true, \ - "Use fast inlined locking code") \ - \ develop(bool, UseSlowPath, false, \ "For debugging: test slow cases by always using them") \ \ diff --git a/src/hotspot/share/cds/archiveBuilder.hpp b/src/hotspot/share/cds/archiveBuilder.hpp index 1057d05b0836647cd1410df9996efc95d233e6fa..484f7271a7c70b271c1214a680c58fcdae4504ab 100644 --- a/src/hotspot/share/cds/archiveBuilder.hpp +++ b/src/hotspot/share/cds/archiveBuilder.hpp @@ -312,14 +312,14 @@ public: template u4 buffer_to_offset_u4(T p) const { uintx offset = buffer_to_offset((address)p); - guarantee(offset <= MAX_SHARED_DELTA, "must be 32-bit offset"); + guarantee(offset <= MAX_SHARED_DELTA, "must be 32-bit offset " INTPTR_FORMAT, offset); return (u4)offset; } template u4 any_to_offset_u4(T p) const { uintx offset = any_to_offset((address)p); - guarantee(offset <= MAX_SHARED_DELTA, "must be 32-bit offset"); + guarantee(offset <= MAX_SHARED_DELTA, "must be 32-bit offset " INTPTR_FORMAT, offset); return (u4)offset; } diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 8c273c06a8d0b431a9591420c0577bb18808a371..073c5f829d2f8743137018c2395b6c92c3121dba 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,9 @@ #include "oops/compressedOops.inline.hpp" #include "runtime/arguments.hpp" #include "utilities/bitMap.inline.hpp" +#include "utilities/debug.hpp" #include "utilities/formatBuffer.hpp" +#include "utilities/globalDefinitions.hpp" CHeapBitMap* ArchivePtrMarker::_ptrmap = NULL; VirtualSpace* ArchivePtrMarker::_vs; @@ -264,7 +266,7 @@ void WriteClosure::do_oop(oop* o) { } else { assert(HeapShared::can_write(), "sanity"); _dump_region->append_intptr_t( - (intptr_t)CompressedOops::encode_not_null(*o)); + UseCompressedOops ? (intptr_t)CompressedOops::encode_not_null(*o) : (intptr_t)((void*)(*o))); } } @@ -306,13 +308,23 @@ void ReadClosure::do_tag(int tag) { } void ReadClosure::do_oop(oop *p) { - narrowOop o = CompressedOops::narrow_oop_cast(nextPtr()); - if (CompressedOops::is_null(o) || !HeapShared::is_fully_available()) { - *p = NULL; + if (UseCompressedOops) { + narrowOop o = CompressedOops::narrow_oop_cast(nextPtr()); + if (CompressedOops::is_null(o) || !HeapShared::is_fully_available()) { + *p = NULL; + } else { + assert(HeapShared::can_use(), "sanity"); + assert(HeapShared::is_fully_available(), "must be"); + *p = HeapShared::decode_from_archive(o); + } } else { - assert(HeapShared::can_use(), "sanity"); - assert(HeapShared::is_fully_available(), "must be"); - *p = HeapShared::decode_from_archive(o); + intptr_t dumptime_oop = nextPtr(); + if (dumptime_oop == 0 || !HeapShared::is_fully_available()) { + *p = NULL; + } else { + intptr_t runtime_oop = dumptime_oop + HeapShared::runtime_delta(); + *p = cast_to_oop(runtime_oop); + } } } diff --git a/src/hotspot/share/cds/classListParser.cpp b/src/hotspot/share/cds/classListParser.cpp index 66e346b19442470807b7906255213f2267248a5b..1da5e79377bf01d25d266ba7d337f43aa3935ff5 100644 --- a/src/hotspot/share/cds/classListParser.cpp +++ b/src/hotspot/share/cds/classListParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ ClassListParser::ClassListParser(const char* file) : _id2klass_table(INITIAL_TAB if (fd != -1) { // Obtain a File* from the file descriptor so that fgets() // can be used in parse_one_line() - _file = os::open(fd, "r"); + _file = os::fdopen(fd, "r"); } if (_file == NULL) { char errmsg[JVM_MAXPATHLEN]; diff --git a/src/hotspot/share/cds/classListWriter.cpp b/src/hotspot/share/cds/classListWriter.cpp index 6750a5d4cac09c113ae466ff631929b29149afbc..2ff647559c35a37645a2bc86af47fd2239ee4d38 100644 --- a/src/hotspot/share/cds/classListWriter.cpp +++ b/src/hotspot/share/cds/classListWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,11 +59,6 @@ void ClassListWriter::write(const InstanceKlass* k, const ClassFileStream* cfs) return; } - // filter out java/lang/invoke/BoundMethodHandle$Species.... - if (cfs != NULL && strcmp(cfs->source(), "_ClassSpecializer_generateConcreteSpeciesCode") == 0) { - return; - } - ClassListWriter w; write_to_stream(k, w.stream(), cfs); } @@ -107,10 +102,21 @@ void ClassListWriter::handle_class_unloading(const InstanceKlass* klass) { void ClassListWriter::write_to_stream(const InstanceKlass* k, outputStream* stream, const ClassFileStream* cfs) { assert_locked(); - ClassLoaderData* loader_data = k->class_loader_data(); - if (!SystemDictionaryShared::is_builtin_loader(loader_data)) { - if (cfs == NULL || strncmp(cfs->source(), "file:", 5) != 0) { + ClassLoaderData* loader_data = k->class_loader_data(); + bool is_builtin_loader = SystemDictionaryShared::is_builtin_loader(loader_data); + if (!is_builtin_loader) { + // class may be loaded from shared archive + if (!k->is_shared()) { + if (cfs == nullptr || cfs->source() == nullptr) { + // CDS static dump only handles unregistered class with known source. + return; + } + if (strncmp(cfs->source(), "file:", 5) != 0) { + return; + } + } else { + // Shared unregistered classes are skipped since their real source are not recorded in shared space. return; } if (!SystemDictionaryShared::add_unregistered_class(Thread::current(), (InstanceKlass*)k)) { @@ -118,6 +124,10 @@ void ClassListWriter::write_to_stream(const InstanceKlass* k, outputStream* stre } } + // filter out java/lang/invoke/BoundMethodHandle$Species... + if (cfs != nullptr && cfs->source() != nullptr && strcmp(cfs->source(), "_ClassSpecializer_generateConcreteSpeciesCode") == 0) { + return; + } { InstanceKlass* super = k->java_super(); @@ -145,7 +155,7 @@ void ClassListWriter::write_to_stream(const InstanceKlass* k, outputStream* stre ResourceMark rm; stream->print("%s id: %d", k->name()->as_C_string(), get_id(k)); - if (!SystemDictionaryShared::is_builtin_loader(loader_data)) { + if (!is_builtin_loader) { InstanceKlass* super = k->java_super(); assert(super != NULL, "must be"); stream->print(" super: %d", get_id(super)); diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.cpp b/src/hotspot/share/cds/dumpTimeClassInfo.cpp index 5a9028d32255a740a74cf32f7795f10923a6e633..77225969b1a4db35d5d9753aa6cff31cf9be1353 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.cpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.cpp @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "cds/archiveBuilder.hpp" -#include "cds/dumpTimeClassInfo.hpp" +#include "cds/dumpTimeClassInfo.inline.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/systemDictionaryShared.hpp" diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.hpp b/src/hotspot/share/cds/dumpTimeClassInfo.hpp index 722849954fa47868728e665225cf91e3914759d0..28fe986ff7a32c72a664f044bfd23ed658c47f44 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.hpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -135,8 +135,7 @@ public: } bool is_excluded() { - // _klass may become NULL due to DynamicArchiveBuilder::set_to_null - return _excluded || _failed_verification || _klass == NULL; + return _excluded || _failed_verification; } // Was this class loaded while JvmtiExport::is_early_phase()==true @@ -168,13 +167,15 @@ inline unsigned DumpTimeSharedClassTable_hash(InstanceKlass* const& k) { } } -class DumpTimeSharedClassTable: public ResourceHashtable< +using DumpTimeSharedClassTableBaseType = ResourceHashtable< InstanceKlass*, DumpTimeClassInfo, 15889, // prime number ResourceObj::C_HEAP, mtClassShared, - &DumpTimeSharedClassTable_hash> + &DumpTimeSharedClassTable_hash>; + +class DumpTimeSharedClassTable: public DumpTimeSharedClassTableBaseType { int _builtin_count; int _unregistered_count; @@ -194,6 +195,11 @@ public: return _unregistered_count; } } + + // Overrides ResourceHashtable<>::iterate(ITER*) + template void iterate(ITER* iter) const; +private: + template class IterationHelper; }; #endif // SHARED_CDS_DUMPTIMESHAREDCLASSINFO_HPP diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.inline.hpp b/src/hotspot/share/cds/dumpTimeClassInfo.inline.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f9dbfc7f816c14f90dc67fb1e19baf3bcb99ccb0 --- /dev/null +++ b/src/hotspot/share/cds/dumpTimeClassInfo.inline.hpp @@ -0,0 +1,74 @@ + +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARED_CDS_DUMPTIMESHAREDCLASSINFO_INLINE_HPP +#define SHARED_CDS_DUMPTIMESHAREDCLASSINFO_INLINE_HPP + +#include "cds/dumpTimeClassInfo.hpp" +#include "classfile/systemDictionaryShared.hpp" +#include "classfile/classLoaderData.inline.hpp" +#include "oops/instanceKlass.hpp" +#include "oops/klass.inline.hpp" +#include "runtime/safepoint.hpp" + +#if INCLUDE_CDS + +// For safety, only iterate over a class if it loader is alive. +// IterationHelper and DumpTimeSharedClassTable::iterate +// must be used only inside a safepoint, where the value of +// k->is_loader_alive() will not change. +template +class DumpTimeSharedClassTable::IterationHelper { + ITER* _iter; +public: + IterationHelper(ITER* iter) { + _iter = iter; + } + bool do_entry(InstanceKlass* k, DumpTimeClassInfo& info) { + assert(SafepointSynchronize::is_at_safepoint(), "invariant"); + assert_lock_strong(DumpTimeTable_lock); + if (k->is_loader_alive()) { + bool result = _iter->do_entry(k, info); + assert(k->is_loader_alive(), "must not change"); + return result; + } else { + if (!SystemDictionaryShared::is_excluded_class(k)) { + SystemDictionaryShared::warn_excluded(k, "Class loader not alive"); + SystemDictionaryShared::set_excluded_locked(k); + } + return true; + } + } +}; + +template +void DumpTimeSharedClassTable::iterate(ITER* iter) const { + IterationHelper helper(iter); + DumpTimeSharedClassTableBaseType::iterate(&helper); +} + +#endif // INCLUDE_CDS + +#endif // SHARED_CDS_DUMPTIMESHAREDCLASSINFO_INLINE_HPP diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index c821d46d4d0de45461ee3265f2ba30a13316766d..0ff6a017fedfef3a28f0c83fe28484edcb1696fd 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,6 +115,12 @@ public: MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); SystemDictionaryShared::check_excluded_classes(); + if (SystemDictionaryShared::is_dumptime_table_empty()) { + log_warning(cds, dynamic)("There is no class to be included in the dynamic archive."); + SystemDictionaryShared::stop_dumping(); + return; + } + // save dumptime tables SystemDictionaryShared::clone_dumptime_tables(); @@ -171,6 +177,7 @@ public: assert(_num_dump_regions_used == _total_dump_regions, "must be"); verify_universe("After CDS dynamic dump"); + SystemDictionaryShared::stop_dumping(); } virtual void iterate_roots(MetaspaceClosure* it, bool is_relocating_pointers) { @@ -180,7 +187,7 @@ public: }; void DynamicArchiveBuilder::init_header() { - FileMapInfo* mapinfo = new FileMapInfo(false); + FileMapInfo* mapinfo = new FileMapInfo(_archive_name, false); assert(FileMapInfo::dynamic_info() == mapinfo, "must be"); FileMapInfo* base_info = FileMapInfo::current_info(); // header only be available after populate_header @@ -320,7 +327,7 @@ void DynamicArchiveBuilder::write_archive(char* serialized_data) { FileMapInfo* dynamic_info = FileMapInfo::dynamic_info(); assert(dynamic_info != NULL, "Sanity"); - dynamic_info->open_for_write(_archive_name); + dynamic_info->open_for_write(); ArchiveBuilder::write_archive(dynamic_info, NULL, NULL, NULL, NULL); address base = _requested_dynamic_archive_bottom; @@ -342,10 +349,6 @@ public: VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; } void doit() { ResourceMark rm; - if (SystemDictionaryShared::is_dumptime_table_empty()) { - log_warning(cds, dynamic)("There is no class to be included in the dynamic archive."); - return; - } if (AllowArchivingWithJavaAgent) { warning("This archive was created with AllowArchivingWithJavaAgent. It should be used " "for testing purposes only and should not be used in a production environment"); @@ -354,6 +357,9 @@ public: _builder.doit(); } + ~VM_PopulateDynamicDumpSharedSpace() { + LambdaFormInvokers::cleanup_regenerated_classes(); + } }; void DynamicArchive::check_for_dynamic_dump() { @@ -378,7 +384,7 @@ void DynamicArchive::check_for_dynamic_dump() { void DynamicArchive::prepare_for_dump_at_exit() { EXCEPTION_MARK; ResourceMark rm(THREAD); - MetaspaceShared::link_shared_classes(THREAD); + MetaspaceShared::link_shared_classes(false/*not from jcmd*/, THREAD); if (HAS_PENDING_EXCEPTION) { log_error(cds)("Dynamic dump has failed"); log_error(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), @@ -394,7 +400,7 @@ void DynamicArchive::dump_for_jcmd(const char* archive_name, TRAPS) { assert(UseSharedSpaces && RecordDynamicDumpInfo, "already checked in arguments.cpp"); assert(ArchiveClassesAtExit == nullptr, "already checked in arguments.cpp"); assert(DynamicDumpSharedSpaces, "already checked by check_for_dynamic_dump() during VM startup"); - MetaspaceShared::link_shared_classes(CHECK); + MetaspaceShared::link_shared_classes(true/*from jcmd*/, CHECK); dump(archive_name, THREAD); } diff --git a/src/hotspot/share/cds/dynamicArchive.hpp b/src/hotspot/share/cds/dynamicArchive.hpp index fbb831ae1953b9b4afa65b8bc853fbdd38b13d12..ec8a505978b9450ceead4846f0c1515b0a02f1fb 100644 --- a/src/hotspot/share/cds/dynamicArchive.hpp +++ b/src/hotspot/share/cds/dynamicArchive.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "cds/filemap.hpp" #include "classfile/compactHashtable.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/memRegion.hpp" #include "memory/virtualspace.hpp" #include "oops/oop.hpp" diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 72a0d35bca72d8903762048eedaae73b2bed3fe9..5128565803b8e48e9b91f469208326b9094fa16d 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,7 +121,6 @@ void FileMapInfo::fail_continue(const char *msg, ...) { fail_exit(msg, ap); } else { if (log_is_enabled(Info, cds)) { - ResourceMark rm; LogStream ls(Log(cds)::info()); ls.print("UseSharedSpaces: "); ls.vprint_cr(msg, ap); @@ -167,8 +166,9 @@ template static void get_header_version(char (&header_version) [N]) { assert(header_version[JVM_IDENT_MAX-1] == 0, "must be"); } -FileMapInfo::FileMapInfo(bool is_static) { +FileMapInfo::FileMapInfo(const char* full_path, bool is_static) { memset((void*)this, 0, sizeof(FileMapInfo)); + _full_path = full_path; _is_static = is_static; if (_is_static) { assert(_current_info == NULL, "must be singleton"); // not thread safe @@ -189,6 +189,9 @@ FileMapInfo::~FileMapInfo() { assert(_dynamic_archive_info == this, "must be singleton"); // not thread safe _dynamic_archive_info = NULL; } + if (_file_open) { + ::close(_fd); + } } void FileMapInfo::populate_header(size_t core_region_alignment) { @@ -242,8 +245,13 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment, _narrow_oop_mode = CompressedOops::mode(); _narrow_oop_base = CompressedOops::base(); _narrow_oop_shift = CompressedOops::shift(); - _heap_begin = CompressedOops::begin(); - _heap_end = CompressedOops::end(); + if (UseCompressedOops) { + _heap_begin = CompressedOops::begin(); + _heap_end = CompressedOops::end(); + } else { + _heap_begin = (address)G1CollectedHeap::heap()->reserved().start(); + _heap_end = (address)G1CollectedHeap::heap()->reserved().end(); + } } _compressed_oops = UseCompressedOops; _compressed_class_ptrs = UseCompressedClassPointers; @@ -274,7 +282,6 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment, if (!DynamicDumpSharedSpaces) { set_shared_path_table(info->_shared_path_table); - CDS_JAVA_HEAP_ONLY(_heap_obj_roots = CompressedOops::encode(HeapShared::roots());) } } @@ -314,6 +321,7 @@ void FileMapHeader::print(outputStream* st) { st->print_cr("- compressed_class_ptrs: %d", _compressed_class_ptrs); st->print_cr("- cloned_vtables_offset: " SIZE_FORMAT_HEX, _cloned_vtables_offset); st->print_cr("- serialized_data_offset: " SIZE_FORMAT_HEX, _serialized_data_offset); + st->print_cr("- heap_begin: " INTPTR_FORMAT, p2i(_heap_begin)); st->print_cr("- heap_end: " INTPTR_FORMAT, p2i(_heap_end)); st->print_cr("- jvm_ident: %s", _jvm_ident); st->print_cr("- shared_path_table_offset: " SIZE_FORMAT_HEX, _shared_path_table_offset); @@ -765,6 +773,21 @@ int FileMapInfo::num_paths(const char* path) { return npaths; } +// Returns true if a path within the paths exists and has non-zero size. +bool FileMapInfo::check_paths_existence(const char* paths) { + ClasspathStream cp_stream(paths); + bool exist = false; + struct stat st; + while (cp_stream.has_next()) { + const char* path = cp_stream.get_next(); + if (os::stat(path, &st) == 0 && st.st_size > 0) { + exist = true; + break; + } + } + return exist; +} + GrowableArray* FileMapInfo::create_path_array(const char* paths) { GrowableArray* path_array = new GrowableArray(10); JavaThread* current = JavaThread::current(); @@ -848,7 +871,12 @@ bool FileMapInfo::validate_boot_class_paths() { if (relaxed_check) { return true; // ok, relaxed check, runtime has extra boot append path entries } else { - mismatch = true; + ResourceMark rm; + if (check_paths_existence(rp)) { + // If a path exists in the runtime boot paths, it is considered a mismatch + // since there's no boot path specified during dump time. + mismatch = true; + } } } else if (dp_len > 0 && rp != NULL) { int num; @@ -1042,25 +1070,41 @@ void FileMapInfo::validate_non_existent_class_paths() { } } -// a utility class for checking file header +// A utility class for reading/validating the GenericCDSFileMapHeader portion of +// a CDS archive's header. The file header of all CDS archives with versions from +// CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION (12) are guaranteed to always start +// with GenericCDSFileMapHeader. This makes it possible to read important information +// from a CDS archive created by a different version of HotSpot, so that we can +// automatically regenerate the archive as necessary (JDK-8261455). class FileHeaderHelper { int _fd; - GenericCDSFileMapHeader _header; + bool _is_valid; + bool _is_static; + GenericCDSFileMapHeader* _header; + const char* _archive_name; + const char* _base_archive_name; public: - FileHeaderHelper() { + FileHeaderHelper(const char* archive_name, bool is_static) { _fd = -1; + _is_valid = false; + _header = nullptr; + _base_archive_name = nullptr; + _archive_name = archive_name; + _is_static = is_static; } ~FileHeaderHelper() { if (_fd != -1) { - os::close(_fd); + ::close(_fd); } } - bool initialize(const char* archive_name) { - _fd = os::open(archive_name, O_RDONLY | O_BINARY, 0); + bool initialize() { + assert(_archive_name != nullptr, "Archive name is NULL"); + _fd = os::open(_archive_name, O_RDONLY | O_BINARY, 0); if (_fd < 0) { + FileMapInfo::fail_continue("Specified shared archive not found (%s)", _archive_name); return false; } return initialize(_fd); @@ -1068,143 +1112,200 @@ public: // for an already opened file, do not set _fd bool initialize(int fd) { - assert(fd != -1, "Archive should be opened"); + assert(_archive_name != nullptr, "Archive name is NULL"); + assert(fd != -1, "Archive must be opened already"); + // First read the generic header so we know the exact size of the actual header. + GenericCDSFileMapHeader gen_header; size_t size = sizeof(GenericCDSFileMapHeader); - lseek(fd, 0, SEEK_SET); - size_t n = os::read(fd, (void*)&_header, (unsigned int)size); + os::lseek(fd, 0, SEEK_SET); + size_t n = ::read(fd, (void*)&gen_header, (unsigned int)size); if (n != size) { - vm_exit_during_initialization("Unable to read generic CDS file map header from shared archive"); + FileMapInfo::fail_continue("Unable to read generic CDS file map header from shared archive"); return false; } - return true; - } - GenericCDSFileMapHeader* get_generic_file_header() { - return &_header; - } - - char* read_base_archive_name() { - assert(_fd != -1, "Archive should be open"); - size_t name_size = _header._base_archive_name_size; - assert(name_size != 0, "For non-default base archive, name size should be non-zero!"); - char* base_name = NEW_C_HEAP_ARRAY(char, name_size, mtInternal); - lseek(_fd, _header._base_archive_name_offset, SEEK_SET); // position to correct offset. - size_t n = os::read(_fd, base_name, (unsigned int)name_size); - if (n != name_size) { - log_info(cds)("Unable to read base archive name from archive"); - FREE_C_HEAP_ARRAY(char, base_name); - return nullptr; - } - if (base_name[name_size - 1] != '\0' || strlen(base_name) != name_size - 1) { - log_info(cds)("Base archive name is damaged"); - FREE_C_HEAP_ARRAY(char, base_name); - return nullptr; + if (gen_header._magic != CDS_ARCHIVE_MAGIC && + gen_header._magic != CDS_DYNAMIC_ARCHIVE_MAGIC) { + FileMapInfo::fail_continue("The shared archive file has a bad magic number: %#x", gen_header._magic); + return false; } - if (!os::file_exists(base_name)) { - log_info(cds)("Base archive %s does not exist", base_name); - FREE_C_HEAP_ARRAY(char, base_name); - return nullptr; + + if (gen_header._version < CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION) { + FileMapInfo::fail_continue("Cannot handle shared archive file version %d. Must be at least %d", + gen_header._version, CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION); + return false; } - return base_name; - } -}; -bool FileMapInfo::check_archive(const char* archive_name, bool is_static) { - FileHeaderHelper file_helper; - if (!file_helper.initialize(archive_name)) { - // do not vm_exit_during_initialization here because Arguments::init_shared_archive_paths() - // requires a shared archive name. The open_for_read() function will log a message regarding - // failure in opening a shared archive. - return false; - } + if (gen_header._version != CURRENT_CDS_ARCHIVE_VERSION) { + FileMapInfo::fail_continue("The shared archive file version %d does not match the required version %d", + gen_header._version, CURRENT_CDS_ARCHIVE_VERSION); + } - GenericCDSFileMapHeader* header = file_helper.get_generic_file_header(); - if (is_static) { - if (header->_magic != CDS_ARCHIVE_MAGIC) { - vm_exit_during_initialization("Not a base shared archive", archive_name); + size_t filelen = os::lseek(fd, 0, SEEK_END); + if (gen_header._header_size >= filelen) { + FileMapInfo::fail_continue("Archive file header larger than archive file"); return false; } - if (header->_base_archive_name_offset != 0) { - log_info(cds)("_base_archive_name_offset should be 0"); - log_info(cds)("_base_archive_name_offset = " UINT32_FORMAT, header->_base_archive_name_offset); + + // Read the actual header and perform more checks + size = gen_header._header_size; + _header = (GenericCDSFileMapHeader*)NEW_C_HEAP_ARRAY(char, size, mtInternal); + os::lseek(fd, 0, SEEK_SET); + n = ::read(fd, (void*)_header, (unsigned int)size); + if (n != size) { + FileMapInfo::fail_continue("Unable to read actual CDS file map header from shared archive"); return false; } - } else { - if (header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) { - vm_exit_during_initialization("Not a top shared archive", archive_name); + + if (!check_crc()) { return false; } - unsigned int name_size = header->_base_archive_name_size; - unsigned int name_offset = header->_base_archive_name_offset; - unsigned int header_size = header->_header_size; - if (name_offset + name_size != header_size) { - log_info(cds)("_header_size should be equal to _base_archive_name_offset plus _base_archive_name_size"); - log_info(cds)(" _base_archive_name_size = " UINT32_FORMAT, name_size); - log_info(cds)(" _base_archive_name_offset = " UINT32_FORMAT, name_offset); - log_info(cds)(" _header_size = " UINT32_FORMAT, header_size); + + if (!check_and_init_base_archive_name()) { return false; } - char* base_name = file_helper.read_base_archive_name(); - if (base_name == nullptr) { + + // All fields in the GenericCDSFileMapHeader has been validated. + _is_valid = true; + return true; + } + + GenericCDSFileMapHeader* get_generic_file_header() { + assert(_header != nullptr && _is_valid, "must be a valid archive file"); + return _header; + } + + const char* base_archive_name() { + assert(_header != nullptr && _is_valid, "must be a valid archive file"); + return _base_archive_name; + } + + private: + bool check_crc() { + if (VerifySharedSpaces) { + FileMapHeader* header = (FileMapHeader*)_header; + int actual_crc = header->compute_crc(); + if (actual_crc != header->crc()) { + log_info(cds)("_crc expected: %d", header->crc()); + log_info(cds)(" actual: %d", actual_crc); + FileMapInfo::fail_continue("Header checksum verification failed."); + return false; + } + } + return true; + } + + bool check_and_init_base_archive_name() { + unsigned int name_offset = _header->_base_archive_name_offset; + unsigned int name_size = _header->_base_archive_name_size; + unsigned int header_size = _header->_header_size; + + if (name_offset + name_size < name_offset) { + FileMapInfo::fail_continue("base_archive_name offset/size overflow: " UINT32_FORMAT "/" UINT32_FORMAT, + name_offset, name_size); return false; } - FREE_C_HEAP_ARRAY(char, base_name); + if (_header->_magic == CDS_ARCHIVE_MAGIC) { + if (name_offset != 0) { + FileMapInfo::fail_continue("static shared archive must have zero _base_archive_name_offset"); + return false; + } + if (name_size != 0) { + FileMapInfo::fail_continue("static shared archive must have zero _base_archive_name_size"); + return false; + } + } else { + assert(_header->_magic == CDS_DYNAMIC_ARCHIVE_MAGIC, "must be"); + if ((name_size == 0 && name_offset != 0) || + (name_size != 0 && name_offset == 0)) { + // If either is zero, both must be zero. This indicates that we are using the default base archive. + FileMapInfo::fail_continue("Invalid base_archive_name offset/size: " UINT32_FORMAT "/" UINT32_FORMAT, + name_offset, name_size); + return false; + } + if (name_size > 0) { + if (name_offset + name_size > header_size) { + FileMapInfo::fail_continue("Invalid base_archive_name offset/size (out of range): " + UINT32_FORMAT " + " UINT32_FORMAT " > " UINT32_FORMAT , + name_offset, name_size, header_size); + return false; + } + const char* name = ((const char*)_header) + _header->_base_archive_name_offset; + if (name[name_size - 1] != '\0' || strlen(name) != name_size - 1) { + FileMapInfo::fail_continue("Base archive name is damaged"); + return false; + } + if (!os::file_exists(name)) { + FileMapInfo::fail_continue("Base archive %s does not exist", name); + return false; + } + _base_archive_name = name; + } + } + return true; } - return true; -} +}; +// Return value: +// false: +// is not a valid archive. *base_archive_name is set to null. +// true && (*base_archive_name) == NULL: +// is a valid static archive. +// true && (*base_archive_name) != NULL: +// is a valid dynamic archive. bool FileMapInfo::get_base_archive_name_from_header(const char* archive_name, char** base_archive_name) { - FileHeaderHelper file_helper; - if (!file_helper.initialize(archive_name)) { + FileHeaderHelper file_helper(archive_name, false); + *base_archive_name = NULL; + + if (!file_helper.initialize()) { return false; } GenericCDSFileMapHeader* header = file_helper.get_generic_file_header(); if (header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) { - // Not a dynamic header, no need to proceed further. - return false; + assert(header->_magic == CDS_ARCHIVE_MAGIC, "must be"); + if (AutoCreateSharedArchive) { + log_warning(cds)("AutoCreateSharedArchive is ignored because %s is a static archive", archive_name); + } + return true; } - if ((header->_base_archive_name_size == 0 && header->_base_archive_name_offset != 0) || - (header->_base_archive_name_size != 0 && header->_base_archive_name_offset == 0)) { - fail_continue("Default base archive not set correct"); - return false; - } - if (header->_base_archive_name_size == 0 && - header->_base_archive_name_offset == 0) { + const char* base = file_helper.base_archive_name(); + if (base == nullptr) { *base_archive_name = Arguments::get_default_shared_archive_path(); } else { - // read the base archive name - *base_archive_name = file_helper.read_base_archive_name(); - if (*base_archive_name == nullptr) { - return false; - } + *base_archive_name = os::strdup_check_oom(base); } + return true; } // Read the FileMapInfo information from the file. bool FileMapInfo::init_from_file(int fd) { - FileHeaderHelper file_helper; + FileHeaderHelper file_helper(_full_path, _is_static); if (!file_helper.initialize(fd)) { fail_continue("Unable to read the file header."); return false; } GenericCDSFileMapHeader* gen_header = file_helper.get_generic_file_header(); - unsigned int expected_magic = is_static() ? CDS_ARCHIVE_MAGIC : CDS_DYNAMIC_ARCHIVE_MAGIC; - if (gen_header->_magic != expected_magic) { - log_info(cds)("_magic expected: 0x%08x", expected_magic); - log_info(cds)(" actual: 0x%08x", gen_header->_magic); - FileMapInfo::fail_continue("The shared archive file has a bad magic number."); - return false; + if (_is_static) { + if (gen_header->_magic != CDS_ARCHIVE_MAGIC) { + FileMapInfo::fail_continue("Not a base shared archive: %s", _full_path); + return false; + } + } else { + if (gen_header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) { + FileMapInfo::fail_continue("Not a top shared archive: %s", _full_path); + return false; + } } _header = (FileMapHeader*)os::malloc(gen_header->_header_size, mtInternal); - lseek(fd, 0, SEEK_SET); // reset to begin of the archive + os::lseek(fd, 0, SEEK_SET); // reset to begin of the archive size_t size = gen_header->_header_size; - size_t n = os::read(fd, (void*)_header, (unsigned int)size); + size_t n = ::read(fd, (void*)_header, (unsigned int)size); if (n != size) { fail_continue("Failed to read file header from the top archive file\n"); return false; @@ -1247,22 +1348,12 @@ bool FileMapInfo::init_from_file(int fd) { return false; } - if (VerifySharedSpaces) { - int expected_crc = header()->compute_crc(); - if (expected_crc != header()->crc()) { - log_info(cds)("_crc expected: %d", expected_crc); - log_info(cds)(" actual: %d", header()->crc()); - FileMapInfo::fail_continue("Header checksum verification failed."); - return false; - } - } - _file_offset = header()->header_size(); // accounts for the size of _base_archive_name if (is_static()) { // just checking the last region is sufficient since the archive is written // in sequential order - size_t len = lseek(fd, 0, SEEK_END); + size_t len = os::lseek(fd, 0, SEEK_END); FileMapRegion* si = space_at(MetaspaceShared::last_valid_region); // The last space might be empty if (si->file_offset() > len || len - si->file_offset() < si->used()) { @@ -1275,7 +1366,7 @@ bool FileMapInfo::init_from_file(int fd) { } void FileMapInfo::seek_to_position(size_t pos) { - if (lseek(_fd, (long)pos, SEEK_SET) < 0) { + if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) { fail_stop("Unable to seek to position " SIZE_FORMAT, pos); } } @@ -1285,18 +1376,13 @@ bool FileMapInfo::open_for_read() { if (_file_open) { return true; } - if (is_static()) { - _full_path = Arguments::GetSharedArchivePath(); - } else { - _full_path = Arguments::GetSharedDynamicArchivePath(); - } log_info(cds)("trying to map %s", _full_path); int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0); if (fd < 0) { if (errno == ENOENT) { - fail_continue("Specified shared archive not found (%s).", _full_path); + fail_continue("Specified shared archive not found (%s)", _full_path); } else { - fail_continue("Failed to open shared archive file (%s).", + fail_continue("Failed to open shared archive file (%s)", os::strerror(errno)); } return false; @@ -1311,12 +1397,7 @@ bool FileMapInfo::open_for_read() { // Write the FileMapInfo information to the file. -void FileMapInfo::open_for_write(const char* path) { - if (path == NULL) { - _full_path = Arguments::GetSharedArchivePath(); - } else { - _full_path = path; - } +void FileMapInfo::open_for_write() { LogMessage(cds) msg; if (msg.is_info()) { msg.info("Dumping shared data to file: "); @@ -1416,7 +1497,11 @@ void FileMapInfo::write_region(int region, char* base, size_t size, } else if (HeapShared::is_heap_region(region)) { assert(!DynamicDumpSharedSpaces, "must be"); requested_base = base; - mapping_offset = (size_t)CompressedOops::encode_not_null(cast_to_oop(base)); + if (UseCompressedOops) { + mapping_offset = (size_t)CompressedOops::encode_not_null(cast_to_oop(base)); + } else { + mapping_offset = requested_base - (char*)G1CollectedHeap::heap()->reserved().start(); + } assert(mapping_offset == (size_t)(uint32_t)mapping_offset, "must be 32-bit only"); } else { char* requested_SharedBaseAddress = (char*)MetaspaceShared::requested_base_address(); @@ -1550,8 +1635,8 @@ size_t FileMapInfo::write_heap_regions(GrowableArray* regions, void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) { assert(_file_open, "must be"); - size_t n = os::write(_fd, buffer, (unsigned int)nbytes); - if (n != nbytes) { + ssize_t n = os::write(_fd, buffer, (unsigned int)nbytes); + if (n < 0 || (size_t)n != nbytes) { // If the shared archive is corrupted, close it and remove it. close(); remove(_full_path); @@ -1686,7 +1771,7 @@ bool FileMapInfo::read_region(int i, char* base, size_t size, bool do_commit) { return false; } } - if (lseek(_fd, (long)si->file_offset(), SEEK_SET) != (int)si->file_offset() || + if (os::lseek(_fd, (long)si->file_offset(), SEEK_SET) != (int)si->file_offset() || read_bytes(base, size) != size) { return false; } @@ -1723,7 +1808,7 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba if (MetaspaceShared::use_windows_memory_mapping() && rs.is_reserved()) { // This is the second time we try to map the archive(s). We have already created a ReservedSpace // that covers all the FileMapRegions to ensure all regions can be mapped. However, Windows - // can't mmap into a ReservedSpace, so we just os::read() the data. We're going to patch all the + // can't mmap into a ReservedSpace, so we just ::read() the data. We're going to patch all the // regions anyway, so there's no benefit for mmap anyway. if (!read_region(i, requested_addr, size, /* do_commit = */ true)) { log_info(cds)("Failed to read %s shared space into reserved space at " INTPTR_FORMAT, @@ -1829,7 +1914,7 @@ bool FileMapInfo::relocate_pointers_in_core_regions(intx addr_delta) { size_t FileMapInfo::read_bytes(void* buffer, size_t count) { assert(_file_open, "Archive file is not open"); - size_t n = os::read(_fd, buffer, (unsigned int)count); + size_t n = ::read(_fd, buffer, (unsigned int)count); if (n != count) { // Close the file if there's a problem reading it. close(); @@ -1938,7 +2023,10 @@ bool FileMapInfo::can_use_heap_regions() { log_info(cds)(" narrow_oop_mode = %d, narrow_oop_base = " PTR_FORMAT ", narrow_oop_shift = %d", CompressedOops::mode(), p2i(CompressedOops::base()), CompressedOops::shift()); log_info(cds)(" heap range = [" PTR_FORMAT " - " PTR_FORMAT "]", - p2i(CompressedOops::begin()), p2i(CompressedOops::end())); + UseCompressedOops ? p2i(CompressedOops::begin()) : + UseG1GC ? p2i((address)G1CollectedHeap::heap()->reserved().start()) : 0L, + UseCompressedOops ? p2i(CompressedOops::end()) : + UseG1GC ? p2i((address)G1CollectedHeap::heap()->reserved().end()) : 0L); if (narrow_klass_base() != CompressedKlassPointers::base() || narrow_klass_shift() != CompressedKlassPointers::shift()) { @@ -1948,6 +2036,26 @@ bool FileMapInfo::can_use_heap_regions() { return true; } +// The address where the bottom of this shared heap region should be mapped +// at runtime +address FileMapInfo::heap_region_runtime_start_address(FileMapRegion* spc) { + assert(UseSharedSpaces, "runtime only"); + spc->assert_is_heap_region(); + if (UseCompressedOops) { + return start_address_as_decoded_from_archive(spc); + } else { + assert(is_aligned(spc->mapping_offset(), sizeof(HeapWord)), "must be"); + return header()->heap_begin() + spc->mapping_offset() + HeapShared::runtime_delta(); + } +} + +void FileMapInfo::set_shared_heap_runtime_delta(ptrdiff_t delta) { + if (UseCompressedOops) { + HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift()); + } else { + HeapShared::set_runtime_delta(delta); + } +} // // Map the closed and open archive heap objects to the runtime java heap. @@ -1970,39 +2078,66 @@ void FileMapInfo::map_heap_regions_impl() { log_info(cds)("CDS heap data needs to be relocated because the archive was created with an incompatible oop encoding mode."); _heap_pointers_need_patching = true; } else { - MemRegion range = get_heap_regions_range_with_current_oop_encoding_mode(); - if (!CompressedOops::is_in(range)) { - log_info(cds)("CDS heap data needs to be relocated because"); - log_info(cds)("the desired range " PTR_FORMAT " - " PTR_FORMAT, p2i(range.start()), p2i(range.end())); - log_info(cds)("is outside of the heap " PTR_FORMAT " - " PTR_FORMAT, p2i(CompressedOops::begin()), p2i(CompressedOops::end())); - _heap_pointers_need_patching = true; - } else if (header()->heap_end() != CompressedOops::end()) { - log_info(cds)("CDS heap data needs to be relocated to the end of the runtime heap to reduce fragmentation"); - _heap_pointers_need_patching = true; + if (UseCompressedOops) { + MemRegion range = get_heap_regions_range_with_current_oop_encoding_mode(); + if (!CompressedOops::is_in(range)) { + log_info(cds)("CDS heap data needs to be relocated because"); + log_info(cds)("the desired range " PTR_FORMAT " - " PTR_FORMAT, p2i(range.start()), p2i(range.end())); + log_info(cds)("is outside of the heap " PTR_FORMAT " - " PTR_FORMAT, p2i(CompressedOops::begin()), p2i(CompressedOops::end())); + _heap_pointers_need_patching = true; + } else if (header()->heap_end() != CompressedOops::end()) { + log_info(cds)("CDS heap data needs to be relocated to the end of the runtime heap to reduce fragmentation"); + _heap_pointers_need_patching = true; + } + } else { + MemRegion range((HeapWord*)header()->heap_begin(), (HeapWord*)header()->heap_end()); + if (!G1CollectedHeap::heap()->reserved().contains(range)) { + log_info(cds)("CDS heap data needs to be relocated because"); + log_info(cds)("the desired range " PTR_FORMAT " - " PTR_FORMAT, p2i(range.start()), p2i(range.end())); + log_info(cds)("is outside of the heap " PTR_FORMAT " - " PTR_FORMAT, + p2i((address)G1CollectedHeap::heap()->reserved().start()), p2i((address)G1CollectedHeap::heap()->reserved().end())); + _heap_pointers_need_patching = true; + } else if (header()->heap_end() != (address)G1CollectedHeap::heap()->reserved().end()) { + log_info(cds)("CDS heap data needs to be relocated to the end of the runtime heap to reduce fragmentation"); + _heap_pointers_need_patching = true; + } } } ptrdiff_t delta = 0; if (_heap_pointers_need_patching) { // dumptime heap end ------------v - // [ |archived heap regions| ] runtime heap end ------v + // [ |archived heap regions| ] run time heap end -----v // [ |archived heap regions| ] + // ^ + // D ^ + // R // |<-----delta-------------------->| // // At dump time, the archived heap regions were near the top of the heap. - // At run time, they may not be inside the heap, so we move them so - // that they are now near the top of the runtime time. This can be done by + // At run time, if the heap ends at a different address, we need to + // move them near to top of the run time heap. This can be done by // the simple math of adding the delta as shown above. + // + // Also: D = bottom of a heap region at dump time + // R = bottom of a heap region at run time + // + // FileMapRegion* spc = ...; + // address D = header()->heap_begin() + spc->mapping_offset(); + // address R = D + delta; address dumptime_heap_end = header()->heap_end(); - address runtime_heap_end = CompressedOops::end(); + address runtime_heap_end = UseCompressedOops ? CompressedOops::end() : + (address)G1CollectedHeap::heap()->reserved().end(); delta = runtime_heap_end - dumptime_heap_end; } log_info(cds)("CDS heap data relocation delta = " INTX_FORMAT " bytes", delta); - HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift()); + + set_shared_heap_runtime_delta(delta); FileMapRegion* si = space_at(MetaspaceShared::first_closed_heap_region); - address relocated_closed_heap_region_bottom = start_address_as_decoded_from_archive(si); + address relocated_closed_heap_region_bottom = heap_region_runtime_start_address(si); + if (!is_aligned(relocated_closed_heap_region_bottom, HeapRegion::GrainBytes)) { // Align the bottom of the closed archive heap regions at G1 region boundary. // This will avoid the situation where the highest open region and the lowest @@ -2013,9 +2148,9 @@ void FileMapInfo::map_heap_regions_impl() { log_info(cds)("CDS heap data needs to be relocated lower by a further " SIZE_FORMAT " bytes to " INTX_FORMAT " to be aligned with HeapRegion::GrainBytes", align, delta); - HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift()); + set_shared_heap_runtime_delta(delta); + relocated_closed_heap_region_bottom = heap_region_runtime_start_address(si); _heap_pointers_need_patching = true; - relocated_closed_heap_region_bottom = start_address_as_decoded_from_archive(si); } assert(is_aligned(relocated_closed_heap_region_bottom, HeapRegion::GrainBytes), "must be"); @@ -2033,7 +2168,6 @@ void FileMapInfo::map_heap_regions_impl() { /*is_open_archive=*/ true, &open_heap_regions, &num_open_heap_regions)) { HeapShared::set_open_regions_mapped(); - HeapShared::set_roots(header()->heap_obj_roots()); } } } @@ -2074,7 +2208,7 @@ bool FileMapInfo::map_heap_regions(int first, int max, bool is_open_archive, si = space_at(i); size_t size = si->used(); if (size > 0) { - HeapWord* start = (HeapWord*)start_address_as_decoded_from_archive(si); + HeapWord* start = (HeapWord*)heap_region_runtime_start_address(si); regions[num_regions] = MemRegion(start, size / HeapWordSize); num_regions ++; log_info(cds)("Trying to map heap data: region[%d] at " INTPTR_FORMAT ", size = " SIZE_FORMAT_W(8) " bytes", @@ -2302,15 +2436,20 @@ bool FileMapInfo::initialize() { return false; } - if (!open_for_read()) { - return false; - } - if (!init_from_file(_fd)) { - return false; - } - if (!validate_header()) { - return false; + if (!open_for_read() || !init_from_file(_fd) || !validate_header()) { + if (_is_static) { + FileMapInfo::fail_continue("Initialize static archive failed."); + return false; + } else { + FileMapInfo::fail_continue("Initialize dynamic archive failed."); + if (AutoCreateSharedArchive) { + DynamicDumpSharedSpaces = true; + ArchiveClassesAtExit = Arguments::GetSharedDynamicArchivePath(); + } + return false; + } } + return true; } @@ -2340,8 +2479,8 @@ void FileMapHeader::set_as_offset(char* p, size_t *offset) { int FileMapHeader::compute_crc() { char* start = (char*)this; - // start computing from the field after _crc to end of base archive name. - char* buf = (char*)&(_generic_header._crc) + sizeof(_generic_header._crc); + // start computing from the field after _header_size to end of base archive name. + char* buf = (char*)&(_generic_header._header_size) + sizeof(_generic_header._header_size); size_t sz = header_size() - (buf - start); int crc = ClassLoader::crc32(0, buf, (jint)sz); return crc; diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index 816ac5469dc5d7d548ddd3671f8256e4062ede9e..e66558581879c4c6b2222b91c3cd2d3ab036ab97 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -232,7 +232,6 @@ private: // some expensive operations. bool _use_full_module_graph; // Can we use the full archived module graph? size_t _ptrmap_size_in_bits; // Size of pointer relocation bitmap - narrowOop _heap_obj_roots; // An objArray that stores all the roots of archived heap objects char* from_mapped_offset(size_t offset) const { return mapped_base_address() + offset; } @@ -279,14 +278,12 @@ public: jshort app_module_paths_start_index() const { return _app_module_paths_start_index; } jshort app_class_paths_start_index() const { return _app_class_paths_start_index; } jshort num_module_paths() const { return _num_module_paths; } - narrowOop heap_obj_roots() const { return _heap_obj_roots; } void set_has_platform_or_app_classes(bool v) { _has_platform_or_app_classes = v; } void set_cloned_vtables(char* p) { set_as_offset(p, &_cloned_vtables_offset); } void set_serialized_data(char* p) { set_as_offset(p, &_serialized_data_offset); } void set_ptrmap_size_in_bits(size_t s) { _ptrmap_size_in_bits = s; } void set_mapped_base_address(char* p) { _mapped_base_address = p; } - void set_heap_obj_roots(narrowOop r) { _heap_obj_roots = r; } void copy_base_archive_name(const char* name); void set_shared_path_table(SharedPathTable table) { @@ -354,12 +351,10 @@ private: static bool _memory_mapping_failed; static GrowableArray* _non_existent_class_paths; - FileMapHeader *header() const { return _header; } - public: + FileMapHeader *header() const { return _header; } static bool get_base_archive_name_from_header(const char* archive_name, char** base_archive_name); - static bool check_archive(const char* archive_name, bool is_static); static SharedPathTable shared_path_table() { return _shared_path_table; } @@ -373,7 +368,7 @@ public: void log_paths(const char* msg, int start_idx, int end_idx); - FileMapInfo(bool is_static); + FileMapInfo(const char* full_apth, bool is_static); ~FileMapInfo(); // Accessors @@ -413,8 +408,6 @@ public: void set_requested_base(char* b) { header()->set_requested_base(b); } char* requested_base_address() const { return header()->requested_base_address(); } - narrowOop heap_obj_roots() const { return header()->heap_obj_roots(); } - class DynamicArchiveHeader* dynamic_header() const { assert(!is_static(), "must be"); return (DynamicArchiveHeader*)header(); @@ -446,7 +439,7 @@ public: // File manipulation. bool initialize() NOT_CDS_RETURN_(false); bool open_for_read(); - void open_for_write(const char* path = NULL); + void open_for_write(); void write_header(); void write_region(int region, char* base, size_t size, bool read_only, bool allow_exec); @@ -560,6 +553,7 @@ public: void seek_to_position(size_t pos); char* skip_first_path_entry(const char* path) NOT_CDS_RETURN_(NULL); int num_paths(const char* path) NOT_CDS_RETURN_(0); + bool check_paths_existence(const char* paths) NOT_CDS_RETURN_(false); GrowableArray* create_path_array(const char* path) NOT_CDS_RETURN_(NULL); bool classpath_failure(const char* msg, const char* name) NOT_CDS_RETURN_(false); bool check_paths(int shared_path_start_idx, int num_paths, @@ -573,6 +567,8 @@ public: bool can_use_heap_regions(); bool load_heap_regions() NOT_CDS_JAVA_HEAP_RETURN_(false); bool map_heap_regions() NOT_CDS_JAVA_HEAP_RETURN_(false); + address heap_region_runtime_start_address(FileMapRegion* spc) NOT_CDS_JAVA_HEAP_RETURN_(NULL); + void set_shared_heap_runtime_delta(ptrdiff_t delta) NOT_CDS_JAVA_HEAP_RETURN; void map_heap_regions_impl() NOT_CDS_JAVA_HEAP_RETURN; MapArchiveResult map_region(int i, intx addr_delta, char* mapped_base_address, ReservedSpace rs); bool relocate_pointers_in_core_regions(intx addr_delta); diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 2ae72ffb5edf06a6d008410e39a4b36717623c00..f519daabbe59b0b5accfacaf216a426d66e5544b 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,6 +76,7 @@ address HeapShared::_narrow_oop_base; int HeapShared::_narrow_oop_shift; DumpedInternedStrings *HeapShared::_dumped_interned_strings = NULL; +// Support for loaded heap. uintptr_t HeapShared::_loaded_heap_bottom = 0; uintptr_t HeapShared::_loaded_heap_top = 0; uintptr_t HeapShared::_dumptime_base_0 = UINTPTR_MAX; @@ -88,6 +89,10 @@ intx HeapShared::_runtime_offset_1 = 0; intx HeapShared::_runtime_offset_2 = 0; intx HeapShared::_runtime_offset_3 = 0; bool HeapShared::_loading_failed = false; + +// Suport for mapped heap (!UseCompressedOops only) +ptrdiff_t HeapShared::_runtime_delta = 0; + // // If you add new entries to the following tables, you should know what you're doing! // @@ -128,7 +133,6 @@ const static int num_fmg_open_archive_subgraph_entry_fields = sizeof(fmg_open_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo); GrowableArrayCHeap* HeapShared::_pending_roots = NULL; -narrowOop HeapShared::_roots_narrow; OopHandle HeapShared::_roots; #ifdef ASSERT @@ -152,7 +156,6 @@ void HeapShared::fixup_regions() { fill_failed_loaded_region(); } if (is_fully_available()) { - _roots = OopHandle(Universe::vm_global(), decode_from_archive(_roots_narrow)); if (!MetaspaceShared::use_full_module_graph()) { // Need to remove all the archived java.lang.Module objects from HeapShared::roots(). ClassLoaderDataShared::clear_archived_oops(); @@ -236,12 +239,6 @@ objArrayOop HeapShared::roots() { return roots; } -void HeapShared::set_roots(narrowOop roots) { - assert(UseSharedSpaces, "runtime only"); - assert(is_fully_available(), "must be"); - _roots_narrow = roots; -} - // Returns an objArray that contains all the roots of the archived objects oop HeapShared::get_root(int index, bool clear) { assert(index >= 0, "sanity"); @@ -370,7 +367,10 @@ void HeapShared::archive_objects(GrowableArray* closed_regions, create_archived_object_cache(); log_info(cds)("Heap range = [" PTR_FORMAT " - " PTR_FORMAT "]", - p2i(CompressedOops::begin()), p2i(CompressedOops::end())); + UseCompressedOops ? p2i(CompressedOops::begin()) : + p2i((address)G1CollectedHeap::heap()->reserved().start()), + UseCompressedOops ? p2i(CompressedOops::end()) : + p2i((address)G1CollectedHeap::heap()->reserved().end())); log_info(cds)("Dumping objects to closed archive heap region ..."); copy_closed_objects(closed_regions); @@ -666,11 +666,26 @@ void HeapShared::write_subgraph_info_table() { CompactHashtableWriter writer(d_table->_count, &stats); CopyKlassSubGraphInfoToArchive copy(&writer); d_table->iterate(©); - writer.dump(&_run_time_subgraph_info_table, "subgraphs"); } -void HeapShared::serialize_subgraph_info_table_header(SerializeClosure* soc) { +void HeapShared::serialize(SerializeClosure* soc) { + oop roots_oop = NULL; + + if (soc->reading()) { + soc->do_oop(&roots_oop); // read from archive + assert(oopDesc::is_oop_or_null(roots_oop), "is oop"); + // Create an OopHandle only if we have actually mapped or loaded the roots + if (roots_oop != NULL) { + assert(HeapShared::is_fully_available(), "must be"); + _roots = OopHandle(Universe::vm_global(), roots_oop); + } + } else { + // writing + roots_oop = roots(); + soc->do_oop(&roots_oop); // write to archive + } + _run_time_subgraph_info_table.serialize_header(soc); } @@ -1392,39 +1407,44 @@ void HeapShared::add_to_dumped_interned_strings(oop string) { // region. This way we can quickly relocate all the pointers without using // BasicOopIterateClosure at runtime. class FindEmbeddedNonNullPointers: public BasicOopIterateClosure { - narrowOop* _start; + void* _start; BitMap *_oopmap; int _num_total_oops; int _num_null_oops; public: - FindEmbeddedNonNullPointers(narrowOop* start, BitMap* oopmap) + FindEmbeddedNonNullPointers(void* start, BitMap* oopmap) : _start(start), _oopmap(oopmap), _num_total_oops(0), _num_null_oops(0) {} virtual void do_oop(narrowOop* p) { _num_total_oops ++; narrowOop v = *p; if (!CompressedOops::is_null(v)) { - size_t idx = p - _start; + size_t idx = p - (narrowOop*)_start; _oopmap->set_bit(idx); } else { _num_null_oops ++; } } - virtual void do_oop(oop *p) { - ShouldNotReachHere(); + virtual void do_oop(oop* p) { + _num_total_oops ++; + if ((*p) != NULL) { + size_t idx = p - (oop*)_start; + _oopmap->set_bit(idx); + } else { + _num_null_oops ++; + } } int num_total_oops() const { return _num_total_oops; } int num_null_oops() const { return _num_null_oops; } }; ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) { - assert(UseCompressedOops, "must be"); - size_t num_bits = region.byte_size() / sizeof(narrowOop); + size_t num_bits = region.byte_size() / (UseCompressedOops ? sizeof(narrowOop) : sizeof(oop)); ResourceBitMap oopmap(num_bits); HeapWord* p = region.start(); HeapWord* end = region.end(); - FindEmbeddedNonNullPointers finder((narrowOop*)p, &oopmap); + FindEmbeddedNonNullPointers finder((void*)p, &oopmap); ArchiveBuilder* builder = DumpSharedSpaces ? ArchiveBuilder::current() : NULL; int num_objs = 0; @@ -1445,11 +1465,11 @@ ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) { // Patch all the embedded oop pointers inside an archived heap region, // to be consistent with the runtime oop encoding. -class PatchEmbeddedPointers: public BitMapClosure { +class PatchCompressedEmbeddedPointers: public BitMapClosure { narrowOop* _start; public: - PatchEmbeddedPointers(narrowOop* start) : _start(start) {} + PatchCompressedEmbeddedPointers(narrowOop* start) : _start(start) {} bool do_bit(size_t offset) { narrowOop* p = _start + offset; @@ -1461,6 +1481,22 @@ class PatchEmbeddedPointers: public BitMapClosure { } }; +class PatchUncompressedEmbeddedPointers: public BitMapClosure { + oop* _start; + + public: + PatchUncompressedEmbeddedPointers(oop* start) : _start(start) {} + + bool do_bit(size_t offset) { + oop* p = _start + offset; + intptr_t dumptime_oop = (intptr_t)((void*)*p); + assert(dumptime_oop != 0, "null oops should have been filtered out at dump time"); + intptr_t runtime_oop = dumptime_oop + HeapShared::runtime_delta(); + RawAccess::oop_store(p, cast_to_oop(runtime_oop)); + return true; + } +}; + // Patch all the non-null pointers that are embedded in the archived heap objects // in this region void HeapShared::patch_embedded_pointers(MemRegion region, address oopmap, @@ -1473,8 +1509,13 @@ void HeapShared::patch_embedded_pointers(MemRegion region, address oopmap, assert(bm.is_same(checkBm), "sanity"); #endif - PatchEmbeddedPointers patcher((narrowOop*)region.start()); - bm.iterate(&patcher); + if (UseCompressedOops) { + PatchCompressedEmbeddedPointers patcher((narrowOop*)region.start()); + bm.iterate(&patcher); + } else { + PatchUncompressedEmbeddedPointers patcher((oop*)region.start()); + bm.iterate(&patcher); + } } // The CDS archive remembers each heap object by its address at dump time, but @@ -1695,7 +1736,6 @@ bool HeapShared::load_heap_regions(FileMapInfo* mapinfo) { init_loaded_heap_relocation(loaded_regions, num_loaded_regions); _is_loaded = true; - set_roots(mapinfo->heap_obj_roots()); return true; } diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index 52a8de9ad4602a37169e290647ab2690e94a96ee..fc7a0bcb57aec7972eea2b568b63b31cef982d3c 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -159,7 +159,7 @@ public: if (_disable_writing) { return false; } - return (UseG1GC && UseCompressedOops && UseCompressedClassPointers); + return (UseG1GC && UseCompressedClassPointers); ) NOT_CDS_JAVA_HEAP(return false;) } @@ -169,7 +169,7 @@ public: } // Can this VM map archived heap regions? Currently only G1+compressed{oops,cp} static bool can_map() { - CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedOops && UseCompressedClassPointers);) + CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedClassPointers);) NOT_CDS_JAVA_HEAP(return false;) } static bool is_mapped() { @@ -297,10 +297,13 @@ private: static void init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[], int num, TRAPS); - // Used by decode_from_archive + // UseCompressedOops only: Used by decode_from_archive static address _narrow_oop_base; static int _narrow_oop_shift; + // !UseCompressedOops only: used to relocate pointers to the archived objects + static ptrdiff_t _runtime_delta; + typedef ResourceHashtable* _pending_roots; - static narrowOop _roots_narrow; static OopHandle _roots; static void init_seen_objects_table() { @@ -418,11 +420,22 @@ private: static oop get_root(int index, bool clear=false); // Run-time only - static void set_roots(narrowOop roots); static void clear_root(int index); + + static void set_runtime_delta(ptrdiff_t delta) { + assert(!UseCompressedOops, "must be"); + _runtime_delta = delta; + } + #endif // INCLUDE_CDS_JAVA_HEAP public: + static ptrdiff_t runtime_delta() { + assert(!UseCompressedOops, "must be"); + CDS_JAVA_HEAP_ONLY(return _runtime_delta;) + NOT_CDS_JAVA_HEAP_RETURN_(0L); + } + static void run_full_gc_in_vm_thread() NOT_CDS_JAVA_HEAP_RETURN; static bool is_heap_region(int idx) { @@ -468,7 +481,7 @@ private: static void init_for_dumping(TRAPS) NOT_CDS_JAVA_HEAP_RETURN; static void write_subgraph_info_table() NOT_CDS_JAVA_HEAP_RETURN; - static void serialize_subgraph_info_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN; + static void serialize(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN; }; #if INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/lambdaFormInvokers.cpp b/src/hotspot/share/cds/lambdaFormInvokers.cpp index 5c058dc43ac131746c1ccb919189b51a94f56776..59666085d0499c19e4ca2e2eece19c2841a1517a 100644 --- a/src/hotspot/share/cds/lambdaFormInvokers.cpp +++ b/src/hotspot/share/cds/lambdaFormInvokers.cpp @@ -39,10 +39,11 @@ #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" -#include "oops/klass.hpp" +#include "oops/klass.inline.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" +#include "oops/oopHandle.inline.hpp" #include "oops/typeArrayOop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" @@ -50,6 +51,7 @@ GrowableArrayCHeap* LambdaFormInvokers::_lambdaform_lines = nullptr; Array*>* LambdaFormInvokers::_static_archive_invokers = nullptr; +GrowableArrayCHeap* LambdaFormInvokers::_regenerated_mirrors = nullptr; #define NUM_FILTER 4 static const char* filter[NUM_FILTER] = {"java.lang.invoke.Invokers$Holder", @@ -81,6 +83,25 @@ void LambdaFormInvokers::append(char* line) { _lambdaform_lines->append(line); } +// The regenerated Klass is not added to any class loader, so we need +// to keep its java_mirror alive to avoid class unloading. +void LambdaFormInvokers::add_regenerated_class(oop regenerated_class) { + if (_regenerated_mirrors == nullptr) { + _regenerated_mirrors = new GrowableArrayCHeap(150); + } + _regenerated_mirrors->append(OopHandle(Universe::vm_global(), regenerated_class)); +} + +void LambdaFormInvokers::cleanup_regenerated_classes() { + if (_regenerated_mirrors == nullptr) return; + + for (int i = 0; i < _regenerated_mirrors->length(); i++) { + _regenerated_mirrors->at(i).release(Universe::vm_global()); + } + delete _regenerated_mirrors; + _regenerated_mirrors = nullptr; +} + // convenient output class PrintLambdaFormMessage { public: @@ -155,12 +176,11 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) { char *buf = NEW_RESOURCE_ARRAY(char, len); memcpy(buf, (char*)h_bytes->byte_at_addr(0), len); ClassFileStream st((u1*)buf, len, NULL, ClassFileStream::verify); - reload_class(class_name, st, CHECK); + regenerate_class(class_name, st, CHECK); } } -// class_handle - the class name, bytes_handle - the class bytes -void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) { +void LambdaFormInvokers::regenerate_class(char* name, ClassFileStream& st, TRAPS) { Symbol* class_name = SymbolTable::new_symbol((const char*)name); // the class must exist Klass* klass = SystemDictionary::resolve_or_null(class_name, THREAD); @@ -180,6 +200,9 @@ void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) { cl_info, CHECK); + assert(result->java_mirror() != nullptr, "must be"); + add_regenerated_class(result->java_mirror()); + { MutexLocker mu_r(THREAD, Compile_lock); // add_to_hierarchy asserts this. SystemDictionary::add_to_hierarchy(result); @@ -191,7 +214,7 @@ void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) { // exclude the existing class from dump SystemDictionaryShared::set_excluded(InstanceKlass::cast(klass)); SystemDictionaryShared::init_dumptime_info(result); - log_info(cds, lambda)("Replaced class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT, + log_info(cds, lambda)("Regenerated class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT, name, p2i(klass), p2i(result)); } diff --git a/src/hotspot/share/cds/lambdaFormInvokers.hpp b/src/hotspot/share/cds/lambdaFormInvokers.hpp index acb5eab4d8adeb989c5314e0b72672f71dc390a3..c3b151790f1c0acd677ee72cd64c0210ffb8fcae 100644 --- a/src/hotspot/share/cds/lambdaFormInvokers.hpp +++ b/src/hotspot/share/cds/lambdaFormInvokers.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_CDS_LAMBDAFORMINVOKERS_HPP #define SHARE_CDS_LAMBDAFORMINVOKERS_HPP #include "memory/allStatic.hpp" +#include "oops/oopHandle.hpp" #include "runtime/handles.hpp" #include "utilities/growableArray.hpp" @@ -37,7 +38,9 @@ class LambdaFormInvokers : public AllStatic { static GrowableArrayCHeap* _lambdaform_lines; // For storing LF form lines (LF_RESOLVE only) in read only table. static Array*>* _static_archive_invokers; - static void reload_class(char* name, ClassFileStream& st, TRAPS); + static GrowableArrayCHeap* _regenerated_mirrors; + static void regenerate_class(char* name, ClassFileStream& st, TRAPS); + static void add_regenerated_class(oop regenerated_class); public: static void append(char* line); static void append_filtered(char* line); @@ -45,5 +48,6 @@ class LambdaFormInvokers : public AllStatic { static void read_static_archive_invokers(); static void regenerate_holder_classes(TRAPS); static void serialize(SerializeClosure* soc); + static void cleanup_regenerated_classes(); }; #endif // SHARE_CDS_LAMBDAFORMINVOKERS_HPP diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index 17e27a5372f6a65fced5c0f6a7af3a94c1c486af..10e96df575b3f84e166b6f0ca4178f320ad0ca09 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,6 +65,7 @@ #include "oops/oopHandle.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" +#include "runtime/globals_extension.hpp" #include "runtime/handles.inline.hpp" #include "runtime/os.hpp" #include "runtime/safepointVerifiers.hpp" @@ -384,7 +385,7 @@ void MetaspaceShared::serialize(SerializeClosure* soc) { // Dump/restore the symbol/string/subgraph_info tables SymbolTable::serialize_shared_table_header(soc); StringTable::serialize_shared_table_header(soc); - HeapShared::serialize_subgraph_info_table_header(soc); + HeapShared::serialize(soc); SystemDictionaryShared::serialize_dictionary_headers(soc); InstanceMirrorKlass::serialize_offsets(soc); @@ -556,7 +557,9 @@ void VM_PopulateDumpSharedSpace::doit() { builder.relocate_to_requested(); // Write the archive file - FileMapInfo* mapinfo = new FileMapInfo(true); + const char* static_archive = Arguments::GetSharedArchivePath(); + assert(static_archive != nullptr, "SharedArchiveFile not set?"); + FileMapInfo* mapinfo = new FileMapInfo(static_archive, true); mapinfo->populate_header(MetaspaceShared::core_region_alignment()); mapinfo->set_serialized_data(serialized_data); mapinfo->set_cloned_vtables(cloned_vtables); @@ -596,7 +599,7 @@ public: void do_cld(ClassLoaderData* cld) { assert(cld->is_alive(), "must be"); _loaded_cld.append(cld); - _loaded_cld_handles.append(OopHandle(Universe::vm_global(), cld->holder_phantom())); + _loaded_cld_handles.append(OopHandle(Universe::vm_global(), cld->holder())); } int nof_cld() const { return _loaded_cld.length(); } @@ -640,8 +643,10 @@ bool MetaspaceShared::link_class_for_cds(InstanceKlass* ik, TRAPS) { return res; } -void MetaspaceShared::link_shared_classes(TRAPS) { - LambdaFormInvokers::regenerate_holder_classes(CHECK); +void MetaspaceShared::link_shared_classes(bool jcmd_request, TRAPS) { + if (!jcmd_request) { + LambdaFormInvokers::regenerate_holder_classes(CHECK); + } // Collect all loaded ClassLoaderData. CollectCLDClosure collect_cld(THREAD); @@ -705,6 +710,30 @@ void MetaspaceShared::preload_and_dump() { } } +#if INCLUDE_CDS_JAVA_HEAP && defined(_LP64) +void MetaspaceShared::adjust_heap_sizes_for_dumping() { + if (!DumpSharedSpaces || UseCompressedOops) { + return; + } + // CDS heap dumping requires all string oops to have an offset + // from the heap bottom that can be encoded in 32-bit. + julong max_heap_size = (julong)(4 * G); + + if (MinHeapSize > max_heap_size) { + log_debug(cds)("Setting MinHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", MinHeapSize/M); + FLAG_SET_ERGO(MinHeapSize, max_heap_size); + } + if (InitialHeapSize > max_heap_size) { + log_debug(cds)("Setting InitialHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", InitialHeapSize/M); + FLAG_SET_ERGO(InitialHeapSize, max_heap_size); + } + if (MaxHeapSize > max_heap_size) { + log_debug(cds)("Setting MaxHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", MaxHeapSize/M); + FLAG_SET_ERGO(MaxHeapSize, max_heap_size); + } +} +#endif // INCLUDE_CDS_JAVA_HEAP && _LP64 + void MetaspaceShared::preload_classes(TRAPS) { char default_classlist[JVM_MAXPATHLEN]; const char* classlist_path; @@ -773,7 +802,7 @@ void MetaspaceShared::preload_and_dump_impl(TRAPS) { // were not explicitly specified in the classlist. E.g., if an interface implemented by class K // fails verification, all other interfaces that were not specified in the classlist but // are implemented by K are not verified. - link_shared_classes(CHECK); + link_shared_classes(false/*not from jcmd*/, CHECK); log_info(cds)("Rewriting and linking classes: done"); #if INCLUDE_CDS_JAVA_HEAP @@ -830,11 +859,10 @@ bool MetaspaceShared::try_link_class(JavaThread* current, InstanceKlass* ik) { void VM_PopulateDumpSharedSpace::dump_java_heap_objects(GrowableArray* klasses) { if(!HeapShared::can_write()) { log_info(cds)( - "Archived java heap is not supported as UseG1GC, " - "UseCompressedOops and UseCompressedClassPointers are required." - "Current settings: UseG1GC=%s, UseCompressedOops=%s, UseCompressedClassPointers=%s.", - BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedOops), - BOOL_TO_STR(UseCompressedClassPointers)); + "Archived java heap is not supported as UseG1GC " + "and UseCompressedClassPointers are required." + "Current settings: UseG1GC=%s, UseCompressedClassPointers=%s.", + BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedClassPointers)); return; } // Find all the interned strings that should be dumped. @@ -946,12 +974,20 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { _requested_base_address = static_mapinfo->requested_base_address(); if (dynamic_mapped) { FileMapInfo::set_shared_path_table(dynamic_mapinfo); + // turn AutoCreateSharedArchive off if successfully mapped + AutoCreateSharedArchive = false; } else { FileMapInfo::set_shared_path_table(static_mapinfo); } } else { set_shared_metaspace_range(NULL, NULL, NULL); + if (DynamicDumpSharedSpaces) { + warning("-XX:ArchiveClassesAtExit is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."); + } UseSharedSpaces = false; + // The base archive cannot be mapped. We cannot dump the dynamic shared archive. + AutoCreateSharedArchive = false; + DynamicDumpSharedSpaces = false; FileMapInfo::fail_continue("Unable to map shared spaces"); if (PrintSharedArchiveAndExit) { vm_exit_during_initialization("Unable to use shared archive."); @@ -967,7 +1003,9 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { } FileMapInfo* MetaspaceShared::open_static_archive() { - FileMapInfo* mapinfo = new FileMapInfo(true); + const char* static_archive = Arguments::GetSharedArchivePath(); + assert(static_archive != nullptr, "SharedArchivePath is NULL"); + FileMapInfo* mapinfo = new FileMapInfo(static_archive, true); if (!mapinfo->initialize()) { delete(mapinfo); return NULL; @@ -979,11 +1017,12 @@ FileMapInfo* MetaspaceShared::open_dynamic_archive() { if (DynamicDumpSharedSpaces) { return NULL; } - if (Arguments::GetSharedDynamicArchivePath() == NULL) { + const char* dynamic_archive = Arguments::GetSharedDynamicArchivePath(); + if (dynamic_archive == nullptr) { return NULL; } - FileMapInfo* mapinfo = new FileMapInfo(false); + FileMapInfo* mapinfo = new FileMapInfo(dynamic_archive, false); if (!mapinfo->initialize()) { delete(mapinfo); return NULL; diff --git a/src/hotspot/share/cds/metaspaceShared.hpp b/src/hotspot/share/cds/metaspaceShared.hpp index 74077d0fff05b582fca74a1d1c46e8760298de18..63c1089bd27a68c50d97fcdf8ccb0607cb0cbe65 100644 --- a/src/hotspot/share/cds/metaspaceShared.hpp +++ b/src/hotspot/share/cds/metaspaceShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,6 +82,9 @@ class MetaspaceShared : AllStatic { static void prepare_for_dumping() NOT_CDS_RETURN; static void preload_and_dump() NOT_CDS_RETURN; +#ifdef _LP64 + static void adjust_heap_sizes_for_dumping() NOT_CDS_JAVA_HEAP_RETURN; +#endif private: static void preload_and_dump_impl(TRAPS) NOT_CDS_RETURN; @@ -133,7 +136,7 @@ public: } static bool try_link_class(JavaThread* current, InstanceKlass* ik); - static void link_shared_classes(TRAPS) NOT_CDS_RETURN; + static void link_shared_classes(bool jcmd_request, TRAPS) NOT_CDS_RETURN; static bool link_class_for_cds(InstanceKlass* ik, TRAPS) NOT_CDS_RETURN_(false); static bool may_be_eagerly_linked(InstanceKlass* ik) NOT_CDS_RETURN_(false); diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index e29b56a3f277c89b20fd3c24ca2ea114d452ef81..323d67c986f685b69846e9040dfd5b8073d3e824 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1688,7 +1688,7 @@ void ciEnv::dump_replay_data(int compile_id) { if (ret > 0) { int fd = os::open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd != -1) { - FILE* replay_data_file = os::open(fd, "w"); + FILE* replay_data_file = os::fdopen(fd, "w"); if (replay_data_file != NULL) { fileStream replay_data_stream(replay_data_file, /*need_close=*/true); dump_replay_data(&replay_data_stream); @@ -1706,7 +1706,7 @@ void ciEnv::dump_inline_data(int compile_id) { if (ret > 0) { int fd = os::open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd != -1) { - FILE* inline_data_file = os::open(fd, "w"); + FILE* inline_data_file = os::fdopen(fd, "w"); if (inline_data_file != NULL) { fileStream replay_data_stream(inline_data_file, /*need_close=*/true); GUARDED_VM_ENTRY( diff --git a/src/hotspot/share/ci/ciMethod.cpp b/src/hotspot/share/ci/ciMethod.cpp index 862824c5b72f9bc75b0d42c01195c21fbf50780e..b2d9e14208dd57d826e8c30bf1548cfca47b8187 100644 --- a/src/hotspot/share/ci/ciMethod.cpp +++ b/src/hotspot/share/ci/ciMethod.cpp @@ -117,9 +117,11 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) : if (h_m->method_holder()->is_linked()) { _can_be_statically_bound = h_m->can_be_statically_bound(); + _can_omit_stack_trace = h_m->can_omit_stack_trace(); } else { // Have to use a conservative value in this case. _can_be_statically_bound = false; + _can_omit_stack_trace = true; } // Adjust the definition of this condition to be more useful: @@ -176,6 +178,7 @@ ciMethod::ciMethod(ciInstanceKlass* holder, _intrinsic_id( vmIntrinsics::_none), _instructions_size(-1), _can_be_statically_bound(false), + _can_omit_stack_trace(true), _liveness( NULL) #if defined(COMPILER2) , @@ -766,6 +769,20 @@ bool ciMethod::can_be_statically_bound(ciInstanceKlass* context) const { return (holder() == context) && can_be_statically_bound(); } +// ------------------------------------------------------------------ +// ciMethod::can_omit_stack_trace +// +// Tries to determine whether a method can omit stack trace in throw in compiled code. +bool ciMethod::can_omit_stack_trace() const { + if (!StackTraceInThrowable) { + return true; // stack trace is switched off. + } + if (!OmitStackTraceInFastThrow) { + return false; // Have to provide stack trace. + } + return _can_omit_stack_trace; +} + // ------------------------------------------------------------------ // ciMethod::resolve_invoke // diff --git a/src/hotspot/share/ci/ciMethod.hpp b/src/hotspot/share/ci/ciMethod.hpp index 926badd2f381f44c041ac40da8ca6fe591c59e9d..5e0732dfeb72bf2d1f89ede4aa36321e1871082a 100644 --- a/src/hotspot/share/ci/ciMethod.hpp +++ b/src/hotspot/share/ci/ciMethod.hpp @@ -92,6 +92,7 @@ class ciMethod : public ciMetadata { bool _is_c2_compilable; bool _can_be_parsed; bool _can_be_statically_bound; + bool _can_omit_stack_trace; bool _has_reserved_stack_access; bool _is_overpass; @@ -364,6 +365,8 @@ class ciMethod : public ciMetadata { bool can_be_statically_bound(ciInstanceKlass* context) const; + bool can_omit_stack_trace() const; + // Replay data methods static void dump_name_as_ascii(outputStream* st, Method* method); void dump_name_as_ascii(outputStream* st); diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index e630278e649762ef7b96ad46554ef2218227741f..a2a249f157ac4e8cdbdd8a8eed68f62ce7d3c989 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -145,7 +145,7 @@ class CompileReplay : public StackObj { _protection_domain = Handle(); _protection_domain_initialized = false; - _stream = fopen(filename, "rt"); + _stream = os::fopen(filename, "rt"); if (_stream == NULL) { fprintf(stderr, "ERROR: Can't open replay file %s\n", filename); } diff --git a/src/hotspot/share/ci/ciStreams.cpp b/src/hotspot/share/ci/ciStreams.cpp index 4e9895bfaed8ad30b814f48cdd8efe88d10c4424..a1e6c5bffe82494a1bc201dc1048d2d02eb99f31 100644 --- a/src/hotspot/share/ci/ciStreams.cpp +++ b/src/hotspot/share/ci/ciStreams.cpp @@ -476,8 +476,9 @@ ciKlass* ciBytecodeStream::get_declared_method_holder() { constantPoolHandle cpool(THREAD, _method->get_Method()->constants()); bool ignore; // report as MethodHandle for invokedynamic, which is syntactically classless - if (cur_bc() == Bytecodes::_invokedynamic) - return CURRENT_ENV->get_klass_by_name(_holder, ciSymbols::java_lang_invoke_MethodHandle(), false); + if (cur_bc() == Bytecodes::_invokedynamic) { + return CURRENT_ENV->MethodHandle_klass(); + } return CURRENT_ENV->get_klass_by_index(cpool, get_method_holder_index(), ignore, _holder); } diff --git a/src/hotspot/share/ci/ciTypeFlow.cpp b/src/hotspot/share/ci/ciTypeFlow.cpp index 802ba97db2e7b2569cc0068348b276a47078f5d8..fc8553aac4828f4495393e08387785a45368cc89 100644 --- a/src/hotspot/share/ci/ciTypeFlow.cpp +++ b/src/hotspot/share/ci/ciTypeFlow.cpp @@ -2202,10 +2202,10 @@ bool ciTypeFlow::can_trap(ciBytecodeStream& str) { // ciTypeFlow::clone_loop_heads // // Clone the loop heads -bool ciTypeFlow::clone_loop_heads(Loop* lp, StateVector* temp_vector, JsrSet* temp_set) { +bool ciTypeFlow::clone_loop_heads(StateVector* temp_vector, JsrSet* temp_set) { bool rslt = false; for (PreorderLoops iter(loop_tree_root()); !iter.done(); iter.next()) { - lp = iter.current(); + Loop* lp = iter.current(); Block* head = lp->head(); if (lp == loop_tree_root() || lp->is_irreducible() || @@ -2450,6 +2450,102 @@ void ciTypeFlow::PreorderLoops::next() { } } +// If the tail is a branch to the head, retrieve how many times that path was taken from profiling +int ciTypeFlow::profiled_count(ciTypeFlow::Loop* loop) { + ciMethodData* methodData = method()->method_data(); + if (!methodData->is_mature()) { + return 0; + } + ciTypeFlow::Block* tail = loop->tail(); + if (tail->control() == -1) { + return 0; + } + + ciProfileData* data = methodData->bci_to_data(tail->control()); + + if (data == NULL || !data->is_JumpData()) { + return 0; + } + + ciBytecodeStream iter(method()); + iter.reset_to_bci(tail->control()); + + bool is_an_if = false; + bool wide = false; + Bytecodes::Code bc = iter.next(); + switch (bc) { + case Bytecodes::_ifeq: + case Bytecodes::_ifne: + case Bytecodes::_iflt: + case Bytecodes::_ifge: + case Bytecodes::_ifgt: + case Bytecodes::_ifle: + case Bytecodes::_if_icmpeq: + case Bytecodes::_if_icmpne: + case Bytecodes::_if_icmplt: + case Bytecodes::_if_icmpge: + case Bytecodes::_if_icmpgt: + case Bytecodes::_if_icmple: + case Bytecodes::_if_acmpeq: + case Bytecodes::_if_acmpne: + case Bytecodes::_ifnull: + case Bytecodes::_ifnonnull: + is_an_if = true; + break; + case Bytecodes::_goto_w: + case Bytecodes::_jsr_w: + wide = true; + break; + case Bytecodes::_goto: + case Bytecodes::_jsr: + break; + default: + fatal(" invalid bytecode: %s", Bytecodes::name(iter.cur_bc())); + } + + GrowableArray* succs = tail->successors(); + + if (!is_an_if) { + assert(((wide ? iter.get_far_dest() : iter.get_dest()) == loop->head()->start()) == (succs->at(ciTypeFlow::GOTO_TARGET) == loop->head()), "branch should lead to loop head"); + if (succs->at(ciTypeFlow::GOTO_TARGET) == loop->head()) { + return method()->scale_count(data->as_JumpData()->taken()); + } + } else { + assert((iter.get_dest() == loop->head()->start()) == (succs->at(ciTypeFlow::IF_TAKEN) == loop->head()), "bytecode and CFG not consistent"); + assert((tail->limit() == loop->head()->start()) == (succs->at(ciTypeFlow::IF_NOT_TAKEN) == loop->head()), "bytecode and CFG not consistent"); + if (succs->at(ciTypeFlow::IF_TAKEN) == loop->head()) { + return method()->scale_count(data->as_JumpData()->taken()); + } else if (succs->at(ciTypeFlow::IF_NOT_TAKEN) == loop->head()) { + return method()->scale_count(data->as_BranchData()->not_taken()); + } + } + + return 0; +} + +bool ciTypeFlow::Loop::at_insertion_point(Loop* lp, Loop* current) { + int lp_pre_order = lp->head()->pre_order(); + if (current->head()->pre_order() < lp_pre_order) { + return true; + } else if (current->head()->pre_order() > lp_pre_order) { + return false; + } + // In the case of a shared head, make the most frequent head/tail (as reported by profiling) the inner loop + if (current->head() == lp->head()) { + int lp_count = outer()->profiled_count(lp); + int current_count = outer()->profiled_count(current); + if (current_count < lp_count) { + return true; + } else if (current_count > lp_count) { + return false; + } + } + if (current->tail()->pre_order() > lp->tail()->pre_order()) { + return true; + } + return false; +} + // ------------------------------------------------------------------ // ciTypeFlow::Loop::sorted_merge // @@ -2467,12 +2563,10 @@ ciTypeFlow::Loop* ciTypeFlow::Loop::sorted_merge(Loop* lp) { int lp_pre_order = lp->head()->pre_order(); // Find insertion point for "lp" while (current != NULL) { - if (current == lp) + if (current == lp) { return leaf; // Already in list - if (current->head()->pre_order() < lp_pre_order) - break; - if (current->head()->pre_order() == lp_pre_order && - current->tail()->pre_order() > lp->tail()->pre_order()) { + } + if (at_insertion_point(lp, current)) { break; } prev = current; @@ -2732,7 +2826,7 @@ void ciTypeFlow::flow_types() { env()->comp_level() >= CompLevel_full_optimization) { // Loop optimizations are not performed on Tier1 compiles. - bool changed = clone_loop_heads(loop_tree_root(), temp_vector, temp_set); + bool changed = clone_loop_heads(temp_vector, temp_set); // If some loop heads were cloned, recompute postorder and loop tree if (changed) { diff --git a/src/hotspot/share/ci/ciTypeFlow.hpp b/src/hotspot/share/ci/ciTypeFlow.hpp index 907897fe310000835410711617a2355756fdc109..b733a694f380073a8c5549fc9a4bc855bc383984 100644 --- a/src/hotspot/share/ci/ciTypeFlow.hpp +++ b/src/hotspot/share/ci/ciTypeFlow.hpp @@ -717,6 +717,9 @@ public: bool _irreducible; LocalSet _def_locals; + ciTypeFlow* outer() const { return head()->outer(); } + bool at_insertion_point(Loop* lp, Loop* current); + public: Loop(Block* head, Block* tail) : _parent(NULL), _sibling(NULL), _child(NULL), @@ -795,7 +798,7 @@ private: bool can_trap(ciBytecodeStream& str); // Clone the loop heads. Returns true if any cloning occurred. - bool clone_loop_heads(Loop* lp, StateVector* temp_vector, JsrSet* temp_set); + bool clone_loop_heads(StateVector* temp_vector, JsrSet* temp_set); // Clone lp's head and replace tail's successors with clone. Block* clone_loop_head(Loop* lp, StateVector* temp_vector, JsrSet* temp_set); @@ -913,6 +916,8 @@ private: // Create the block map, which indexes blocks in pre_order. void map_blocks(); + int profiled_count(ciTypeFlow::Loop* loop); + public: // Perform type inference flow analysis. void do_flow(); diff --git a/src/hotspot/share/classfile/altHashing.hpp b/src/hotspot/share/classfile/altHashing.hpp index f2fc52410d16332d1b8530d029ea56a074fb4ded..555720c0666d9152e5e31b4707cb6cf35ad53c69 100644 --- a/src/hotspot/share/classfile/altHashing.hpp +++ b/src/hotspot/share/classfile/altHashing.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ #define SHARE_CLASSFILE_ALTHASHING_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" /** * Implementation of alternate more secure hashing. diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index a7ae7bef5c3d5e5dcbf6c3189846e0dc497db0ef..2325241dc64f7213d23b2ea3d0700a54da7a6102 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -139,6 +139,8 @@ #define JAVA_18_VERSION 62 +#define JAVA_19_VERSION 63 + void ClassFileParser::set_class_bad_constant_seen(short bad_constant) { assert((bad_constant == JVM_CONSTANT_Module || bad_constant == JVM_CONSTANT_Package) && _major_version >= JAVA_9_VERSION, @@ -2835,7 +2837,8 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs, annotation_default_length, CHECK_NULL); - if (name == vmSymbols::finalize_method_name() && + if (InstanceKlass::is_finalization_enabled() && + name == vmSymbols::finalize_method_name() && signature == vmSymbols::void_method_signature()) { if (m->is_empty_method()) { _has_empty_finalizer = true; @@ -3050,6 +3053,7 @@ static int inner_classes_jump_to_outer(const Array* inner_classes, int inner static bool inner_classes_check_loop_through_outer(const Array* inner_classes, int idx, const ConstantPool* cp, int length) { int slow = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset); int fast = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset); + while (fast != -1 && fast != 0) { if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) { return true; // found a circularity @@ -3079,14 +3083,15 @@ bool ClassFileParser::check_inner_classes_circularity(const ConstantPool* cp, in for (int y = idx + InstanceKlass::inner_class_next_offset; y < length; y += InstanceKlass::inner_class_next_offset) { - // To maintain compatibility, throw an exception if duplicate inner classes - // entries are found. - guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) || - _inner_classes->at(idx+1) != _inner_classes->at(y+1) || - _inner_classes->at(idx+2) != _inner_classes->at(y+2) || - _inner_classes->at(idx+3) != _inner_classes->at(y+3)), - "Duplicate entry in InnerClasses attribute in class file %s", - CHECK_(true)); + // 4347400: make sure there's no duplicate entry in the classes array + if (_major_version >= JAVA_1_5_VERSION) { + guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) || + _inner_classes->at(idx+1) != _inner_classes->at(y+1) || + _inner_classes->at(idx+2) != _inner_classes->at(y+2) || + _inner_classes->at(idx+3) != _inner_classes->at(y+3)), + "Duplicate entry in InnerClasses attribute in class file %s", + CHECK_(true)); + } // Return true if there are two entries with the same inner_class_info_index. if (_inner_classes->at(y) == _inner_classes->at(idx)) { return true; @@ -3179,10 +3184,9 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea inner_classes->at_put(index++, inner_access_flags.as_short()); } - // 4347400: make sure there's no duplicate entry in the classes array - // Also, check for circular entries. + // Check for circular and duplicate entries. bool has_circularity = false; - if (_need_verify && _major_version >= JAVA_1_5_VERSION) { + if (_need_verify) { has_circularity = check_inner_classes_circularity(cp, length * 4, CHECK_0); if (has_circularity) { // If circularity check failed then ignore InnerClasses attribute. @@ -4171,7 +4175,8 @@ void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) { bool f = false; const Method* const m = ik->lookup_method(vmSymbols::finalize_method_name(), vmSymbols::void_method_signature()); - if (m != NULL && !m->is_empty_method()) { + if (InstanceKlass::is_finalization_enabled() && + (m != NULL) && !m->is_empty_method()) { f = true; } @@ -4525,7 +4530,6 @@ void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) const { const bool is_enum = (flags & JVM_ACC_ENUM) != 0; const bool is_annotation = (flags & JVM_ACC_ANNOTATION) != 0; const bool major_gte_1_5 = _major_version >= JAVA_1_5_VERSION; - const bool major_gte_14 = _major_version >= JAVA_14_VERSION; if ((is_abstract && is_final) || (is_interface && !is_abstract) || @@ -4781,7 +4785,7 @@ bool ClassFileParser::verify_unqualified_name(const char* name, // Take pointer to a UTF8 byte string (not NUL-terminated). // Skip over the longest part of the string that could -// be taken as a fieldname. Allow '/' if slash_ok is true. +// be taken as a fieldname. Allow non-trailing '/'s if slash_ok is true. // Return a pointer to just past the fieldname. // Return NULL if no fieldname at all was found, or in the case of slash_ok // being true, we saw consecutive slashes (meaning we were looking for a @@ -4855,7 +4859,7 @@ static const char* skip_over_field_name(const char* const name, } return (not_first_ch) ? old_p : NULL; } - return (not_first_ch) ? p : NULL; + return (not_first_ch && !last_is_slash) ? p : NULL; } // Take pointer to a UTF8 byte string (not NUL-terminated). diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index d5ac1c308fdc4a50b5303f64665d3a16c4f1852e..bf450cbf407414851acea8b0e074f393e94ce997 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,7 +99,8 @@ static FindEntry_t FindEntry = NULL; static ReadEntry_t ReadEntry = NULL; static GetNextEntry_t GetNextEntry = NULL; static Crc32_t Crc32 = NULL; -int ClassLoader::_libzip_loaded = 0; +int ClassLoader::_libzip_loaded = 0; +void* ClassLoader::_zip_handle = NULL; // Entry points for jimage.dll for loading jimage file entries @@ -253,9 +254,9 @@ ClassFileStream* ClassPathDirEntry::open_stream(JavaThread* current, const char* if (file_handle != -1) { // read contents into resource array u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size); - size_t num_read = os::read(file_handle, (char*) buffer, st.st_size); + size_t num_read = ::read(file_handle, (char*) buffer, st.st_size); // close file - os::close(file_handle); + ::close(file_handle); // construct ClassFileStream if (num_read == (size_t)st.st_size) { if (UsePerfData) { @@ -303,13 +304,19 @@ u1* ClassPathZipEntry::open_entry(JavaThread* current, const char* name, jint* f } // read contents into resource array - int size = (*filesize) + ((nul_terminate) ? 1 : 0); + size_t size = (uint32_t)(*filesize); + if (nul_terminate) { + if (sizeof(size) == sizeof(uint32_t) && size == UINT_MAX) { + return NULL; // 32-bit integer overflow will occur. + } + size++; + } buffer = NEW_RESOURCE_ARRAY(u1, size); if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL; // return result if (nul_terminate) { - buffer[*filesize] = 0; + buffer[size - 1] = 0; } return buffer; } @@ -936,20 +943,19 @@ void ClassLoader::load_zip_library() { assert(ZipOpen == NULL, "should not load zip library twice"); char path[JVM_MAXPATHLEN]; char ebuf[1024]; - void* handle = NULL; if (os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), "zip")) { - handle = os::dll_load(path, ebuf, sizeof ebuf); + _zip_handle = os::dll_load(path, ebuf, sizeof ebuf); } - if (handle == NULL) { + if (_zip_handle == NULL) { vm_exit_during_initialization("Unable to load zip library", path); } - ZipOpen = CAST_TO_FN_PTR(ZipOpen_t, dll_lookup(handle, "ZIP_Open", path)); - ZipClose = CAST_TO_FN_PTR(ZipClose_t, dll_lookup(handle, "ZIP_Close", path)); - FindEntry = CAST_TO_FN_PTR(FindEntry_t, dll_lookup(handle, "ZIP_FindEntry", path)); - ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, dll_lookup(handle, "ZIP_ReadEntry", path)); - GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, dll_lookup(handle, "ZIP_GetNextEntry", path)); - Crc32 = CAST_TO_FN_PTR(Crc32_t, dll_lookup(handle, "ZIP_CRC32", path)); + ZipOpen = CAST_TO_FN_PTR(ZipOpen_t, dll_lookup(_zip_handle, "ZIP_Open", path)); + ZipClose = CAST_TO_FN_PTR(ZipClose_t, dll_lookup(_zip_handle, "ZIP_Close", path)); + FindEntry = CAST_TO_FN_PTR(FindEntry_t, dll_lookup(_zip_handle, "ZIP_FindEntry", path)); + ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, dll_lookup(_zip_handle, "ZIP_ReadEntry", path)); + GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, dll_lookup(_zip_handle, "ZIP_GetNextEntry", path)); + Crc32 = CAST_TO_FN_PTR(Crc32_t, dll_lookup(_zip_handle, "ZIP_CRC32", path)); } void ClassLoader::load_jimage_library() { diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp index c454a503a2ed5d3a6af003d9326ba944cc96eb01..d2f2c6ccef1926e3c88801c9787af0c66fff0510 100644 --- a/src/hotspot/share/classfile/classLoader.hpp +++ b/src/hotspot/share/classfile/classLoader.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -229,6 +229,9 @@ class ClassLoader: AllStatic { bool check_for_duplicates); CDS_ONLY(static void add_to_module_path_entries(const char* path, ClassPathEntry* entry);) + + // cache the zip library handle + static void* _zip_handle; public: CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;}) CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;}) @@ -253,9 +256,10 @@ class ClassLoader: AllStatic { private: static int _libzip_loaded; // used to sync loading zip. static void release_load_zip_library(); - static inline void load_zip_library_if_needed(); public: + static inline void load_zip_library_if_needed(); + static void* zip_library_handle() { return _zip_handle; } static jzfile* open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread); static ClassPathEntry* create_class_path_entry(JavaThread* current, const char *path, const struct stat* st, diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp index 0f1840cc9a6c0f9537f0bb07a41320e99fbf8c20..e3a3ada3e8a9e1d1cc2a57926e0651c892670f75 100644 --- a/src/hotspot/share/classfile/classLoaderData.cpp +++ b/src/hotspot/share/classfile/classLoaderData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,6 +67,7 @@ #include "memory/universe.hpp" #include "oops/access.inline.hpp" #include "oops/klass.inline.hpp" +#include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/oopHandle.inline.hpp" #include "oops/weakHandle.inline.hpp" @@ -358,15 +359,28 @@ void ClassLoaderData::loaded_classes_do(KlassClosure* klass_closure) { // Lock-free access requires load_acquire for (Klass* k = Atomic::load_acquire(&_klasses); k != NULL; k = k->next_link()) { - // Do not filter ArrayKlass oops here... - if (k->is_array_klass() || (k->is_instance_klass() && InstanceKlass::cast(k)->is_loaded())) { + // Filter out InstanceKlasses (or their ObjArrayKlasses) that have not entered the + // loaded state. + if (k->is_instance_klass()) { + if (!InstanceKlass::cast(k)->is_loaded()) { + continue; + } + } else if (k->is_shared() && k->is_objArray_klass()) { + Klass* bottom = ObjArrayKlass::cast(k)->bottom_klass(); + if (bottom->is_instance_klass() && !InstanceKlass::cast(bottom)->is_loaded()) { + // This could happen if is a shared class that has been restored + // but is not yet marked as loaded. All archived array classes of the + // bottom class are already restored and placed in the _klasses list. + continue; + } + } + #ifdef ASSERT - oop m = k->java_mirror(); - assert(m != NULL, "NULL mirror"); - assert(m->is_a(vmClasses::Class_klass()), "invalid mirror"); + oop m = k->java_mirror(); + assert(m != NULL, "NULL mirror"); + assert(m->is_a(vmClasses::Class_klass()), "invalid mirror"); #endif - klass_closure->do_klass(k); - } + klass_closure->do_klass(k); } } @@ -615,8 +629,9 @@ Dictionary* ClassLoaderData::create_dictionary() { return new Dictionary(this, size, resizable); } -// Tell the GC to keep this klass alive while iterating ClassLoaderDataGraph -oop ClassLoaderData::holder_phantom() const { +// Tell the GC to keep this klass alive. Needed while iterating ClassLoaderDataGraph, +// and any runtime code that uses klasses. +oop ClassLoaderData::holder() const { // A klass that was previously considered dead can be looked up in the // CLD/SD, and its _java_mirror or _class_loader can be stored in a root // or a reachable object making it alive again. The SATB part of G1 needs diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp index bb4938750433eed17e860478dfd1f4e199a64393..0d6defae93515c9dd0bda709a59dce638deb0e99 100644 --- a/src/hotspot/share/classfile/classLoaderData.hpp +++ b/src/hotspot/share/classfile/classLoaderData.hpp @@ -174,7 +174,7 @@ class ClassLoaderData : public CHeapObj { bool has_modified_oops() { return _modified_oops; } oop holder_no_keepalive() const; - oop holder_phantom() const; + oop holder() const; private: void unload(); diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.cpp b/src/hotspot/share/classfile/classLoaderDataGraph.cpp index c1e672a0c4343939cc0651f23075db1f842f25ba..4cbee3ec7d8ae6070e98942a6d3f0efee396cd0c 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp @@ -336,7 +336,7 @@ public: } if (cld != NULL) { // Keep cld that is being returned alive. - _holder = Handle(_thread, cld->holder_phantom()); + _holder = Handle(_thread, cld->holder()); _next = cld->next(); } else { _next = NULL; diff --git a/src/hotspot/share/classfile/compactHashtable.cpp b/src/hotspot/share/classfile/compactHashtable.cpp index dc21ee4e7f3913ed4375d59894c69b8483a7570d..4538af56e4b9ebaa6a5cf24bfa492502f650fd88 100644 --- a/src/hotspot/share/classfile/compactHashtable.cpp +++ b/src/hotspot/share/classfile/compactHashtable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -252,7 +252,7 @@ HashtableTextDump::HashtableTextDump(const char* filename) : _fd(-1) { HashtableTextDump::~HashtableTextDump() { os::unmap_memory((char*)_base, _size); if (_fd >= 0) { - close(_fd); + ::close(_fd); } } diff --git a/src/hotspot/share/classfile/klassFactory.hpp b/src/hotspot/share/classfile/klassFactory.hpp index 2b2ee36dfa35bc3df6786dacccd279ed56e4bd82..b1584b3e2caec64e670927f1e524231834da9a97 100644 --- a/src/hotspot/share/classfile/klassFactory.hpp +++ b/src/hotspot/share/classfile/klassFactory.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_CLASSFILE_KLASSFACTORY_HPP #define SHARE_CLASSFILE_KLASSFACTORY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" class ClassFileStream; diff --git a/src/hotspot/share/classfile/modules.hpp b/src/hotspot/share/classfile/modules.hpp index 31cab8209fa28a75e1a7d8fac106e2576abe617c..5c52a323b0cfdfd933df02aa6d20c712d3df88a7 100644 --- a/src/hotspot/share/classfile/modules.hpp +++ b/src/hotspot/share/classfile/modules.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_CLASSFILE_MODULES_HPP #define SHARE_CLASSFILE_MODULES_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" class ModuleEntryTable; diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index c43f940b790a49b61f04df02a0fd930f16315cb6..e3015a02eb5a477e7ab197576c7a2138abc6b3de 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "cds/archiveBuilder.hpp" +#include "cds/filemap.hpp" #include "cds/heapShared.inline.hpp" #include "classfile/altHashing.hpp" #include "classfile/compactHashtable.hpp" @@ -55,6 +56,9 @@ #include "utilities/macros.hpp" #include "utilities/resizeableResourceHash.hpp" #include "utilities/utf8.hpp" +#if INCLUDE_G1GC +#include "gc/g1/g1CollectedHeap.hpp" +#endif // We prefer short chains of avg 2 const double PREF_AVG_LIST_LEN = 2.0; @@ -67,9 +71,18 @@ const double CLEAN_DEAD_HIGH_WATER_MARK = 0.5; #if INCLUDE_CDS_JAVA_HEAP inline oop read_string_from_compact_hashtable(address base_address, u4 offset) { - assert(sizeof(narrowOop) == sizeof(offset), "must be"); - narrowOop v = CompressedOops::narrow_oop_cast(offset); - return HeapShared::decode_from_archive(v); + if (UseCompressedOops) { + assert(sizeof(narrowOop) == sizeof(offset), "must be"); + narrowOop v = CompressedOops::narrow_oop_cast(offset); + return HeapShared::decode_from_archive(v); + } else { + intptr_t dumptime_oop = (uintptr_t)offset; + assert(dumptime_oop != 0, "null strings cannot be interned"); + intptr_t runtime_oop = dumptime_oop + + (intptr_t)FileMapInfo::current_info()->header()->heap_begin() + + (intptr_t)HeapShared::runtime_delta(); + return (oop)cast_to_oop(runtime_oop); + } } typedef CompactHashtable< @@ -746,6 +759,16 @@ oop StringTable::create_archived_string(oop s) { class CopyToArchive : StackObj { CompactHashtableWriter* _writer; +private: + u4 compute_delta(oop s) { + HeapWord* start = G1CollectedHeap::heap()->reserved().start(); + intx offset = ((address)(void*)s) - ((address)(void*)start); + assert(offset >= 0, "must be"); + if (offset > 0xffffffff) { + fatal("too large"); + } + return (u4)offset; + } public: CopyToArchive(CompactHashtableWriter* writer) : _writer(writer) {} bool do_entry(oop s, bool value_ignored) { @@ -757,7 +780,11 @@ public: } // add to the compact table - _writer->add(hash, CompressedOops::narrow_oop_value(new_s)); + if (UseCompressedOops) { + _writer->add(hash, CompressedOops::narrow_oop_value(new_s)); + } else { + _writer->add(hash, compute_delta(new_s)); + } return true; } }; @@ -771,7 +798,6 @@ void StringTable::write_to_archive(const DumpedInternedStrings* dumped_interned_ // Copy the interned strings into the "string space" within the java heap CopyToArchive copier(&writer); dumped_interned_strings->iterate(&copier); - writer.dump(&_shared_table, "string"); } diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 3e4bd3cfb34f455dd3b9b0344392045efbfcd7bd..6272503fe934b2f08a0c3826a864ee8f0a614487 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -31,7 +31,7 @@ #include "cds/filemap.hpp" #include "cds/heapShared.hpp" #include "cds/cdsProtectionDomain.hpp" -#include "cds/dumpTimeClassInfo.hpp" +#include "cds/dumpTimeClassInfo.inline.hpp" #include "cds/metaspaceShared.hpp" #include "cds/runTimeClassInfo.hpp" #include "classfile/classFileStream.hpp" @@ -187,6 +187,11 @@ void SystemDictionaryShared::start_dumping() { _dump_in_progress = true; } +void SystemDictionaryShared::stop_dumping() { + assert_lock_strong(DumpTimeTable_lock); + _dump_in_progress = false; +} + DumpTimeClassInfo* SystemDictionaryShared::find_or_allocate_info_for(InstanceKlass* k) { MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); return find_or_allocate_info_for_locked(k); @@ -1528,6 +1533,7 @@ void SystemDictionaryShared::print_table_statistics(outputStream* st) { } bool SystemDictionaryShared::is_dumptime_table_empty() { + assert_lock_strong(DumpTimeTable_lock); if (_dumptime_table == NULL) { return true; } diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp index bbd76c8d7b75f429f8a72ebfe2d98e90bb71a6c2..a05484b429593149eaa55ec51dfe28f0dc830f91 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.hpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp @@ -300,6 +300,7 @@ public: static void print_table_statistics(outputStream* st) NOT_CDS_RETURN; static bool is_dumptime_table_empty() NOT_CDS_RETURN_(true); static void start_dumping() NOT_CDS_RETURN; + static void stop_dumping() NOT_CDS_RETURN; static bool is_supported_invokedynamic(BootstrapInfo* bsi) NOT_CDS_RETURN_(false); DEBUG_ONLY(static bool no_class_loading_should_happen() {return _no_class_loading_should_happen;}) diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 08cc2bec0e697dcb5c767918dd89ce789ea36cfc..7c3cb1d3f10235bcbb23d3363b930f98953a647d 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -869,15 +869,16 @@ class methodHandle; "Ljdk/internal/vm/vector/VectorSupport$Vector;") \ do_name(vector_ternary_op_name, "ternaryOp") \ \ - do_intrinsic(_VectorBroadcastCoerced, jdk_internal_vm_vector_VectorSupport, vector_broadcast_coerced_name, vector_broadcast_coerced_sig, F_S)\ - do_signature(vector_broadcast_coerced_sig, "(Ljava/lang/Class;" \ + do_intrinsic(_VectorFromBitsCoerced, jdk_internal_vm_vector_VectorSupport, vector_frombits_coerced_name, vector_frombits_coerced_sig, F_S) \ + do_signature(vector_frombits_coerced_sig, "(Ljava/lang/Class;" \ "Ljava/lang/Class;" \ "I" \ "J" \ + "I" \ "Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;" \ - "Ljdk/internal/vm/vector/VectorSupport$BroadcastOperation;)" \ + "Ljdk/internal/vm/vector/VectorSupport$FromBitsCoercedOperation;)" \ "Ljdk/internal/vm/vector/VectorSupport$VectorPayload;") \ - do_name(vector_broadcast_coerced_name, "broadcastCoerced") \ + do_name(vector_frombits_coerced_name, "fromBitsCoerced") \ \ do_intrinsic(_VectorShuffleIota, jdk_internal_vm_vector_VectorSupport, vector_shuffle_step_iota_name, vector_shuffle_step_iota_sig, F_S) \ do_signature(vector_shuffle_step_iota_sig, "(Ljava/lang/Class;" \ diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index d8dfcc418cc2fff97c7829a5fae03df96818b659..65acd172f685ff9ad9dcd33e3f6331a6d74cbee2 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -142,6 +142,7 @@ template(java_util_Iterator, "java/util/Iterator") \ template(java_lang_Record, "java/lang/Record") \ template(sun_instrument_InstrumentationImpl, "sun/instrument/InstrumentationImpl") \ + template(sun_invoke_util_ValueConversions, "sun/invoke/util/ValueConversions") \ \ template(jdk_internal_loader_NativeLibraries, "jdk/internal/loader/NativeLibraries") \ template(jdk_internal_loader_BuiltinClassLoader, "jdk/internal/loader/BuiltinClassLoader") \ diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index 2b89fa89f32b04c3ac0be4069eb60011dee80a35..278792f2bc76619c9e79c9bcba3013dd82194023 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -678,7 +678,7 @@ void CodeCache::nmethods_do(void f(nmethod* nm)) { void CodeCache::metadata_do(MetadataClosure* f) { assert_locked_or_safepoint(CodeCache_lock); - NMethodIterator iter(NMethodIterator::only_alive_and_not_unloading); + NMethodIterator iter(NMethodIterator::only_alive); while(iter.next()) { iter.method()->metadata_do(f); } @@ -1032,7 +1032,7 @@ CompiledMethod* CodeCache::find_compiled(void* start) { } #if INCLUDE_JVMTI -// RedefineClasses support for unloading nmethods that are dependent on "old" methods. +// RedefineClasses support for saving nmethods that are dependent on "old" methods. // We don't really expect this table to grow very large. If it does, it can become a hashtable. static GrowableArray* old_compiled_method_table = NULL; @@ -1085,7 +1085,7 @@ int CodeCache::mark_dependents_for_evol_deoptimization() { reset_old_method_table(); int number_of_marked_CodeBlobs = 0; - CompiledMethodIterator iter(CompiledMethodIterator::only_alive_and_not_unloading); + CompiledMethodIterator iter(CompiledMethodIterator::only_alive); while(iter.next()) { CompiledMethod* nm = iter.method(); // Walk all alive nmethods to check for old Methods. @@ -1105,7 +1105,7 @@ int CodeCache::mark_dependents_for_evol_deoptimization() { void CodeCache::mark_all_nmethods_for_evol_deoptimization() { assert(SafepointSynchronize::is_at_safepoint(), "Can only do this at a safepoint!"); - CompiledMethodIterator iter(CompiledMethodIterator::only_alive_and_not_unloading); + CompiledMethodIterator iter(CompiledMethodIterator::only_alive); while(iter.next()) { CompiledMethod* nm = iter.method(); if (!nm->method()->is_method_handle_intrinsic()) { diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp index 8ca9c59fc8270105691f7772366c612adabf57a5..e150b300b7b6519db253c43994ace80ae8d8d90a 100644 --- a/src/hotspot/share/code/dependencies.cpp +++ b/src/hotspot/share/code/dependencies.cpp @@ -116,6 +116,12 @@ void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm, } } +void Dependencies::assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) { + check_ctxk(ctxk); + check_unique_implementor(ctxk, uniqk); + assert_common_2(unique_implementor, ctxk, uniqk); +} + void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) { check_ctxk(ctxk); assert_common_1(no_finalizable_subclasses, ctxk); @@ -173,6 +179,13 @@ void Dependencies::assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Kla assert_common_2(abstract_with_unique_concrete_subtype, ctxk_dv, conck_dv); } +void Dependencies::assert_unique_implementor(InstanceKlass* ctxk, InstanceKlass* uniqk) { + check_ctxk(ctxk); + assert(ctxk->is_interface(), "not an interface"); + assert(ctxk->implementor() == uniqk, "not a unique implementor"); + assert_common_2(unique_implementor, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqk)); +} + void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) { check_ctxk(ctxk); check_unique_method(ctxk, uniqm); @@ -580,6 +593,7 @@ const char* Dependencies::_dep_name[TYPE_LIMIT] = { "abstract_with_unique_concrete_subtype", "unique_concrete_method_2", "unique_concrete_method_4", + "unique_implementor", "no_finalizable_subclasses", "call_site_target_value" }; @@ -591,6 +605,7 @@ int Dependencies::_dep_args[TYPE_LIMIT] = { 2, // abstract_with_unique_concrete_subtype ctxk, k 2, // unique_concrete_method_2 ctxk, m 4, // unique_concrete_method_4 ctxk, m, resolved_klass, resolved_method + 2, // unique_implementor ctxk, implementor 1, // no_finalizable_subclasses ctxk 2 // call_site_target_value call_site, method_handle }; @@ -1813,6 +1828,16 @@ Klass* Dependencies::check_unique_concrete_method(InstanceKlass* ctxk, return NULL; } +Klass* Dependencies::check_unique_implementor(InstanceKlass* ctxk, Klass* uniqk, NewKlassDepChange* changes) { + assert(ctxk->is_interface(), "sanity"); + assert(ctxk->nof_implementors() > 0, "no implementors"); + if (ctxk->nof_implementors() == 1) { + assert(ctxk->implementor() == uniqk, "sanity"); + return NULL; + } + return ctxk; // no unique implementor +} + // Search for AME. // There are two version of checks. // 1) Spot checking version(Classload time). Newly added class is checked for AME. @@ -2062,6 +2087,9 @@ Klass* Dependencies::DepStream::check_new_klass_dependency(NewKlassDepChange* ch case unique_concrete_method_4: witness = check_unique_concrete_method(context_type(), method_argument(1), type_argument(2), method_argument(3), changes); break; + case unique_implementor: + witness = check_unique_implementor(context_type(), type_argument(1), changes); + break; case no_finalizable_subclasses: witness = check_has_no_finalizable_subclasses(context_type(), changes); break; diff --git a/src/hotspot/share/code/dependencies.hpp b/src/hotspot/share/code/dependencies.hpp index 104fc9ee6496bb290485ce6b3c633fdf8f8d2fa5..0d8fa9fa48c71a5743e6543b295836df1305a76d 100644 --- a/src/hotspot/share/code/dependencies.hpp +++ b/src/hotspot/share/code/dependencies.hpp @@ -143,6 +143,9 @@ class Dependencies: public ResourceObj { // of the analysis. unique_concrete_method_4, // one unique concrete method under CX + // This dependency asserts that interface CX has a unique implementor class. + unique_implementor, // one unique implementor under CX + // This dependency asserts that no instances of class or it's // subclasses require finalization registration. no_finalizable_subclasses, @@ -329,7 +332,10 @@ class Dependencies: public ResourceObj { assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract"); } static void check_unique_method(ciKlass* ctxk, ciMethod* m) { - assert(!m->can_be_statically_bound(ctxk->as_instance_klass()), "redundant"); + assert(!m->can_be_statically_bound(ctxk->as_instance_klass()) || ctxk->is_interface(), "redundant"); + } + static void check_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) { + assert(ctxk->implementor() == uniqk, "not a unique implementor"); } void assert_common_1(DepType dept, ciBaseObject* x); @@ -343,9 +349,9 @@ class Dependencies: public ResourceObj { void assert_abstract_with_unique_concrete_subtype(ciKlass* ctxk, ciKlass* conck); void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm); void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm, ciKlass* resolved_klass, ciMethod* resolved_method); + void assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk); void assert_has_no_finalizable_subclasses(ciKlass* ctxk); void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle); - #if INCLUDE_JVMCI private: static void check_ctxk(Klass* ctxk) { @@ -366,6 +372,7 @@ class Dependencies: public ResourceObj { void assert_evol_method(Method* m); void assert_has_no_finalizable_subclasses(Klass* ctxk); void assert_leaf_type(Klass* ctxk); + void assert_unique_implementor(InstanceKlass* ctxk, InstanceKlass* uniqk); void assert_unique_concrete_method(Klass* ctxk, Method* uniqm); void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck); void assert_call_site_target_value(oop callSite, oop methodHandle); @@ -413,6 +420,7 @@ class Dependencies: public ResourceObj { static Klass* check_evol_method(Method* m); static Klass* check_leaf_type(InstanceKlass* ctxk); static Klass* check_abstract_with_unique_concrete_subtype(InstanceKlass* ctxk, Klass* conck, NewKlassDepChange* changes = NULL); + static Klass* check_unique_implementor(InstanceKlass* ctxk, Klass* uniqk, NewKlassDepChange* changes = NULL); static Klass* check_unique_concrete_method(InstanceKlass* ctxk, Method* uniqm, NewKlassDepChange* changes = NULL); static Klass* check_unique_concrete_method(InstanceKlass* ctxk, Method* uniqm, Klass* resolved_klass, Method* resolved_method, KlassDepChange* changes = NULL); static Klass* check_has_no_finalizable_subclasses(InstanceKlass* ctxk, NewKlassDepChange* changes = NULL); diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index d0154bc85a37ad1e0f3221df79147238681d22d1..d31e62f404a63e5f795972fed6fb747448f7c0ab 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -256,7 +256,7 @@ class nmethod : public CompiledMethod { // stack. An not_entrant method can be removed when there are no // more activations, i.e., when the _stack_traversal_mark is less than // current sweep traversal index. - volatile long _stack_traversal_mark; + volatile int64_t _stack_traversal_mark; // The _hotness_counter indicates the hotness of a method. The higher // the value the hotter the method. The hotness counter of a nmethod is @@ -538,8 +538,8 @@ public: void fix_oop_relocations() { fix_oop_relocations(NULL, NULL, false); } // Sweeper support - long stack_traversal_mark() { return _stack_traversal_mark; } - void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; } + int64_t stack_traversal_mark() { return _stack_traversal_mark; } + void set_stack_traversal_mark(int64_t l) { _stack_traversal_mark = l; } // On-stack replacement support int osr_entry_bci() const { assert(is_osr_method(), "wrong kind of nmethod"); return _entry_bci; } diff --git a/src/hotspot/share/code/vtableStubs.hpp b/src/hotspot/share/code/vtableStubs.hpp index 8fc2bdae94c2042149299637581baaaceaa29d6d..9498ad7d329e6ec3442a6eb9db42f38d373d232a 100644 --- a/src/hotspot/share/code/vtableStubs.hpp +++ b/src/hotspot/share/code/vtableStubs.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "asm/macroAssembler.hpp" #include "code/vmreg.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // A VtableStub holds an individual code stub for a pair (vtable index, #args) for either itables or vtables // There's a one-to-one relationship between a VtableStub and such a pair. diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index eab2751c3b03e910682f369d0bb431c0d8fb456e..4ae7bc21ce63038d58b90c67af44646f2b927060 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -186,7 +186,7 @@ int CompileBroker::_sum_standard_bytes_compiled = 0; int CompileBroker::_sum_nmethod_size = 0; int CompileBroker::_sum_nmethod_code_size = 0; -long CompileBroker::_peak_compilation_time = 0; +jlong CompileBroker::_peak_compilation_time = 0; CompilerStatistics CompileBroker::_stats_per_level[CompLevel_full_optimization]; @@ -1970,6 +1970,8 @@ void CompileBroker::compiler_thread_loop() { method->clear_queued_for_compilation(); task->set_failure_reason("compilation is disabled"); } + } else { + task->set_failure_reason("breakpoints are present"); } if (UseDynamicNumberOfCompilerThreads) { @@ -2003,7 +2005,7 @@ void CompileBroker::init_compiler_thread_log() { os::file_separator(), thread_id, os::current_process_id()); } - fp = fopen(file_name, "wt"); + fp = os::fopen(file_name, "wt"); if (fp != NULL) { if (LogCompilation && Verbose) { tty->print_cr("Opening compilation log %s", file_name); diff --git a/src/hotspot/share/compiler/compileBroker.hpp b/src/hotspot/share/compiler/compileBroker.hpp index 33fde0dace6cdd7480dd9f5143ebbeb3f13fac4c..be770aac9c242afafccc65afa6c6d12bf9104dad 100644 --- a/src/hotspot/share/compiler/compileBroker.hpp +++ b/src/hotspot/share/compiler/compileBroker.hpp @@ -222,7 +222,7 @@ class CompileBroker: AllStatic { static int _sum_standard_bytes_compiled; static int _sum_nmethod_size; static int _sum_nmethod_code_size; - static long _peak_compilation_time; + static jlong _peak_compilation_time; static CompilerStatistics _stats_per_level[]; @@ -411,8 +411,8 @@ public: static int get_sum_standard_bytes_compiled() { return _sum_standard_bytes_compiled; } static int get_sum_nmethod_size() { return _sum_nmethod_size;} static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; } - static long get_peak_compilation_time() { return _peak_compilation_time; } - static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); } + static jlong get_peak_compilation_time() { return _peak_compilation_time; } + static jlong get_total_compilation_time() { return _t_total_compilation.milliseconds(); } // Log that compilation profiling is skipped because metaspace is full. static void log_metaspace_failure(); diff --git a/src/hotspot/share/compiler/compileLog.cpp b/src/hotspot/share/compiler/compileLog.cpp index eb52c5f5fb1acd1decd55f1c27768575e4c06295..3dbc71f6075d6ac29a6d8495d050311efef554b0 100644 --- a/src/hotspot/share/compiler/compileLog.cpp +++ b/src/hotspot/share/compiler/compileLog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -225,7 +225,7 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen) if (to_read < (julong)buflen) nr = (size_t)to_read; else nr = buflen; - bytes_read = read(partial_fd, buf, (int)nr); + bytes_read = ::read(partial_fd, buf, (int)nr); if (bytes_read <= 0) break; nr = bytes_read; to_read -= (julong)nr; @@ -235,7 +235,7 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen) // Copy any remaining data inside a quote: bool saw_slop = false; int end_cdata = 0; // state machine [0..2] watching for too many "]]" - while ((bytes_read = read(partial_fd, buf, buflen-1)) > 0) { + while ((bytes_read = ::read(partial_fd, buf, buflen-1)) > 0) { nr = bytes_read; buf[buflen-1] = '\0'; if (!saw_slop) { @@ -285,7 +285,7 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen) file->print_raw_cr(""); } file->print_raw_cr(""); - close(partial_fd); + ::close(partial_fd); } CompileLog* next_log = log->_next; delete log; // Removes partial file diff --git a/src/hotspot/share/compiler/compilerDefinitions.hpp b/src/hotspot/share/compiler/compilerDefinitions.hpp index 1c8096918a6a49a9233c55f62800583f56231d91..153dfaad3645cdeea4b5674312f20fb6b8d55dfa 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.hpp +++ b/src/hotspot/share/compiler/compilerDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "compiler/compiler_globals.hpp" #include "jvmci/jvmci_globals.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/globals.hpp" // The (closed set) of concrete compiler classes. diff --git a/src/hotspot/share/compiler/compilerDirectives.cpp b/src/hotspot/share/compiler/compilerDirectives.cpp index 0e38b067246aef7641fb59e14a8e078d21ba63a6..6d864072d1b6dfcd41a5954fc6b0e1f670b950dc 100644 --- a/src/hotspot/share/compiler/compilerDirectives.cpp +++ b/src/hotspot/share/compiler/compilerDirectives.cpp @@ -334,9 +334,21 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle if (!CompilerDirectivesIgnoreCompileCommandsOption && CompilerOracle::has_any_command_set()) { DirectiveSetPtr set(this); +#ifdef COMPILER1 + if (C1Breakpoint) { + // If the directives didn't have 'BreakAtExecute', + // the command 'C1Breakpoint' would become effective. + if (!_modified[BreakAtExecuteIndex]) { + set.cloned()->BreakAtExecuteOption = true; + } + } +#endif + // All CompileCommands are not equal so this gets a bit verbose // When CompileCommands have been refactored less clutter will remain. if (CompilerOracle::should_break_at(method)) { + // If the directives didn't have 'BreakAtCompile' or 'BreakAtExecute', + // the sub-command 'Break' of the 'CompileCommand' would become effective. if (!_modified[BreakAtCompileIndex]) { set.cloned()->BreakAtCompileOption = true; } diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp index d51aa28e28cc6026578aada9d7ec23b3b44f6fb8..7daa034a8d0262b97f9c4952b407329a387bf970 100644 --- a/src/hotspot/share/compiler/compilerDirectives.hpp +++ b/src/hotspot/share/compiler/compilerDirectives.hpp @@ -67,6 +67,7 @@ NOT_PRODUCT(cflags(TraceOptoPipelining, bool, TraceOptoPipelining, TraceOptoPipelining)) \ NOT_PRODUCT(cflags(TraceOptoOutput, bool, TraceOptoOutput, TraceOptoOutput)) \ NOT_PRODUCT(cflags(PrintIdeal, bool, PrintIdeal, PrintIdeal)) \ +NOT_PRODUCT(cflags(PrintIdealLevel, uintx, PrintIdealLevel, PrintIdealLevel)) \ cflags(TraceSpilling, bool, TraceSpilling, TraceSpilling) \ cflags(Vectorize, bool, false, Vectorize) \ cflags(CloneMapDebug, bool, false, CloneMapDebug) \ diff --git a/src/hotspot/share/compiler/compilerEvent.hpp b/src/hotspot/share/compiler/compilerEvent.hpp index 65fc296b66b3dab9e5f1dacfa1aed1c8ff2f54de..cf04ce9a4364b8f3fb2904ffe0a867f024197644 100644 --- a/src/hotspot/share/compiler/compilerEvent.hpp +++ b/src/hotspot/share/compiler/compilerEvent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "jni.h" #include "compiler/compilerDefinitions.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" #include "utilities/ticks.hpp" diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp index 8464d22ef42d11a111d136941bc01e5492434334..7d58a28d27235bc63df84f73dc92a5a3aae3ef14 100644 --- a/src/hotspot/share/compiler/compilerOracle.cpp +++ b/src/hotspot/share/compiler/compilerOracle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -932,7 +932,7 @@ bool CompilerOracle::_quiet = false; void CompilerOracle::parse_from_file() { assert(has_command_file(), "command file must be specified"); - FILE* stream = fopen(cc_file(), "rt"); + FILE* stream = os::fopen(cc_file(), "rt"); if (stream == NULL) return; char token[1024]; diff --git a/src/hotspot/share/compiler/compilerOracle.hpp b/src/hotspot/share/compiler/compilerOracle.hpp index 858e5c794060ffbe96c84bc02339ee757881f491..f2fc0e8251dfd61cbb463907b57b24a234a1169c 100644 --- a/src/hotspot/share/compiler/compilerOracle.hpp +++ b/src/hotspot/share/compiler/compilerOracle.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_COMPILER_COMPILERORACLE_HPP #define SHARE_COMPILER_COMPILERORACLE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" class methodHandle; @@ -79,7 +79,8 @@ class methodHandle; option(TraceOptoPipelining, "TraceOptoPipelining", Bool) \ option(TraceOptoOutput, "TraceOptoOutput", Bool) \ option(TraceSpilling, "TraceSpilling", Bool) \ - option(PrintIdeal, "PrintIdeal", Bool) \ + option(PrintIdeal, "PrintIdeal", Bool) \ + option(PrintIdealLevel, "PrintIdealLevel", Uintx) \ option(IGVPrintLevel, "IGVPrintLevel", Intx) \ option(Vectorize, "Vectorize", Bool) \ option(VectorizeDebug, "VectorizeDebug", Uintx) \ diff --git a/src/hotspot/share/compiler/directivesParser.cpp b/src/hotspot/share/compiler/directivesParser.cpp index e88dda3768b810914b417ed4e8d0c3bb4634ef91..b4ce9a3877c88db97224f305437846a8746d9f9c 100644 --- a/src/hotspot/share/compiler/directivesParser.cpp +++ b/src/hotspot/share/compiler/directivesParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,11 +94,11 @@ bool DirectivesParser::parse_from_file_inner(const char* filename, outputStream* if (file_handle != -1) { // read contents into resource array char* buffer = NEW_RESOURCE_ARRAY(char, st.st_size+1); - ssize_t num_read = os::read(file_handle, (char*) buffer, st.st_size); + ssize_t num_read = ::read(file_handle, (char*) buffer, st.st_size); if (num_read >= 0) { buffer[num_read] = '\0'; // close file - os::close(file_handle); + ::close(file_handle); return parse_string(buffer, stream) > 0; } } diff --git a/src/hotspot/share/compiler/disassembler.cpp b/src/hotspot/share/compiler/disassembler.cpp index 54cea9cc2811d56e1e1011c6768513b710764528..1beb75441cd429e14d1914fb35eba85bc6240dcc 100644 --- a/src/hotspot/share/compiler/disassembler.cpp +++ b/src/hotspot/share/compiler/disassembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -267,7 +267,7 @@ void decode_env::print_hook_comments(address pc, bool newline) { _cached_src_lines = new (ResourceObj::C_HEAP, mtCode)GrowableArray(0, mtCode); } - if ((fp = fopen(file, "r")) == NULL) { + if ((fp = os::fopen(file, "r")) == NULL) { _cached_src = NULL; return; } diff --git a/src/hotspot/share/compiler/methodLiveness.cpp b/src/hotspot/share/compiler/methodLiveness.cpp index 5f83eea6716e65406e2239906f7f724b2fd004f4..6bcabfe4ace5a1ca6aa6aa334acd7ed1e5d32057 100644 --- a/src/hotspot/share/compiler/methodLiveness.cpp +++ b/src/hotspot/share/compiler/methodLiveness.cpp @@ -97,8 +97,6 @@ void MethodLiveness::compute_liveness() { void MethodLiveness::init_basic_blocks() { - bool bailout = false; - int method_len = method()->code_size(); ciMethodBlocks *mblocks = method()->get_method_blocks(); @@ -255,10 +253,6 @@ void MethodLiveness::init_basic_blocks() { // We will patch up jsr/rets in a subsequent pass. ret_list->append(current_block); break; - case Bytecodes::_breakpoint: - // Bail out of there are breakpoints in here. - bailout = true; - break; default: // Do nothing. break; diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp index 0f929b64bd9f9faa47d1dbbb897bd00e36ec1074..036593c72aef61cc37e9d1f59f7702b5f578292e 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp @@ -132,7 +132,7 @@ public: bool is_in_reserved(const void* addr) const { return _reserved.contains(addr); } // Support for loading objects from CDS archive into the heap - virtual bool can_load_archived_objects() const { return true; } + virtual bool can_load_archived_objects() const { return UseCompressedOops; } virtual HeapWord* allocate_loaded_archive_space(size_t size); virtual void print_on(outputStream* st) const; diff --git a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp index d7d67c1862e1b72208ad6056f05acdd3fe4a6e61..f599b111908ce92f742d9d792c9930be10c4600a 100644 --- a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp +++ b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp @@ -442,7 +442,7 @@ void G1BarrierSetC2::post_barrier(GraphKit* kit, Node* cast = __ CastPX(__ ctrl(), adr); // Divide pointer by card size - Node* card_offset = __ URShiftX( cast, __ ConI(CardTable::card_shift) ); + Node* card_offset = __ URShiftX( cast, __ ConI(CardTable::card_shift()) ); // Combine card table base and card offset Node* card_adr = __ AddP(no_base, byte_map_base_node(kit), card_offset ); diff --git a/src/hotspot/share/gc/g1/g1AllocRegion.cpp b/src/hotspot/share/gc/g1/g1AllocRegion.cpp index 239822d6d1d9fbedef918942a172bacf47326879..915110e3ebb1f5c22bd837384972d7c541896d86 100644 --- a/src/hotspot/share/gc/g1/g1AllocRegion.cpp +++ b/src/hotspot/share/gc/g1/g1AllocRegion.cpp @@ -371,7 +371,7 @@ HeapRegion* OldGCAllocRegion::release() { // Determine how far we are from the next card boundary. If it is smaller than // the minimum object size we can allocate into, expand into the next card. HeapWord* top = cur->top(); - HeapWord* aligned_top = align_up(top, BOTConstants::N_bytes); + HeapWord* aligned_top = align_up(top, BOTConstants::card_size()); size_t to_allocate_words = pointer_delta(aligned_top, top, HeapWordSize); diff --git a/src/hotspot/share/gc/g1/g1Allocator.cpp b/src/hotspot/share/gc/g1/g1Allocator.cpp index 7a6cb0a499dcb0807981d4ec7a3c43b070a92336..f83ae9b52d30d919745911eae7cebef620597539 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.cpp +++ b/src/hotspot/share/gc/g1/g1Allocator.cpp @@ -301,10 +301,7 @@ G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) : _alloc_buffers[state] = NEW_C_HEAP_ARRAY(PLAB*, length, mtGC); size_t word_sz = _g1h->desired_plab_sz(state); for (uint node_index = 0; node_index < length; node_index++) { - // Specialized PLABs for old that handle BOT updates for object allocations. - _alloc_buffers[state][node_index] = (state == G1HeapRegionAttr::Old) - ? new G1BotUpdatingPLAB(word_sz) - : new PLAB(word_sz); + _alloc_buffers[state][node_index] = new PLAB(word_sz); } } } @@ -364,7 +361,6 @@ HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(G1HeapRegionAttr dest, // Try direct allocation. HeapWord* result = _allocator->par_allocate_during_gc(dest, word_sz, node_index); if (result != NULL) { - update_bot_for_direct_allocation(dest, result, word_sz); _direct_allocated[dest.type()] += word_sz; } return result; diff --git a/src/hotspot/share/gc/g1/g1Allocator.hpp b/src/hotspot/share/gc/g1/g1Allocator.hpp index 8eea1e0f12b43ef2ba3c6ad82d70086134cefcc0..5014442845ab91469cf966e1a450b296660d3200 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.hpp +++ b/src/hotspot/share/gc/g1/g1Allocator.hpp @@ -145,22 +145,6 @@ public: uint node_index); }; -// Specialized PLAB for old generation promotions. For old regions the -// BOT needs to be updated and the relevant data to do this efficiently -// is stored in the PLAB. -class G1BotUpdatingPLAB : public PLAB { - // An object spanning this threshold will cause a BOT update. - HeapWord* _next_bot_threshold; - // The region in which the PLAB resides. - HeapRegion* _region; -public: - G1BotUpdatingPLAB(size_t word_sz) : PLAB(word_sz) { } - // Sets the new PLAB buffer as well as updates the threshold and region. - void set_buf(HeapWord* buf, size_t word_sz) override; - // Updates the BOT if the last allocation crossed the threshold. - inline void update_bot(size_t word_sz); -}; - // Manages the PLABs used during garbage collection. Interface for allocation from PLABs. // Needs to handle multiple contexts, extra alignment in any "survivor" area and some // statistics. @@ -181,18 +165,11 @@ private: inline PLAB* alloc_buffer(G1HeapRegionAttr dest, uint node_index) const; inline PLAB* alloc_buffer(region_type_t dest, uint node_index) const; - // Helpers to do explicit BOT updates for allocations in old generation regions. - void update_bot_for_direct_allocation(G1HeapRegionAttr attr, HeapWord* addr, size_t size); - // Returns the number of allocation buffers for the given dest. // There is only 1 buffer for Old while Young may have multiple buffers depending on // active NUMA nodes. inline uint alloc_buffers_length(region_type_t dest) const; - // Returns if BOT updates are needed for the given destinaion. Currently we only have - // two destinations and BOT updates are only needed for the old generation. - inline bool needs_bot_update(G1HeapRegionAttr dest) const; - bool may_throw_away_buffer(size_t const allocation_word_sz, size_t const buffer_size) const; public: G1PLABAllocator(G1Allocator* allocator); @@ -221,9 +198,6 @@ public: bool* refill_failed, uint node_index); - // Update the BOT for the last PLAB allocation. - inline void update_bot_for_plab_allocation(G1HeapRegionAttr dest, size_t word_sz, uint node_index); - void undo_allocation(G1HeapRegionAttr dest, HeapWord* obj, size_t word_sz, uint node_index); }; diff --git a/src/hotspot/share/gc/g1/g1Allocator.inline.hpp b/src/hotspot/share/gc/g1/g1Allocator.inline.hpp index 82223a75ad454522d090186f03f1d1ffbfae8302..42d6a547257511d2d6a9eb4c669f254f5c84a52b 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.inline.hpp +++ b/src/hotspot/share/gc/g1/g1Allocator.inline.hpp @@ -133,49 +133,4 @@ inline HeapWord* G1PLABAllocator::allocate(G1HeapRegionAttr dest, return allocate_direct_or_new_plab(dest, word_sz, refill_failed, node_index); } -inline bool G1PLABAllocator::needs_bot_update(G1HeapRegionAttr dest) const { - return dest.is_old(); -} - -inline void G1PLABAllocator::update_bot_for_direct_allocation(G1HeapRegionAttr attr, HeapWord* addr, size_t size) { - if (!needs_bot_update(attr)) { - return; - } - - // Out of PLAB allocations in an old generation region. Update BOT. - HeapRegion* region = _g1h->heap_region_containing(addr); - region->update_bot_at(addr, size); -} - -inline void G1PLABAllocator::update_bot_for_plab_allocation(G1HeapRegionAttr dest, size_t word_sz, uint node_index) { - assert(needs_bot_update(dest), "Wrong destination: %s", dest.get_type_str()); - G1BotUpdatingPLAB* plab = static_cast(alloc_buffer(dest, node_index)); - plab->update_bot(word_sz); -} - -inline void G1BotUpdatingPLAB::set_buf(HeapWord* buf, size_t word_sz) { - PLAB::set_buf(buf, word_sz); - // Update the region and threshold to allow efficient BOT updates. - _region = G1CollectedHeap::heap()->heap_region_containing(buf); - _next_bot_threshold = _region->bot_threshold_for_addr(buf); -} - -inline void G1BotUpdatingPLAB::update_bot(size_t word_sz) { - // The last object end is at _top, if it did not cross the - // threshold, there is nothing to do. - if (_top <= _next_bot_threshold) { - return; - } - - HeapWord* obj_start = _top - word_sz; - assert(contains(obj_start), - "Object start outside PLAB. bottom: " PTR_FORMAT " object: " PTR_FORMAT, - p2i(_bottom), p2i(obj_start)); - assert(obj_start <= _next_bot_threshold, - "Object start not below or at threshold. threshold: " PTR_FORMAT " object: " PTR_FORMAT, - p2i(_next_bot_threshold), p2i(obj_start)); - - _region->update_bot_crossing_threshold(&_next_bot_threshold, obj_start, _top); -} - #endif // SHARE_GC_G1_G1ALLOCATOR_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/g1Arguments.cpp b/src/hotspot/share/gc/g1/g1Arguments.cpp index 400f6b500240d6b0a7f2c0dff5d04e7a248ef32f..348402cf95785697437d9bd064befb965fd466fe 100644 --- a/src/hotspot/share/gc/g1/g1Arguments.cpp +++ b/src/hotspot/share/gc/g1/g1Arguments.cpp @@ -135,7 +135,7 @@ void G1Arguments::initialize_card_set_configuration() { uint region_size_log_mb = (uint)MAX2(HeapRegion::LogOfHRGrainBytes - LOG_M, 0); if (FLAG_IS_DEFAULT(G1RemSetArrayOfCardsEntries)) { - uint max_cards_in_inline_ptr = G1CardSetConfiguration::max_cards_in_inline_ptr(HeapRegion::LogOfHRGrainBytes - CardTable::card_shift); + uint max_cards_in_inline_ptr = G1CardSetConfiguration::max_cards_in_inline_ptr(HeapRegion::LogOfHRGrainBytes - CardTable::card_shift()); FLAG_SET_ERGO(G1RemSetArrayOfCardsEntries, MAX2(max_cards_in_inline_ptr * 2, G1RemSetArrayOfCardsEntriesBase * (1u << (region_size_log_mb + 1)))); } diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp index c98aa2c79a2d3606c3bc8cf1f888de2c08946946..7bbfe60e8a8015df2e95696ac601cf8a1d6ce4a9 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp @@ -52,14 +52,14 @@ G1BlockOffsetTable::G1BlockOffsetTable(MemRegion heap, G1RegionToSpaceMapper* st bool G1BlockOffsetTable::is_card_boundary(HeapWord* p) const { assert(p >= _reserved.start(), "just checking"); size_t delta = pointer_delta(p, _reserved.start()); - return (delta & right_n_bits((int)BOTConstants::LogN_words)) == (size_t)NoBits; + return (delta & right_n_bits((int)BOTConstants::log_card_size_in_words())) == (size_t)NoBits; } #ifdef ASSERT void G1BlockOffsetTable::check_index(size_t index, const char* msg) const { - assert((index) < (_reserved.word_size() >> BOTConstants::LogN_words), + assert((index) < (_reserved.word_size() >> BOTConstants::log_card_size_in_words()), "%s - index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT, - msg, (index), (_reserved.word_size() >> BOTConstants::LogN_words)); + msg, (index), (_reserved.word_size() >> BOTConstants::log_card_size_in_words())); assert(G1CollectedHeap::heap()->is_in(address_for_index_raw(index)), "Index " SIZE_FORMAT " corresponding to " PTR_FORMAT " (%u) is not in committed area.", @@ -74,8 +74,6 @@ void G1BlockOffsetTable::check_index(size_t index, const char* msg) const { ////////////////////////////////////////////////////////////////////// G1BlockOffsetTablePart::G1BlockOffsetTablePart(G1BlockOffsetTable* array, HeapRegion* hr) : - _next_offset_threshold(NULL), - DEBUG_ONLY(_object_can_span(false) COMMA) _bot(array), _hr(hr) { @@ -96,7 +94,7 @@ void G1BlockOffsetTablePart::update() { // The arguments follow the normal convention of denoting // a right-open interval: [start, end) -void G1BlockOffsetTablePart:: set_remainder_to_point_to_start(HeapWord* start, HeapWord* end) { +void G1BlockOffsetTablePart::set_remainder_to_point_to_start(HeapWord* start, HeapWord* end) { assert(start < end, "precondition"); // Write the backskip value for each region. // @@ -134,7 +132,7 @@ void G1BlockOffsetTablePart:: set_remainder_to_point_to_start(HeapWord* start, H size_t start_card = _bot->index_for(start); size_t end_card = _bot->index_for(end-1); assert(start ==_bot->address_for_index(start_card), "Precondition"); - assert(end ==_bot->address_for_index(end_card)+BOTConstants::N_words, "Precondition"); + assert(end ==_bot->address_for_index(end_card)+BOTConstants::card_size_in_words(), "Precondition"); set_remainder_to_point_to_start_incl(start_card, end_card); // closed interval } @@ -144,7 +142,7 @@ void G1BlockOffsetTablePart:: set_remainder_to_point_to_start(HeapWord* start, H void G1BlockOffsetTablePart::set_remainder_to_point_to_start_incl(size_t start_card, size_t end_card) { assert(start_card <= end_card, "precondition"); assert(start_card > _bot->index_for(_hr->bottom()), "Cannot be first card"); - assert(_bot->offset_array(start_card-1) <= BOTConstants::N_words, + assert(_bot->offset_array(start_card-1) < BOTConstants::card_size_in_words(), "Offset card has an unexpected value"); size_t start_card_for_region = start_card; u_char offset = max_jubyte; @@ -153,7 +151,7 @@ void G1BlockOffsetTablePart::set_remainder_to_point_to_start_incl(size_t start_c // so that the reach ends in this region and not at the start // of the next. size_t reach = start_card - 1 + (BOTConstants::power_to_cards_back(i+1) - 1); - offset = BOTConstants::N_words + i; + offset = BOTConstants::card_size_in_words() + i; if (reach >= end_card) { _bot->set_offset_array(start_card_for_region, end_card, offset); start_card_for_region = reach + 1; @@ -174,16 +172,16 @@ void G1BlockOffsetTablePart::check_all_cards(size_t start_card, size_t end_card) if (end_card < start_card) { return; } - guarantee(_bot->offset_array(start_card) == BOTConstants::N_words, "Wrong value in second card"); + guarantee(_bot->offset_array(start_card) == BOTConstants::card_size_in_words(), "Wrong value in second card"); for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) { u_char entry = _bot->offset_array(c); if (c - start_card > BOTConstants::power_to_cards_back(1)) { - guarantee(entry > BOTConstants::N_words, + guarantee(entry > BOTConstants::card_size_in_words(), "Should be in logarithmic region - " "entry: %u, " "_array->offset_array(c): %u, " "N_words: %u", - (uint)entry, (uint)_bot->offset_array(c), BOTConstants::N_words); + (uint)entry, (uint)_bot->offset_array(c), BOTConstants::card_size_in_words()); } size_t backskip = BOTConstants::entry_to_cards_back(entry); size_t landing_card = c - backskip; @@ -196,94 +194,86 @@ void G1BlockOffsetTablePart::check_all_cards(size_t start_card, size_t end_card) } else { guarantee(landing_card == start_card - 1, "Tautology"); // Note that N_words is the maximum offset value - guarantee(_bot->offset_array(landing_card) <= BOTConstants::N_words, + guarantee(_bot->offset_array(landing_card) < BOTConstants::card_size_in_words(), "landing card offset: %u, " "N_words: %u", - (uint)_bot->offset_array(landing_card), (uint)BOTConstants::N_words); + (uint)_bot->offset_array(landing_card), (uint)BOTConstants::card_size_in_words()); } } } // -// threshold_ +// cur_card_boundary // | _index_ // v v // +-------+-------+-------+-------+-------+ // | i-1 | i | i+1 | i+2 | i+3 | // +-------+-------+-------+-------+-------+ // ( ^ ] -// block-start +// blk_start // -void G1BlockOffsetTablePart::alloc_block_work(HeapWord** threshold_, HeapWord* blk_start, +void G1BlockOffsetTablePart::alloc_block_work(HeapWord* blk_start, HeapWord* blk_end) { - // For efficiency, do copy-in/copy-out. - HeapWord* threshold = *threshold_; - size_t index = _bot->index_for_raw(threshold); + HeapWord* const cur_card_boundary = align_up_by_card_size(blk_start); + size_t const index = _bot->index_for_raw(cur_card_boundary); assert(blk_start != NULL && blk_end > blk_start, "phantom block"); - assert(blk_end > threshold, "should be past threshold"); - assert(blk_start <= threshold, "blk_start should be at or before threshold"); - assert(pointer_delta(threshold, blk_start) <= BOTConstants::N_words, - "offset should be <= BlockOffsetSharedArray::N"); + assert(blk_end > cur_card_boundary, "should be past cur_card_boundary"); + assert(blk_start <= cur_card_boundary, "blk_start should be at or before cur_card_boundary"); + assert(pointer_delta(cur_card_boundary, blk_start) < BOTConstants::card_size_in_words(), + "offset should be < BOTConstants::card_size_in_words()"); assert(G1CollectedHeap::heap()->is_in_reserved(blk_start), "reference must be into the heap"); - assert(G1CollectedHeap::heap()->is_in_reserved(blk_end-1), + assert(G1CollectedHeap::heap()->is_in_reserved(blk_end - 1), "limit must be within the heap"); - assert(threshold == _bot->_reserved.start() + index*BOTConstants::N_words, - "index must agree with threshold"); + assert(cur_card_boundary == _bot->_reserved.start() + index*BOTConstants::card_size_in_words(), + "index must agree with cur_card_boundary"); - DEBUG_ONLY(size_t orig_index = index;) + // Mark the card that holds the offset into the block. + _bot->set_offset_array(index, cur_card_boundary, blk_start); - // Mark the card that holds the offset into the block. Note - // that _next_offset_threshold is not updated until the end - // of this method. - _bot->set_offset_array(index, threshold, blk_start); + // We need to now mark the subsequent cards that this block spans. - // We need to now mark the subsequent cards that this blk spans. - - // Index of card on which blk ends. - size_t end_index = _bot->index_for(blk_end - 1); + // Index of card on which the block ends. + size_t end_index = _bot->index_for(blk_end - 1); // Are there more cards left to be updated? if (index + 1 <= end_index) { HeapWord* rem_st = _bot->address_for_index(index + 1); // Calculate rem_end this way because end_index // may be the last valid index in the covered region. - HeapWord* rem_end = _bot->address_for_index(end_index) + BOTConstants::N_words; + HeapWord* rem_end = _bot->address_for_index(end_index) + BOTConstants::card_size_in_words(); set_remainder_to_point_to_start(rem_st, rem_end); } - index = end_index + 1; - // Calculate threshold_ this way because end_index +#ifdef ASSERT + // Calculate new_card_boundary this way because end_index // may be the last valid index in the covered region. - threshold = _bot->address_for_index(end_index) + BOTConstants::N_words; - assert(threshold >= blk_end, "Incorrect offset threshold"); - - *threshold_ = threshold; + HeapWord* new_card_boundary = _bot->address_for_index(end_index) + BOTConstants::card_size_in_words(); + assert(new_card_boundary >= blk_end, "postcondition"); -#ifdef ASSERT // The offset can be 0 if the block starts on a boundary. That // is checked by an assertion above. size_t start_index = _bot->index_for(blk_start); HeapWord* boundary = _bot->address_for_index(start_index); - assert((_bot->offset_array(orig_index) == 0 && blk_start == boundary) || - (_bot->offset_array(orig_index) > 0 && _bot->offset_array(orig_index) <= BOTConstants::N_words), + assert((_bot->offset_array(index) == 0 && blk_start == boundary) || + (_bot->offset_array(index) > 0 && _bot->offset_array(index) < BOTConstants::card_size_in_words()), "offset array should have been set - " - "orig_index offset: %u, " + "index offset: %u, " "blk_start: " PTR_FORMAT ", " "boundary: " PTR_FORMAT, - (uint)_bot->offset_array(orig_index), + (uint)_bot->offset_array(index), p2i(blk_start), p2i(boundary)); - for (size_t j = orig_index + 1; j <= end_index; j++) { + for (size_t j = index + 1; j <= end_index; j++) { assert(_bot->offset_array(j) > 0 && _bot->offset_array(j) <= - (u_char) (BOTConstants::N_words+BOTConstants::N_powers-1), + (u_char) (BOTConstants::card_size_in_words()+BOTConstants::N_powers-1), "offset array should have been set - " "%u not > 0 OR %u not <= %u", (uint) _bot->offset_array(j), (uint) _bot->offset_array(j), - (uint) (BOTConstants::N_words+BOTConstants::N_powers-1)); + (uint) (BOTConstants::card_size_in_words() + BOTConstants::N_powers - 1)); } #endif } @@ -291,13 +281,11 @@ void G1BlockOffsetTablePart::alloc_block_work(HeapWord** threshold_, HeapWord* b void G1BlockOffsetTablePart::verify() const { assert(_hr->bottom() < _hr->top(), "Only non-empty regions should be verified."); size_t start_card = _bot->index_for(_hr->bottom()); - // Do not verify beyond the BOT allocation threshold. - assert(_hr->top() <= _next_offset_threshold, "invariant"); size_t end_card = _bot->index_for(_hr->top() - 1); for (size_t current_card = start_card; current_card < end_card; current_card++) { u_char entry = _bot->offset_array(current_card); - if (entry < BOTConstants::N_words) { + if (entry < BOTConstants::card_size_in_words()) { // The entry should point to an object before the current card. Verify that // it is possible to walk from that object in to the current card by just // iterating over the objects following it. @@ -331,12 +319,6 @@ void G1BlockOffsetTablePart::verify() const { } } -#ifdef ASSERT -void G1BlockOffsetTablePart::set_object_can_span(bool can_span) { - _object_can_span = can_span; -} -#endif - #ifndef PRODUCT void G1BlockOffsetTablePart::print_on(outputStream* out) { size_t from_index = _bot->index_for(_hr->bottom()); @@ -349,24 +331,10 @@ void G1BlockOffsetTablePart::print_on(outputStream* out) { i, p2i(_bot->address_for_index(i)), (uint) _bot->offset_array(i)); } - out->print_cr(" next offset threshold: " PTR_FORMAT, p2i(_next_offset_threshold)); } #endif // !PRODUCT -void G1BlockOffsetTablePart::zero_bottom_entry_raw() { - size_t bottom_index = _bot->index_for_raw(_hr->bottom()); - assert(_bot->address_for_index_raw(bottom_index) == _hr->bottom(), - "Precondition of call"); - _bot->set_offset_array_raw(bottom_index, 0); -} - -void G1BlockOffsetTablePart::initialize_threshold() { - _next_offset_threshold = _hr->bottom() + BOTConstants::N_words; -} - void G1BlockOffsetTablePart::set_for_starts_humongous(HeapWord* obj_top, size_t fill_size) { - // The first BOT entry should have offset 0. - reset_bot(); alloc_block(_hr->bottom(), obj_top); if (fill_size > 0) { alloc_block(obj_top, fill_size); diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp index 128e9d105a2e6631e6218b4540de2e01ad73fba3..04c966a29cca742b278a7794c85eaedbe3091c51 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp @@ -55,9 +55,9 @@ private: volatile u_char* _offset_array; // byte array keeping backwards offsets void check_offset(size_t offset, const char* msg) const { - assert(offset <= BOTConstants::N_words, + assert(offset < BOTConstants::card_size_in_words(), "%s - offset: " SIZE_FORMAT ", N_words: %u", - msg, offset, BOTConstants::N_words); + msg, offset, BOTConstants::card_size_in_words()); } // Bounds checking accessors: @@ -80,13 +80,13 @@ public: // Return the number of slots needed for an offset array // that covers mem_region_words words. static size_t compute_size(size_t mem_region_words) { - size_t number_of_slots = (mem_region_words / BOTConstants::N_words); + size_t number_of_slots = (mem_region_words / BOTConstants::card_size_in_words()); return ReservedSpace::allocation_align_size_up(number_of_slots); } // Returns how many bytes of the heap a single byte of the BOT corresponds to. static size_t heap_map_factor() { - return BOTConstants::N_bytes; + return BOTConstants::card_size(); } // Initialize the Block Offset Table to cover the memory region passed @@ -102,7 +102,7 @@ public: inline HeapWord* address_for_index(size_t index) const; // Variant of address_for_index that does not check the index for validity. inline HeapWord* address_for_index_raw(size_t index) const { - return _reserved.start() + (index << BOTConstants::LogN_words); + return _reserved.start() + (index << BOTConstants::log_card_size_in_words()); } }; @@ -111,12 +111,6 @@ class G1BlockOffsetTablePart { friend class HeapRegion; friend class VMStructs; private: - // allocation boundary at which offset array must be updated - HeapWord* _next_offset_threshold; - - // Indicates if an object can span into this G1BlockOffsetTablePart. - debug_only(bool _object_can_span;) - // This is the global BlockOffsetTable. G1BlockOffsetTable* _bot; @@ -132,10 +126,6 @@ private: // that is closed: [start_index, end_index] void set_remainder_to_point_to_start_incl(size_t start, size_t end); - // Zero out the entry for _bottom (offset will be zero). Does not check for availability of the - // memory first. - void zero_bottom_entry_raw(); - inline size_t block_size(const HeapWord* p) const; // Returns the address of a block whose start is at most "addr". @@ -147,19 +137,23 @@ private: inline HeapWord* forward_to_block_containing_addr(HeapWord* q, HeapWord* n, const void* addr) const; - // Requires that "*threshold_" be the first array entry boundary at or - // above "blk_start". If the block starts at or crosses "*threshold_", records - // "blk_start" as the appropriate block start for the array index - // starting at "*threshold_", and for any other indices crossed by the - // block. Updates "*threshold_" to correspond to the first index after - // the block end. - void alloc_block_work(HeapWord** threshold_, - HeapWord* blk_start, - HeapWord* blk_end); + // Update BOT entries corresponding to the mem range [blk_start, blk_end). + void alloc_block_work(HeapWord* blk_start, HeapWord* blk_end); void check_all_cards(size_t left_card, size_t right_card) const; public: + static HeapWord* align_up_by_card_size(HeapWord* const addr) { + return align_up(addr, BOTConstants::card_size()); + } + + static bool is_crossing_card_boundary(HeapWord* const obj_start, + HeapWord* const obj_end) { + HeapWord* cur_card_boundary = align_up_by_card_size(obj_start); + // strictly greater-than + return obj_end > cur_card_boundary; + } + // The elements of the array are initialized to zero. G1BlockOffsetTablePart(G1BlockOffsetTable* array, HeapRegion* hr); @@ -167,52 +161,24 @@ public: void verify() const; - // Given an address calculate where the next threshold needing an update is. - inline HeapWord* threshold_for_addr(const void* addr); - // Returns the address of the start of the block containing "addr", or // else "null" if it is covered by no block. (May have side effects, // namely updating of shared array entries that "point" too far // backwards. This can occur, for example, when lab allocation is used // in a space covered by the table.) inline HeapWord* block_start(const void* addr); - // Same as above, but does not have any of the possible side effects - // discussed above. - inline HeapWord* block_start_const(const void* addr) const; - - // Initialize the threshold to reflect the first boundary after the - // bottom of the covered region. - void initialize_threshold(); - - void reset_bot() { - zero_bottom_entry_raw(); - initialize_threshold(); - } - // Return the next threshold, the point at which the table should be - // updated. - HeapWord* threshold() const { return _next_offset_threshold; } - - // Sets the threshold explicitly to keep it consistent with what has been - // updated. This needs to be done when the threshold is not used for updating - // the bot, for example when promoting to old in young collections. - void set_threshold(HeapWord* threshold) { _next_offset_threshold = threshold; } - - // These must be guaranteed to work properly (i.e., do nothing) - // when "blk_start" ("blk" for second version) is "NULL". In this - // implementation, that's true because NULL is represented as 0, and thus - // never exceeds the "_next_offset_threshold". void alloc_block(HeapWord* blk_start, HeapWord* blk_end) { - if (blk_end > _next_offset_threshold) { - alloc_block_work(&_next_offset_threshold, blk_start, blk_end); + if (is_crossing_card_boundary(blk_start, blk_end)) { + alloc_block_work(blk_start, blk_end); } } - void alloc_block(HeapWord* blk, size_t size) { - alloc_block(blk, blk+size); + + void alloc_block(HeapWord* blk_start, size_t size) { + alloc_block(blk_start, blk_start + size); } void set_for_starts_humongous(HeapWord* obj_top, size_t fill_size); - void set_object_can_span(bool can_span) NOT_DEBUG_RETURN; void print_on(outputStream* out) PRODUCT_RETURN; }; diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp index 7471a4ca0787fa6e5f01ea2225453c9e6c46ed16..f70cb118627225f646cb43345c44b4a5a37cb085 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp @@ -30,20 +30,7 @@ #include "gc/g1/heapRegion.hpp" #include "gc/shared/memset_with_concurrent_readers.hpp" #include "runtime/atomic.hpp" - -inline HeapWord* G1BlockOffsetTablePart::threshold_for_addr(const void* addr) { - assert(addr >= _hr->bottom() && addr < _hr->top(), "invalid address"); - size_t index = _bot->index_for(addr); - HeapWord* card_boundary = _bot->address_for_index(index); - // Address at card boundary, use as threshold. - if (card_boundary == addr) { - return card_boundary; - } - - // Calculate next threshold. - HeapWord* threshold = card_boundary + BOTConstants::N_words; - return threshold; -} +#include "oops/oop.inline.hpp" inline HeapWord* G1BlockOffsetTablePart::block_start(const void* addr) { assert(addr >= _hr->bottom() && addr < _hr->top(), "invalid address"); @@ -84,7 +71,7 @@ void G1BlockOffsetTable::set_offset_array(size_t left, size_t right, u_char offs // Variant of index_for that does not check the index for validity. inline size_t G1BlockOffsetTable::index_for_raw(const void* p) const { - return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> BOTConstants::LogN; + return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> BOTConstants::log_card_size(); } inline size_t G1BlockOffsetTable::index_for(const void* p) const { @@ -113,21 +100,26 @@ inline size_t G1BlockOffsetTablePart::block_size(const HeapWord* p) const { } inline HeapWord* G1BlockOffsetTablePart::block_at_or_preceding(const void* addr) const { - assert(_object_can_span || _bot->offset_array(_bot->index_for(_hr->bottom())) == 0, - "Object crossed region boundary, found offset %u instead of 0", - (uint) _bot->offset_array(_bot->index_for(_hr->bottom()))); +#ifdef ASSERT + if (!_hr->is_continues_humongous()) { + // For non-ContinuesHumongous regions, the first obj always starts from bottom. + u_char offset = _bot->offset_array(_bot->index_for(_hr->bottom())); + assert(offset == 0, "Found offset %u instead of 0 for region %u %s", + offset, _hr->hrm_index(), _hr->get_short_type_str()); + } +#endif size_t index = _bot->index_for(addr); uint offset = _bot->offset_array(index); // Extend u_char to uint. - while (offset >= BOTConstants::N_words) { + while (offset >= BOTConstants::card_size_in_words()) { // The excess of the offset from N_words indicates a power of Base // to go back by. size_t n_cards_back = BOTConstants::entry_to_cards_back(offset); index -= n_cards_back; offset = _bot->offset_array(index); } - assert(offset < BOTConstants::N_words, "offset too large"); + assert(offset < BOTConstants::card_size_in_words(), "offset too large"); HeapWord* q = _bot->address_for_index(index); return q - offset; @@ -144,10 +136,8 @@ inline HeapWord* G1BlockOffsetTablePart::forward_to_block_containing_addr(HeapWo "BOT not precise. Index for n: " SIZE_FORMAT " must be equal to the index for addr: " SIZE_FORMAT, _bot->index_for(n), _bot->index_for(addr)); q = n; - oop obj = cast_to_oop(q); - if (obj->klass_or_null_acquire() == NULL) { - return q; - } + assert(cast_to_oop(q)->klass_or_null() != nullptr, + "start of block must be an initialized object"); n += block_size(q); } assert(q <= n, "wrong order for q and addr"); diff --git a/src/hotspot/share/gc/g1/g1CardCounts.cpp b/src/hotspot/share/gc/g1/g1CardCounts.cpp index 1607ec40b95b9a96b2f015bd2b2c5979167001d1..6e56eecafb9a2a4afd22974a13e361c0c1c0b87e 100644 --- a/src/hotspot/share/gc/g1/g1CardCounts.cpp +++ b/src/hotspot/share/gc/g1/g1CardCounts.cpp @@ -126,7 +126,7 @@ void G1CardCounts::clear_range(MemRegion mr) { HeapWord* start_addr = _ct->addr_for(from_card_ptr); assert(start_addr == mr.start(), "MemRegion start must be aligned to a card."); HeapWord* last_addr = _ct->addr_for(last_card_ptr); - assert((last_addr + G1CardTable::card_size_in_words) == mr.end(), "MemRegion end must be aligned to a card."); + assert((last_addr + G1CardTable::card_size_in_words()) == mr.end(), "MemRegion end must be aligned to a card."); #endif // ASSERT // Clear the counts for the (exclusive) card range. diff --git a/src/hotspot/share/gc/g1/g1CardTable.cpp b/src/hotspot/share/gc/g1/g1CardTable.cpp index 9e565c1ba64a6b9b26ae09a66053d768f5a74497..4fc6db5bac10ea92d42130abb5808015269bbe77 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.cpp +++ b/src/hotspot/share/gc/g1/g1CardTable.cpp @@ -62,7 +62,7 @@ void G1CardTable::initialize(G1RegionToSpaceMapper* mapper) { _covered[0] = _whole_heap; _byte_map = (CardValue*) mapper->reserved().start(); - _byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); + _byte_map_base = _byte_map - (uintptr_t(low_bound) >> _card_shift); assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map"); assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map"); diff --git a/src/hotspot/share/gc/g1/g1CardTable.hpp b/src/hotspot/share/gc/g1/g1CardTable.hpp index fd150db39f8dfa9102f8a9cd884cf1f7365aeb2c..e73cbfaf86d2f100374198b560ef619eada15465 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.hpp +++ b/src/hotspot/share/gc/g1/g1CardTable.hpp @@ -110,12 +110,12 @@ public: inline uint region_idx_for(CardValue* p); static size_t compute_size(size_t mem_region_size_in_words) { - size_t number_of_slots = (mem_region_size_in_words / card_size_in_words); + size_t number_of_slots = (mem_region_size_in_words / _card_size_in_words); return ReservedSpace::allocation_align_size_up(number_of_slots); } // Returns how many bytes of the heap a single byte of the Card Table corresponds to. - static size_t heap_map_factor() { return card_size; } + static size_t heap_map_factor() { return _card_size; } void initialize() {} void initialize(G1RegionToSpaceMapper* mapper); diff --git a/src/hotspot/share/gc/g1/g1CardTable.inline.hpp b/src/hotspot/share/gc/g1/g1CardTable.inline.hpp index 41ffdf5318e30c1fb37b1ab162fc2cc6102d2737..d2962cbad845526fceb36755fce7f83f9042711b 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CardTable.inline.hpp @@ -31,7 +31,7 @@ inline uint G1CardTable::region_idx_for(CardValue* p) { size_t const card_idx = pointer_delta(p, _byte_map, sizeof(CardValue)); - return (uint)(card_idx >> (HeapRegion::LogOfHRGrainBytes - card_shift)); + return (uint)(card_idx >> (HeapRegion::LogOfHRGrainBytes - _card_shift)); } inline bool G1CardTable::mark_clean_as_dirty(CardValue* card) { diff --git a/src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp b/src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp index 725e0130388c069722c80c6838c910b978060bcf..f2dc595ef5369cf9a736afdebaff12c80db529c2 100644 --- a/src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp +++ b/src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp @@ -40,8 +40,8 @@ void G1CodeBlobClosure::HeapRegionGatheringOopClosure::do_oop_work(T* p) { if (!CompressedOops::is_null(oop_or_narrowoop)) { oop o = CompressedOops::decode_not_null(oop_or_narrowoop); HeapRegion* hr = _g1h->heap_region_containing(o); - assert(!_g1h->is_in_cset(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in collection set then evacuation failed and nm must already be in the remset"); - hr->add_strong_code_root(_nm); + assert(!_g1h->is_in_cset(o) || hr->rem_set()->code_roots_list_contains(_nm), "if o still in collection set then evacuation failed and nm must already be in the remset"); + hr->add_code_root(_nm); } } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index b35f48eaa7bad553528fad173ecd323de712d467..adc3e66d316ecc63b3dd6d6a82a6b888eede4352 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1042,8 +1042,8 @@ void G1CollectedHeap::prepare_heap_for_mutators() { resize_heap_if_necessary(); uncommit_regions_if_necessary(); - // Rebuild the strong code root lists for each region - rebuild_strong_code_roots(); + // Rebuild the code root lists for each region + rebuild_code_roots(); // Purge code root memory purge_code_root_memory(); @@ -1660,7 +1660,7 @@ jint G1CollectedHeap::initialize() { // The G1FromCardCache reserves card with value 0 as "invalid", so the heap must not // start within the first card. - guarantee((uintptr_t)(heap_rs.base()) >= G1CardTable::card_size, "Java heap must not start within the first card."); + guarantee((uintptr_t)(heap_rs.base()) >= G1CardTable::card_size(), "Java heap must not start within the first card."); G1FromCardCache::initialize(max_reserved_regions()); // Also create a G1 rem set. _rem_set = new G1RemSet(this, _card_table, _hot_card_cache); @@ -2957,14 +2957,18 @@ void G1CollectedHeap::record_obj_copy_mem_stats() { create_g1_evac_summary(&_old_evac_stats)); } +void G1CollectedHeap::clear_prev_bitmap_for_region(HeapRegion* hr) { + MemRegion mr(hr->bottom(), hr->end()); + concurrent_mark()->clear_range_in_prev_bitmap(mr); +} + void G1CollectedHeap::free_region(HeapRegion* hr, FreeRegionList* free_list) { assert(!hr->is_free(), "the region should not be free"); assert(!hr->is_empty(), "the region should not be empty"); assert(_hrm.is_available(hr->hrm_index()), "region should be committed"); if (G1VerifyBitmaps) { - MemRegion mr(hr->bottom(), hr->end()); - concurrent_mark()->clear_range_in_prev_bitmap(mr); + clear_prev_bitmap_for_region(hr); } // Clear the card counts for this region. @@ -3291,7 +3295,6 @@ void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region, _bytes_used_during_gc += allocated_bytes; if (dest.is_old()) { old_set_add(alloc_region); - alloc_region->update_bot_threshold(); } else { assert(dest.is_young(), "Retiring alloc region should be young (%d)", dest.type()); _survivor.add_used_bytes(allocated_bytes); @@ -3338,8 +3341,8 @@ public: " starting at " HR_FORMAT, p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())); - // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries. - hr->add_strong_code_root_locked(_nm); + // HeapRegion::add_code_root_locked() avoids adding duplicate entries. + hr->add_code_root_locked(_nm); } } @@ -3364,7 +3367,7 @@ public: " starting at " HR_FORMAT, p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())); - hr->remove_strong_code_root(_nm); + hr->remove_code_root(_nm); } } @@ -3407,11 +3410,11 @@ void G1CollectedHeap::purge_code_root_memory() { G1CodeRootSet::purge(); } -class RebuildStrongCodeRootClosure: public CodeBlobClosure { +class RebuildCodeRootClosure: public CodeBlobClosure { G1CollectedHeap* _g1h; public: - RebuildStrongCodeRootClosure(G1CollectedHeap* g1h) : + RebuildCodeRootClosure(G1CollectedHeap* g1h) : _g1h(g1h) {} void do_code_blob(CodeBlob* cb) { @@ -3424,8 +3427,8 @@ public: } }; -void G1CollectedHeap::rebuild_strong_code_roots() { - RebuildStrongCodeRootClosure blob_cl(this); +void G1CollectedHeap::rebuild_code_roots() { + RebuildCodeRootClosure blob_cl(this); CodeCache::blobs_do(&blob_cl); } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 30ff5d19bec92854fc5a1efd4e7192506b06c577..83da03019af80d2b608f7df5f6299dc432cdcb8c 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -622,6 +622,8 @@ public: // for all regions. void verify_region_attr_remset_is_tracked() PRODUCT_RETURN; + void clear_prev_bitmap_for_region(HeapRegion* hr); + bool is_user_requested_concurrent_full_gc(GCCause::Cause cause); // This is called at the start of either a concurrent cycle or a Full @@ -1252,6 +1254,9 @@ public: inline bool is_obj_dead_full(const oop obj, const HeapRegion* hr) const; inline bool is_obj_dead_full(const oop obj) const; + // Mark the live object that failed evacuation in the prev bitmap. + inline void mark_evac_failure_object(const oop obj, uint worker_id) const; + G1ConcurrentMark* concurrent_mark() const { return _cm; } // Refinement @@ -1282,9 +1287,9 @@ public: // Free up superfluous code root memory. void purge_code_root_memory(); - // Rebuild the strong code root lists for each region + // Rebuild the code root lists for each region // after a full GC. - void rebuild_strong_code_roots(); + void rebuild_code_roots(); // Performs cleaning of data structures after class unloading. void complete_cleaning(BoolObjectClosure* is_alive, bool class_unloading_occurred); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp index 159ee0471c24c1c9dcd0450b4a1daa0aee12a04e..264121cfa939c804c35df3bf5982e0ad69729fe4 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp @@ -29,6 +29,7 @@ #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1CollectorState.hpp" +#include "gc/g1/g1ConcurrentMark.inline.hpp" #include "gc/g1/g1EvacFailureRegions.hpp" #include "gc/g1/g1Policy.hpp" #include "gc/g1/g1RemSet.hpp" @@ -247,6 +248,13 @@ inline bool G1CollectedHeap::is_obj_dead_full(const oop obj) const { return is_obj_dead_full(obj, heap_region_containing(obj)); } +inline void G1CollectedHeap::mark_evac_failure_object(const oop obj, uint worker_id) const { + // All objects failing evacuation are live. What we'll do is + // that we'll update the prev marking info so that they are + // all under PTAMS and explicitly marked. + _cm->par_mark_in_prev_bitmap(obj); +} + inline void G1CollectedHeap::set_humongous_reclaim_candidate(uint region, bool value) { assert(_hrm.at(region)->is_starts_humongous(), "Must start a humongous object"); _humongous_reclaim_candidates.set_candidate(region, value); diff --git a/src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp b/src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp index 5692a0c407e273dfa07ab877b03e7a88c0f752cd..e8894323d651837505c767f5512ce8170886162d 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_GC_G1_G1COLLECTIONSETCHOOSER_HPP #include "gc/g1/heapRegion.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/globals.hpp" class G1CollectionSetCandidates; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index ece2ac0452adedf33b7e7580b2ae737613302062..5d0c0dd605daa1ae9c4e870a89e2d7b080b45595 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -1646,9 +1646,10 @@ void G1ConcurrentMark::weak_refs_work() { if (has_overflown()) { // We can not trust g1_is_alive and the contents of the heap if the marking stack // overflowed while processing references. Exit the VM. - fatal("Overflow during reference processing, can not continue. Please " - "increase MarkStackSizeMax (current value: " SIZE_FORMAT ") and " - "restart.", MarkStackSizeMax); + fatal("Overflow during reference processing, can not continue. Current mark stack depth: " + SIZE_FORMAT ", MarkStackSize: " SIZE_FORMAT ", MarkStackSizeMax: " SIZE_FORMAT ". " + "Please increase MarkStackSize and/or MarkStackSizeMax and restart.", + _global_mark_stack.size(), MarkStackSize, MarkStackSizeMax); return; } @@ -2008,13 +2009,21 @@ void G1ConcurrentMark::print_stats() { } void G1ConcurrentMark::concurrent_cycle_abort() { - if (!cm_thread()->in_progress() || _has_aborted) { - // We haven't started a concurrent cycle or we have already aborted it. No need to do anything. + // We haven't started a concurrent cycle no need to do anything; we might have + // aborted the marking because of shutting down though. In this case the marking + // might have already completed the abort (leading to in_progress() below to + // return false), however this still left marking state particularly in the + // shared marking bitmap that must be cleaned up. + // If there are multiple full gcs during shutdown we do this work repeatedly for + // nothing, but this situation should be extremely rare (a full gc after shutdown + // has been signalled is alredy rare), and this work should be negligible compared + // to actual full gc work. + if (!cm_thread()->in_progress() && !_g1h->concurrent_mark_is_terminating()) { return; } - // Clear all marks in the next bitmap for the next marking cycle. This will allow us to skip the next - // concurrent bitmap clearing. + // Clear all marks in the next bitmap for this full gc as it has been used by the + // marking that is interrupted by this full gc. { GCTraceTime(Debug, gc) debug("Clear Next Bitmap"); clear_next_bitmap(_g1h->workers()); @@ -2028,9 +2037,8 @@ void G1ConcurrentMark::concurrent_cycle_abort() { for (uint i = 0; i < _max_num_tasks; ++i) { _tasks[i]->clear_region_fields(); } - _first_overflow_barrier_sync.abort(); - _second_overflow_barrier_sync.abort(); - _has_aborted = true; + + abort_marking_threads(); SATBMarkQueueSet& satb_mq_set = G1BarrierSet::satb_mark_queue_set(); satb_mq_set.abandon_partial_marking(); @@ -2041,6 +2049,13 @@ void G1ConcurrentMark::concurrent_cycle_abort() { satb_mq_set.is_active() /* expected_active */); } +void G1ConcurrentMark::abort_marking_threads() { + assert(!_root_regions.scan_in_progress(), "still doing root region scan"); + _has_aborted = true; + _first_overflow_barrier_sync.abort(); + _second_overflow_barrier_sync.abort(); +} + static void print_ms_time_info(const char* prefix, const char* name, NumberSeq& ns) { log_trace(gc, marking)("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).", @@ -2939,7 +2954,7 @@ G1CMTask::G1CMTask(uint worker_id, G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* phase_name) : _total_used_bytes(0), _total_capacity_bytes(0), _total_prev_live_bytes(0), _total_next_live_bytes(0), - _total_remset_bytes(0), _total_strong_code_roots_bytes(0) + _total_remset_bytes(0), _total_code_roots_bytes(0) { if (!log_is_enabled(Trace, gc, liveness)) { return; @@ -2999,7 +3014,7 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) { size_t next_live_bytes = r->next_live_bytes(); double gc_eff = r->gc_efficiency(); size_t remset_bytes = r->rem_set()->mem_size(); - size_t strong_code_roots_bytes = r->rem_set()->strong_code_roots_mem_size(); + size_t code_roots_bytes = r->rem_set()->code_roots_mem_size(); const char* remset_type = r->rem_set()->get_short_state_str(); FormatBuffer<16> gc_efficiency(""); @@ -3008,7 +3023,7 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) { _total_prev_live_bytes += prev_live_bytes; _total_next_live_bytes += next_live_bytes; _total_remset_bytes += remset_bytes; - _total_strong_code_roots_bytes += strong_code_roots_bytes; + _total_code_roots_bytes += code_roots_bytes; if(gc_eff < 0) { gc_efficiency.append("-"); @@ -3029,7 +3044,7 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) { G1PPRL_BYTE_FORMAT, type, p2i(bottom), p2i(end), used_bytes, prev_live_bytes, next_live_bytes, gc_efficiency.buffer(), - remset_bytes, remset_type, strong_code_roots_bytes); + remset_bytes, remset_type, code_roots_bytes); return false; } @@ -3059,5 +3074,5 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() { bytes_to_mb(_total_next_live_bytes), percent_of(_total_next_live_bytes, _total_capacity_bytes), bytes_to_mb(_total_remset_bytes), - bytes_to_mb(_total_strong_code_roots_bytes)); + bytes_to_mb(_total_code_roots_bytes)); } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index 28752225f133688726d2731fa676d5c6577076ba..cc603df18c4d650a7f87cbe04364f42b57bf52af 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -496,6 +496,11 @@ public: void concurrent_cycle_abort(); void concurrent_cycle_end(); + // Notifies marking threads to abort. This is a best-effort notification. Does not + // guarantee or update any state after the call. Root region scan must not be + // running. + void abort_marking_threads(); + void update_accum_task_vtime(int i, double vtime) { _accum_task_vtime[i] += vtime; } @@ -563,7 +568,7 @@ public: void cleanup(); // Mark in the previous bitmap. Caution: the prev bitmap is usually read-only, so use // this carefully. - inline void mark_in_prev_bitmap(oop p); + inline void par_mark_in_prev_bitmap(oop p); // Clears marks for all objects in the given range, for the prev or // next bitmaps. Caution: the previous bitmap is usually @@ -842,8 +847,8 @@ class G1PrintRegionLivenessInfoClosure : public HeapRegionClosure { // Accumulator for the remembered set size size_t _total_remset_bytes; - // Accumulator for strong code roots memory size - size_t _total_strong_code_roots_bytes; + // Accumulator for code roots memory size + size_t _total_code_roots_bytes; static double bytes_to_mb(size_t val) { return (double) val / (double) M; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp index 9d45803e2ef9963e2a1f318590dceefc64bfdc01..9d0670a6fae588bf1e922fd38eee35ae9ad4a189 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp @@ -268,9 +268,8 @@ inline bool G1CMTask::deal_with_reference(T* p) { return make_reference_grey(obj); } -inline void G1ConcurrentMark::mark_in_prev_bitmap(oop p) { - assert(!_prev_mark_bitmap->is_marked(p), "sanity"); - _prev_mark_bitmap->mark(p); +inline void G1ConcurrentMark::par_mark_in_prev_bitmap(oop p) { + _prev_mark_bitmap->par_mark(p); } bool G1ConcurrentMark::is_marked_in_prev_bitmap(oop p) const { diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp index dde620e9398f852b2d326e9776270b532f717e75..d7bdd8ea9a564eee148779de6793e622d4f796ea 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp @@ -56,26 +56,6 @@ G1ConcurrentMarkThread::G1ConcurrentMarkThread(G1ConcurrentMark* cm) : create_and_start(); } -class CMRemark : public VoidClosure { - G1ConcurrentMark* _cm; -public: - CMRemark(G1ConcurrentMark* cm) : _cm(cm) {} - - void do_void(){ - _cm->remark(); - } -}; - -class CMCleanup : public VoidClosure { - G1ConcurrentMark* _cm; -public: - CMCleanup(G1ConcurrentMark* cm) : _cm(cm) {} - - void do_void(){ - _cm->cleanup(); - } -}; - double G1ConcurrentMarkThread::mmu_delay_end(G1Policy* policy, bool remark) { // There are 3 reasons to use SuspendibleThreadSetJoiner. // 1. To avoid concurrency problem. @@ -159,6 +139,15 @@ void G1ConcurrentMarkThread::run_service() { } void G1ConcurrentMarkThread::stop_service() { + if (in_progress()) { + // We are not allowed to abort the marking threads during root region scan. + // Needs to be done separately. + _cm->root_regions()->abort(); + _cm->root_regions()->wait_until_scan_finished(); + + _cm->abort_marking_threads(); + } + MutexLocker ml(CGC_lock, Mutex::_no_safepoint_check_flag); CGC_lock->notify_all(); } @@ -239,8 +228,7 @@ bool G1ConcurrentMarkThread::subphase_delay_to_keep_mmu_before_remark() { bool G1ConcurrentMarkThread::subphase_remark() { ConcurrentGCBreakpoints::at("BEFORE MARKING COMPLETED"); - CMRemark cl(_cm); - VM_G1Concurrent op(&cl, "Pause Remark"); + VM_G1PauseRemark op; VMThread::execute(&op); return _cm->has_aborted(); } @@ -257,8 +245,7 @@ bool G1ConcurrentMarkThread::phase_delay_to_keep_mmu_before_cleanup() { } bool G1ConcurrentMarkThread::phase_cleanup() { - CMCleanup cl(_cm); - VM_G1Concurrent op(&cl, "Pause Cleanup"); + VM_G1PauseCleanup op; VMThread::execute(&op); return _cm->has_aborted(); } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp index 7d8076f3cf3c6d80e8d3304de25f4caf86b67acb..3393d3b601242cb41e943b7d6814c07c3cc658ff 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -250,14 +250,21 @@ static size_t calc_min_yellow_zone_size() { } } +// An initial guess at the rate for pause-time card refinement for one +// thread, used when computing the default initial green zone value. +const double InitialPauseTimeCardRefinementRate = 200.0; + static size_t calc_init_green_zone() { - size_t green = G1ConcRefinementGreenZone; - const char* name = "G1ConcRefinementGreenZone"; + size_t green; if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) { - green = ParallelGCThreads; - name = "ParallelGCThreads"; + const double rate = InitialPauseTimeCardRefinementRate * ParallelGCThreads; + // The time budget for pause-time card refinement. + const double ms = MaxGCPauseMillis * (G1RSetUpdatingPauseTimePercent / 100.0); + green = rate * ms; + } else { + green = configuration_buffers_to_cards(G1ConcRefinementGreenZone, + "G1ConcRefinementGreenZone"); } - green = configuration_buffers_to_cards(green, name); return MIN2(green, max_green_zone); } diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp index 9819328ee669dac107c82efc54d97b77b098bfd2..22e8e218057c914ad08cca8da3063e983756e2f8 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "gc/g1/g1BarrierSet.inline.hpp" -#include "gc/g1/g1BufferNodeList.hpp" #include "gc/g1/g1CardTableEntryClosure.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentRefineStats.hpp" @@ -35,6 +34,7 @@ #include "gc/g1/g1RemSet.hpp" #include "gc/g1/g1ThreadLocalData.hpp" #include "gc/g1/heapRegionRemSet.inline.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "memory/iterator.hpp" #include "runtime/atomic.hpp" @@ -123,7 +123,13 @@ void G1DirtyCardQueueSet::enqueue_completed_buffer(BufferNode* cbn) { // Increment _num_cards before adding to queue, so queue removal doesn't // need to deal with _num_cards possibly going negative. size_t new_num_cards = Atomic::add(&_num_cards, buffer_size() - cbn->index()); - _completed.push(*cbn); + { + // Perform push in CS. The old tail may be popped while the push is + // observing it (attaching it to the new buffer). We need to ensure it + // can't be reused until the push completes, to avoid ABA problems. + GlobalCounter::CriticalSection cs(Thread::current()); + _completed.push(*cbn); + } if ((new_num_cards > process_cards_threshold()) && (_primary_refinement_thread != NULL)) { _primary_refinement_thread->activate(); @@ -307,7 +313,7 @@ void G1DirtyCardQueueSet::enqueue_all_paused_buffers() { } void G1DirtyCardQueueSet::abandon_completed_buffers() { - G1BufferNodeList list = take_all_completed_buffers(); + BufferNodeList list = take_all_completed_buffers(); BufferNode* buffers_to_delete = list._head; while (buffers_to_delete != NULL) { BufferNode* bn = buffers_to_delete; @@ -328,20 +334,20 @@ void G1DirtyCardQueueSet::notify_if_necessary() { // result. The queue sets must share the same allocator. void G1DirtyCardQueueSet::merge_bufferlists(G1RedirtyCardsQueueSet* src) { assert(allocator() == src->allocator(), "precondition"); - const G1BufferNodeList from = src->take_all_completed_buffers(); + const BufferNodeList from = src->take_all_completed_buffers(); if (from._head != NULL) { Atomic::add(&_num_cards, from._entry_count); _completed.append(*from._head, *from._tail); } } -G1BufferNodeList G1DirtyCardQueueSet::take_all_completed_buffers() { +BufferNodeList G1DirtyCardQueueSet::take_all_completed_buffers() { enqueue_all_paused_buffers(); verify_num_cards(); Pair pair = _completed.take_all(); size_t num_cards = Atomic::load(&_num_cards); Atomic::store(&_num_cards, size_t(0)); - return G1BufferNodeList(pair.first, pair.second, num_cards); + return BufferNodeList(pair.first, pair.second, num_cards); } class G1RefineBufferedCards : public StackObj { @@ -495,6 +501,14 @@ void G1DirtyCardQueueSet::handle_completed_buffer(BufferNode* new_node, return; } + // Don't try to process a buffer that will just get immediately paused. + // When going into a safepoint it's just a waste of effort. + // When coming out of a safepoint, Java threads may be running before the + // yield request (for non-Java threads) has been cleared. + if (SuspendibleThreadSet::should_yield()) { + return; + } + // Only Java threads perform mutator refinement. if (!Thread::current()->is_Java_thread()) { return; diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp index 9e9ad0ee80cddb67a71c7818bb648108c0ebb9d3..051e29058ebd6af7cf00c473740888402c4d201d 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,10 @@ #ifndef SHARE_GC_G1_G1DIRTYCARDQUEUE_HPP #define SHARE_GC_G1_G1DIRTYCARDQUEUE_HPP -#include "gc/g1/g1BufferNodeList.hpp" #include "gc/g1/g1FreeIdSet.hpp" #include "gc/g1/g1CardTable.hpp" #include "gc/g1/g1ConcurrentRefineStats.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "gc/shared/ptrQueue.hpp" #include "memory/allocation.hpp" #include "memory/padded.hpp" @@ -69,7 +69,7 @@ public: class G1DirtyCardQueueSet: public PtrQueueSet { // Head and tail of a list of BufferNodes, linked through their next() - // fields. Similar to G1BufferNodeList, but without the _entry_count. + // fields. Similar to BufferNodeList, but without the _entry_count. struct HeadTail { BufferNode* _head; BufferNode* _tail; @@ -275,7 +275,7 @@ public: void merge_bufferlists(G1RedirtyCardsQueueSet* src); - G1BufferNodeList take_all_completed_buffers(); + BufferNodeList take_all_completed_buffers(); void flush_queue(G1DirtyCardQueue& queue); diff --git a/src/hotspot/share/gc/g1/g1EvacFailure.cpp b/src/hotspot/share/gc/g1/g1EvacFailure.cpp index e447b0f07763fb9f9c68996c4aaa02de996b989b..2a4f46ff16e85da7cf6157004d71656859fd73e9 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp @@ -28,6 +28,7 @@ #include "gc/g1/g1ConcurrentMark.inline.hpp" #include "gc/g1/g1EvacFailure.hpp" #include "gc/g1/g1EvacFailureRegions.hpp" +#include "gc/g1/g1GCPhaseTimes.hpp" #include "gc/g1/g1HeapVerifier.hpp" #include "gc/g1/g1OopClosures.inline.hpp" #include "gc/g1/heapRegion.hpp" @@ -37,7 +38,7 @@ #include "oops/compressedOops.inline.hpp" #include "oops/oop.inline.hpp" -class RemoveSelfForwardPtrObjClosure: public ObjectClosure { +class RemoveSelfForwardPtrObjClosure { G1CollectedHeap* _g1h; G1ConcurrentMark* _cm; HeapRegion* _hr; @@ -60,13 +61,13 @@ public: size_t marked_bytes() { return _marked_words * HeapWordSize; } - // Iterate over the live objects in the region to find self-forwarded objects + // Handle the marked objects in the region. These are self-forwarded objects // that need to be kept live. We need to update the remembered sets of these // objects. Further update the BOT and marks. // We can coalesce and overwrite the remaining heap contents with dummy objects // as they have either been dead or evacuated (which are unreferenced now, i.e. // dead too) already. - void do_object(oop obj) { + size_t apply(oop obj) { HeapWord* obj_addr = cast_from_oop(obj); assert(_last_forwarded_object_end <= obj_addr, "should iterate in ascending address order"); assert(_hr->is_in(obj_addr), "sanity"); @@ -75,12 +76,8 @@ public: assert(obj->is_forwarded() && obj->forwardee() == obj, "sanity"); zap_dead_objects(_last_forwarded_object_end, obj_addr); - // We consider all objects that we find self-forwarded to be - // live. What we'll do is that we'll update the prev marking - // info so that they are all under PTAMS and explicitly marked. - if (!_cm->is_marked_in_prev_bitmap(obj)) { - _cm->mark_in_prev_bitmap(obj); - } + + assert(_cm->is_marked_in_prev_bitmap(obj), "should be correctly marked"); if (_during_concurrent_start) { // For the next marking info we'll only mark the // self-forwarded objects explicitly if we are during @@ -92,7 +89,7 @@ public: // explicitly and all objects in the CSet are considered // (implicitly) live. So, we won't mark them explicitly and // we'll leave them over NTAMS. - _cm->mark_in_next_bitmap(_worker_id, _hr, obj); + _cm->mark_in_next_bitmap(_worker_id, obj); } size_t obj_size = obj->size(); @@ -102,10 +99,12 @@ public: HeapWord* obj_end = obj_addr + obj_size; _last_forwarded_object_end = obj_end; _hr->alloc_block_in_bot(obj_addr, obj_end); + return obj_size; } // Fill the memory area from start to end with filler objects, and update the BOT - // and the mark bitmap accordingly. + // accordingly. Since we clear and use the prev bitmap for marking objects that + // failed evacuation, there is no work to be done there. void zap_dead_objects(HeapWord* start, HeapWord* end) { if (start == end) { return; @@ -134,7 +133,7 @@ public: #endif } } - _cm->clear_range_in_prev_bitmap(mr); + assert(!_cm->is_marked_in_prev_bitmap(cast_to_oop(start)), "should not be marked in prev bitmap"); } void zap_remainder() { @@ -148,12 +147,15 @@ class RemoveSelfForwardPtrHRClosure: public HeapRegionClosure { G1EvacFailureRegions* _evac_failure_regions; + G1GCPhaseTimes* _phase_times; + public: RemoveSelfForwardPtrHRClosure(uint worker_id, G1EvacFailureRegions* evac_failure_regions) : _g1h(G1CollectedHeap::heap()), _worker_id(worker_id), - _evac_failure_regions(evac_failure_regions) { + _evac_failure_regions(evac_failure_regions), + _phase_times(G1CollectedHeap::heap()->phase_times()) { } size_t remove_self_forward_ptr_by_walking_hr(HeapRegion* hr, @@ -161,8 +163,11 @@ public: RemoveSelfForwardPtrObjClosure rspc(hr, during_concurrent_start, _worker_id); - // Iterates evac failure objs which are recorded during evacuation. - hr->process_and_drop_evac_failure_objs(&rspc); + + // All objects that failed evacuation has been marked in the prev bitmap. + // Use the bitmap to apply the above closure to all failing objects. + G1CMBitMap* bitmap = const_cast(_g1h->concurrent_mark()->prev_mark_bitmap()); + hr->apply_to_marked_objects(bitmap, &rspc); // Need to zap the remainder area of the processed region. rspc.zap_remainder(); @@ -172,26 +177,29 @@ public: bool do_heap_region(HeapRegion *hr) { assert(!hr->is_pinned(), "Unexpected pinned region at index %u", hr->hrm_index()); assert(hr->in_collection_set(), "bad CS"); + assert(_evac_failure_regions->contains(hr->hrm_index()), "precondition"); - if (_evac_failure_regions->contains(hr->hrm_index())) { - hr->clear_index_in_opt_cset(); + hr->clear_index_in_opt_cset(); - bool during_concurrent_start = _g1h->collector_state()->in_concurrent_start_gc(); - bool during_concurrent_mark = _g1h->collector_state()->mark_or_rebuild_in_progress(); + bool during_concurrent_start = _g1h->collector_state()->in_concurrent_start_gc(); + bool during_concurrent_mark = _g1h->collector_state()->mark_or_rebuild_in_progress(); - hr->note_self_forwarding_removal_start(during_concurrent_start, - during_concurrent_mark); - _g1h->verifier()->check_bitmaps("Self-Forwarding Ptr Removal", hr); + hr->note_self_forwarding_removal_start(during_concurrent_start, + during_concurrent_mark); - hr->reset_bot(); + _phase_times->record_or_add_thread_work_item(G1GCPhaseTimes::RestoreRetainedRegions, + _worker_id, + 1, + G1GCPhaseTimes::RestoreRetainedRegionsNum); - size_t live_bytes = remove_self_forward_ptr_by_walking_hr(hr, during_concurrent_start); + size_t live_bytes = remove_self_forward_ptr_by_walking_hr(hr, during_concurrent_start); - hr->rem_set()->clean_strong_code_roots(hr); - hr->rem_set()->clear_locked(true); + hr->rem_set()->clean_code_roots(hr); + hr->rem_set()->clear_locked(true); + + hr->note_self_forwarding_removal_end(live_bytes); + _g1h->verifier()->check_bitmaps("Self-Forwarding Ptr Removal", hr); - hr->note_self_forwarding_removal_end(live_bytes); - } return false; } }; diff --git a/src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.cpp b/src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.cpp deleted file mode 100644 index a15f8965bcbd1a25c541b218ad5421a96073a20b..0000000000000000000000000000000000000000 --- a/src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2021, Huawei and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc/g1/g1EvacFailureObjectsSet.hpp" -#include "gc/g1/g1CollectedHeap.hpp" -#include "gc/g1/g1SegmentedArray.inline.hpp" -#include "gc/g1/heapRegion.inline.hpp" -#include "utilities/quickSort.hpp" - - -const G1SegmentedArrayAllocOptions G1EvacFailureObjectsSet::_alloc_options = - G1SegmentedArrayAllocOptions((uint)sizeof(OffsetInRegion), SegmentLength, UINT_MAX, Alignment); - -G1SegmentedArrayFreeList G1EvacFailureObjectsSet::_free_segment_list; - -#ifdef ASSERT -void G1EvacFailureObjectsSet::assert_is_valid_offset(size_t offset) const { - const uint max_offset = 1u << (HeapRegion::LogOfHRGrainBytes - LogHeapWordSize); - assert(offset < max_offset, "must be, but is " SIZE_FORMAT, offset); -} -#endif - -oop G1EvacFailureObjectsSet::from_offset(OffsetInRegion offset) const { - assert_is_valid_offset(offset); - return cast_to_oop(_bottom + offset); -} - -G1EvacFailureObjectsSet::OffsetInRegion G1EvacFailureObjectsSet::to_offset(oop obj) const { - const HeapWord* o = cast_from_oop(obj); - size_t offset = pointer_delta(o, _bottom); - assert(obj == from_offset(static_cast(offset)), "must be"); - return static_cast(offset); -} - -G1EvacFailureObjectsSet::G1EvacFailureObjectsSet(uint region_idx, HeapWord* bottom) : - DEBUG_ONLY(_region_idx(region_idx) COMMA) - _bottom(bottom), - _offsets(&_alloc_options, &_free_segment_list) { - assert(HeapRegion::LogOfHRGrainBytes < 32, "must be"); -} - -// Helper class to join, sort and iterate over the previously collected segmented -// array of objects that failed evacuation. -class G1EvacFailureObjectsIterationHelper { - typedef G1EvacFailureObjectsSet::OffsetInRegion OffsetInRegion; - - G1EvacFailureObjectsSet* _objects_set; - const G1SegmentedArray* _segments; - OffsetInRegion* _offset_array; - uint _array_length; - - static int order_oop(OffsetInRegion a, OffsetInRegion b) { - return static_cast(a-b); - } - - void join_and_sort() { - _segments->iterate_segments(*this); - - QuickSort::sort(_offset_array, _array_length, order_oop, true); - } - - void iterate(ObjectClosure* closure) { - for (uint i = 0; i < _array_length; i++) { - oop cur = _objects_set->from_offset(_offset_array[i]); - closure->do_object(cur); - } - } - -public: - G1EvacFailureObjectsIterationHelper(G1EvacFailureObjectsSet* collector) : - _objects_set(collector), - _segments(&_objects_set->_offsets), - _offset_array(nullptr), - _array_length(0) { } - - void process_and_drop(ObjectClosure* closure) { - uint num = _segments->num_allocated_slots(); - _offset_array = NEW_C_HEAP_ARRAY(OffsetInRegion, num, mtGC); - - join_and_sort(); - assert(_array_length == num, "must be %u, %u", _array_length, num); - iterate(closure); - - FREE_C_HEAP_ARRAY(OffsetInRegion, _offset_array); - } - - // Callback of G1SegmentedArray::iterate_segments - void do_segment(G1SegmentedArraySegment* segment, uint length) { - segment->copy_to(&_offset_array[_array_length]); - _array_length += length; - } -}; - -void G1EvacFailureObjectsSet::process_and_drop(ObjectClosure* closure) { - assert_at_safepoint(); - - G1EvacFailureObjectsIterationHelper helper(this); - helper.process_and_drop(closure); - - _offsets.drop_all(); -} diff --git a/src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.hpp b/src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.hpp deleted file mode 100644 index a2628807ee1c921956e49184e0cd545d9237c567..0000000000000000000000000000000000000000 --- a/src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2021, Huawei and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_G1_G1EVACFAILUREOBJECTSSET_HPP -#define SHARE_GC_G1_G1EVACFAILUREOBJECTSSET_HPP - -#include "gc/g1/g1SegmentedArray.hpp" -#include "memory/iterator.hpp" -#include "oops/oop.hpp" - -class G1EvacFailureObjectsIterationHelper; - -// This class collects addresses of objects that failed evacuation in a specific -// heap region. -// Provides sorted iteration of these objects for processing during the remove -// self forwards phase. -class G1EvacFailureObjectsSet { - friend class G1EvacFailureObjectsIterationHelper; - -public: - // Storage type of an object that failed evacuation within a region. Given - // heap region size and possible object locations within a region, it is - // sufficient to use an uint here to save some space instead of full pointers. - typedef uint OffsetInRegion; - -private: - static const uint SegmentLength = 256; - static const uint Alignment = 4; - - static const G1SegmentedArrayAllocOptions _alloc_options; - - // This free list is shared among evacuation failure process in all regions. - static G1SegmentedArrayFreeList _free_segment_list; - - DEBUG_ONLY(const uint _region_idx;) - - // Region bottom - const HeapWord* _bottom; - - // Offsets within region containing objects that failed evacuation. - G1SegmentedArray _offsets; - - void assert_is_valid_offset(size_t offset) const NOT_DEBUG_RETURN; - // Converts between an offset within a region and an oop address. - oop from_offset(OffsetInRegion offset) const; - OffsetInRegion to_offset(oop obj) const; - -public: - G1EvacFailureObjectsSet(uint region_idx, HeapWord* bottom); - - // Record an object that failed evacuation. - inline void record(oop obj); - - // Apply the given ObjectClosure to all objects that failed evacuation and - // empties the list after processing. - // Objects are passed in increasing address order. - void process_and_drop(ObjectClosure* closure); -}; - - -#endif //SHARE_GC_G1_G1EVACFAILUREOBJECTSSET_HPP diff --git a/src/hotspot/share/gc/g1/g1FromCardCache.hpp b/src/hotspot/share/gc/g1/g1FromCardCache.hpp index b76d7b1b8633401ed719504a01779096c7a7b7ef..0a01e0102aed3e1b497bd6dbbd55c89018943f1a 100644 --- a/src/hotspot/share/gc/g1/g1FromCardCache.hpp +++ b/src/hotspot/share/gc/g1/g1FromCardCache.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_G1_G1FROMCARDCACHE_HPP #define SHARE_GC_G1_G1FROMCARDCACHE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/ostream.hpp" // G1FromCardCache remembers the most recently processed card on the heap on diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 603b381802903c1ff317cdd062b9f811b68b6e3a..e6e7dd25c0a612dbe7759ea4bd11e14c10224c46 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * 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 @@ #include "gc/g1/g1FullGCCompactTask.hpp" #include "gc/g1/g1FullGCMarker.inline.hpp" #include "gc/g1/g1FullGCMarkTask.hpp" -#include "gc/g1/g1FullGCPrepareTask.hpp" +#include "gc/g1/g1FullGCPrepareTask.inline.hpp" #include "gc/g1/g1FullGCScope.hpp" #include "gc/g1/g1OopClosures.hpp" #include "gc/g1/g1Policy.hpp" @@ -294,17 +294,74 @@ void G1FullCollector::phase1_mark_live_objects() { } scope()->tracer()->report_object_count_after_gc(&_is_alive); +#if TASKQUEUE_STATS + oop_queue_set()->print_and_reset_taskqueue_stats("Oop Queue"); + array_queue_set()->print_and_reset_taskqueue_stats("ObjArrayOop Queue"); +#endif } void G1FullCollector::phase2_prepare_compaction() { - GCTraceTime(Info, gc, phases) info("Phase 2: Prepare for compaction", scope()->timer()); + GCTraceTime(Info, gc, phases) info("Phase 2: Prepare compaction", scope()->timer()); + + phase2a_determine_worklists(); + + bool has_free_compaction_targets = phase2b_forward_oops(); + + // Try to avoid OOM immediately after Full GC in case there are no free regions + // left after determining the result locations (i.e. this phase). Prepare to + // maximally compact the tail regions of the compaction queues serially. + if (!has_free_compaction_targets) { + phase2c_prepare_serial_compaction(); + } +} + +void G1FullCollector::phase2a_determine_worklists() { + GCTraceTime(Debug, gc, phases) debug("Phase 2: Determine work lists", scope()->timer()); + + G1DetermineCompactionQueueClosure cl(this); + _heap->heap_region_iterate(&cl); +} + +bool G1FullCollector::phase2b_forward_oops() { + GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare parallel compaction", scope()->timer()); + G1FullGCPrepareTask task(this); run_task(&task); - // To avoid OOM when there is memory left. - if (!task.has_freed_regions()) { - task.prepare_serial_compaction(); + return task.has_free_compaction_targets(); +} + +void G1FullCollector::phase2c_prepare_serial_compaction() { + GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare serial compaction", scope()->timer()); + // At this point we know that after parallel compaction there will be no + // completely free regions. That means that the last region of + // all compaction queues still have data in them. We try to compact + // these regions in serial to avoid a premature OOM when the mutator wants + // to allocate the first eden region after gc. + for (uint i = 0; i < workers(); i++) { + G1FullGCCompactionPoint* cp = compaction_point(i); + if (cp->has_regions()) { + serial_compaction_point()->add(cp->remove_last()); + } + } + + // Update the forwarding information for the regions in the serial + // compaction point. + G1FullGCCompactionPoint* cp = serial_compaction_point(); + for (GrowableArrayIterator it = cp->regions()->begin(); it != cp->regions()->end(); ++it) { + HeapRegion* current = *it; + if (!cp->is_initialized()) { + // Initialize the compaction point. Nothing more is needed for the first heap region + // since it is already prepared for compaction. + cp->initialize(current); + } else { + assert(!current->is_humongous(), "Should be no humongous regions in compaction queue"); + G1SerialRePrepareClosure re_prepare(cp, current); + current->set_compaction_top(current->bottom()); + current->apply_to_marked_objects(mark_bitmap(), &re_prepare); + } } + cp->update(); } void G1FullCollector::phase3_adjust_pointers() { diff --git a/src/hotspot/share/gc/g1/g1FullCollector.hpp b/src/hotspot/share/gc/g1/g1FullCollector.hpp index c4d019629dd89d8738ccd514439aa474f36f9cc6..f9087298b86003f8455024c7a9c56fc63cf41a88 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -110,7 +110,7 @@ public: G1FullGCCompactionPoint* serial_compaction_point() { return &_serial_compaction_point; } G1CMBitMap* mark_bitmap(); ReferenceProcessor* reference_processor(); - size_t live_words(uint region_index) { + size_t live_words(uint region_index) const { assert(region_index < _heap->max_regions(), "sanity"); return _live_stats[region_index]._live_words; } @@ -121,6 +121,9 @@ public: inline bool is_skip_compacting(uint region_index) const; inline bool is_skip_marking(oop obj) const; + // Are we (potentially) going to compact into this region? + inline bool is_compaction_target(uint region_index) const; + inline void set_free(uint region_idx); inline bool is_free(uint region_idx) const; inline void update_from_compacting_to_skip_compacting(uint region_idx); @@ -128,6 +131,11 @@ public: private: void phase1_mark_live_objects(); void phase2_prepare_compaction(); + + void phase2a_determine_worklists(); + bool phase2b_forward_oops(); + void phase2c_prepare_serial_compaction(); + void phase3_adjust_pointers(); void phase4_do_compaction(); diff --git a/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp b/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp index 5a0863b202a07a8131091de6bfafd949cb03dcd0..37e16fc6f78b9b0a512c3d5255283ae23f9d391d 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,10 @@ bool G1FullCollector::is_skip_marking(oop obj) const { return _region_attr_table.is_skip_marking(cast_from_oop(obj)); } +bool G1FullCollector::is_compaction_target(uint region_index) const { + return _region_attr_table.is_compacting(region_index) || is_free(region_index); +} + void G1FullCollector::set_free(uint region_idx) { _region_attr_table.set_free(region_idx); } diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp index 2ccda820fb0245891870200e0d4b8739206a0f44..f484ee5133c7007f793b74a57e3edc851cbc8356 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp @@ -46,22 +46,38 @@ public: uint region_index = r->hrm_index(); // Only for skip-compaction regions; early return otherwise. if (!_collector->is_skip_compacting(region_index)) { - return false; } - assert(_collector->live_words(region_index) > _collector->scope()->region_compaction_threshold() || - !r->is_starts_humongous() || - _collector->mark_bitmap()->is_marked(cast_to_oop(r->bottom())), - "must be, otherwise reclaimed earlier"); +#ifdef ASSERT + if (r->is_humongous()) { + oop obj = cast_to_oop(r->humongous_start_region()->bottom()); + assert(_collector->mark_bitmap()->is_marked(obj), "must be live"); + } else if (r->is_open_archive()) { + bool is_empty = (_collector->live_words(r->hrm_index()) == 0); + assert(!is_empty, "should contain at least one live obj"); + } else if (r->is_closed_archive()) { + // should early-return above + ShouldNotReachHere(); + } else { + assert(_collector->live_words(region_index) > _collector->scope()->region_compaction_threshold(), + "should be quite full"); + } +#endif r->reset_skip_compacting_after_full_gc(); return false; } }; +void G1FullGCCompactTask::G1CompactRegionClosure::clear_in_prev_bitmap(oop obj) { + assert(_bitmap->is_marked(obj), "Should only compact marked objects"); + _bitmap->clear(obj); +} + size_t G1FullGCCompactTask::G1CompactRegionClosure::apply(oop obj) { size_t size = obj->size(); if (!obj->is_forwarded()) { - // Object not moving + // Object not moving, but clear the mark to allow reuse of the bitmap. + clear_in_prev_bitmap(obj); return size; } @@ -74,6 +90,9 @@ size_t G1FullGCCompactTask::G1CompactRegionClosure::apply(oop obj) { cast_to_oop(destination)->init_mark(); assert(cast_to_oop(destination)->klass() != NULL, "should have a class"); + // Clear the mark for the compacted object to allow reuse of the + // bitmap without an additional clearing step. + clear_in_prev_bitmap(obj); return size; } @@ -82,13 +101,15 @@ void G1FullGCCompactTask::compact_region(HeapRegion* hr) { assert(!hr->is_humongous(), "Should be no humongous regions in compaction queue"); if (!collector()->is_free(hr->hrm_index())) { + // The compaction closure not only copies the object to the new + // location, but also clears the bitmap for it. This is needed + // for bitmap verification and to be able to use the prev_bitmap + // for evacuation failures in the next young collection. Testing + // showed that it was better overall to clear bit by bit, compared + // to clearing the whole region at the end. This difference was + // clearly seen for regions with few marks. G1CompactRegionClosure compact(collector()->mark_bitmap()); hr->apply_to_marked_objects(collector()->mark_bitmap(), &compact); - // Clear the liveness information for this region if necessary i.e. if we actually look at it - // for bitmap verification. Otherwise it is sufficient that we move the TAMS to bottom(). - if (G1VerifyBitmaps) { - collector()->mark_bitmap()->clear_region(hr); - } } hr->reset_compacted_after_full_gc(); diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactTask.hpp b/src/hotspot/share/gc/g1/g1FullGCCompactTask.hpp index 5f96796accadc4b2fff82bd550cf125f44faf8e6..936980b98056379d4b26e41e0499d79a53fc8d07 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactTask.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.hpp @@ -50,7 +50,7 @@ public: class G1CompactRegionClosure : public StackObj { G1CMBitMap* _bitmap; - + void clear_in_prev_bitmap(oop object); public: G1CompactRegionClosure(G1CMBitMap* bitmap) : _bitmap(bitmap) { } size_t apply(oop object); diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp index 25ff38da77fd653e29e89197466d59b6b839e8d8..0e7543ec63d9b3117a8838ebbc8fe7d46a3f6ba8 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp @@ -45,11 +45,8 @@ void G1FullGCCompactionPoint::update() { } } -void G1FullGCCompactionPoint::initialize_values(bool init_threshold) { +void G1FullGCCompactionPoint::initialize_values() { _compaction_top = _current_region->compaction_top(); - if (init_threshold) { - _current_region->initialize_bot_threshold(); - } } bool G1FullGCCompactionPoint::has_regions() { @@ -60,9 +57,9 @@ bool G1FullGCCompactionPoint::is_initialized() { return _current_region != NULL; } -void G1FullGCCompactionPoint::initialize(HeapRegion* hr, bool init_threshold) { +void G1FullGCCompactionPoint::initialize(HeapRegion* hr) { _current_region = hr; - initialize_values(init_threshold); + initialize_values(); } HeapRegion* G1FullGCCompactionPoint::current_region() { @@ -89,7 +86,7 @@ void G1FullGCCompactionPoint::switch_region() { _current_region->set_compaction_top(_compaction_top); // Get the next region and re-initialize the values. _current_region = next_region(); - initialize_values(true); + initialize_values(); } void G1FullGCCompactionPoint::forward(oop object, size_t size) { diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp index 21bb75ee2e97ad8489eecae20541e1f1a7a3391a..41a9783a07c2a022c87f2815ce38bb1dfeae5364 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp @@ -38,7 +38,7 @@ class G1FullGCCompactionPoint : public CHeapObj { GrowableArrayIterator _compaction_region_iterator; bool object_will_fit(size_t size); - void initialize_values(bool init_threshold); + void initialize_values(); void switch_region(); HeapRegion* next_region(); @@ -48,7 +48,7 @@ public: bool has_regions(); bool is_initialized(); - void initialize(HeapRegion* hr, bool init_threshold); + void initialize(HeapRegion* hr); void update(); void forward(oop object, size_t size); void add(HeapRegion* hr); diff --git a/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp b/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp index ca2f970edde55f0eaf7ff136d89d30343286a454..017877785f41e3dbd9004173697117eff5c87c7a 100644 --- a/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,6 +70,10 @@ public: return get_by_address(obj) == Compacting; } + bool is_compacting(uint idx) const { + return get_by_index(idx) == Compacting; + } + bool is_skip_compacting(uint idx) const { return get_by_index(idx) == SkipCompacting; } diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.cpp b/src/hotspot/share/gc/g1/g1FullGCMarker.cpp index 2e2773c54dd0f672ef6f36b365ad27902f4e1e4e..bf0b49dd8283a15ec672c863677ed86ecd6af4d2 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.cpp @@ -45,7 +45,6 @@ G1FullGCMarker::G1FullGCMarker(G1FullCollector* collector, _stack_closure(this), _cld_closure(mark_closure(), ClassLoaderData::_claim_strong), _mark_stats_cache(mark_stats, G1RegionMarkStatsCache::RegionMarkStatsCacheSize) { - _mark_stats_cache.reset(); } G1FullGCMarker::~G1FullGCMarker() { diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.hpp b/src/hotspot/share/gc/g1/g1FullGCMarker.hpp index ec7f029b7cee72ae6a4ec460c84197c241bd0618..2d935d863c5debe86f7fab6b57215ba20a2cc4a5 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,8 +71,6 @@ class G1FullGCMarker : public CHeapObj { G1RegionMarkStatsCache _mark_stats_cache; inline bool is_empty(); - inline bool pop_object(oop& obj); - inline bool pop_objarray(ObjArrayTask& array); inline void push_objarray(oop obj, size_t index); inline bool mark_object(oop obj); @@ -80,6 +78,14 @@ class G1FullGCMarker : public CHeapObj { inline void follow_object(oop obj); inline void follow_array(objArrayOop array); inline void follow_array_chunk(objArrayOop array, int index); + + inline void drain_oop_stack(); + // Transfer contents from the objArray task queue overflow stack to the shared + // objArray stack. + // Returns true and a valid task if there has not been enough space in the shared + // objArray stack, otherwise the task is invalid. + inline bool transfer_objArray_overflow_stack(ObjArrayTask& task); + public: G1FullGCMarker(G1FullCollector* collector, uint worker_id, diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp index 3ef6375c3a4b54816223af5f31d9832c5c2cd949..a68bae5ced64f934b6bb7f5c22d67bc1bf81eae4 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,12 +54,10 @@ inline bool G1FullGCMarker::mark_object(oop obj) { } // Marked by us, preserve if needed. - markWord mark = obj->mark(); - if (obj->mark_must_be_preserved(mark) && - // It is not necessary to preserve marks for objects in regions we do not - // compact because we do not change their headers (i.e. forward them). - _collector->is_compacting(obj)) { - preserved_stack()->push(obj, mark); + if (_collector->is_compacting(obj)) { + // It is not necessary to preserve marks for objects in regions we do not + // compact because we do not change their headers (i.e. forward them). + preserved_stack()->push_if_necessary(obj, obj->mark()); } // Check if deduplicatable string. @@ -93,20 +91,12 @@ inline bool G1FullGCMarker::is_empty() { return _oop_stack.is_empty() && _objarray_stack.is_empty(); } -inline bool G1FullGCMarker::pop_object(oop& oop) { - return _oop_stack.pop_overflow(oop) || _oop_stack.pop_local(oop); -} - inline void G1FullGCMarker::push_objarray(oop obj, size_t index) { ObjArrayTask task(obj, index); assert(task.is_valid(), "bad ObjArrayTask"); _objarray_stack.push(task); } -inline bool G1FullGCMarker::pop_objarray(ObjArrayTask& arr) { - return _objarray_stack.pop_overflow(arr) || _objarray_stack.pop_local(arr); -} - inline void G1FullGCMarker::follow_array(objArrayOop array) { follow_klass(array->klass()); // Don't push empty arrays to avoid unnecessary work. @@ -161,16 +151,40 @@ inline void G1FullGCMarker::follow_object(oop obj) { } } -void G1FullGCMarker::drain_stack() { - do { - oop obj; - while (pop_object(obj)) { +inline void G1FullGCMarker::drain_oop_stack() { + oop obj; + while (_oop_stack.pop_overflow(obj)) { + if (!_oop_stack.try_push_to_taskqueue(obj)) { assert(_bitmap->is_marked(obj), "must be marked"); follow_object(obj); } - // Process ObjArrays one at a time to avoid marking stack bloat. + } + while (_oop_stack.pop_local(obj)) { + assert(_bitmap->is_marked(obj), "must be marked"); + follow_object(obj); + } +} + +inline bool G1FullGCMarker::transfer_objArray_overflow_stack(ObjArrayTask& task) { + // It is desirable to move as much as possible work from the overflow queue to + // the shared queue as quickly as possible. + while (_objarray_stack.pop_overflow(task)) { + if (!_objarray_stack.try_push_to_taskqueue(task)) { + return true; + } + } + return false; +} + +void G1FullGCMarker::drain_stack() { + do { + // First, drain regular oop stack. + drain_oop_stack(); + + // Then process ObjArrays one at a time to avoid marking stack bloat. ObjArrayTask task; - if (pop_objarray(task)) { + if (transfer_objArray_overflow_stack(task) || + _objarray_stack.pop_local(task)) { follow_array_chunk(objArrayOop(task.obj()), task.index()); } } while (!is_empty()); diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp index ea7f94880c429fa27c668e73d25f1a97bccb058d..4ffe9329dc754a359281103b452f1b700b8a8c38 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * 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,13 +23,13 @@ */ #include "precompiled.hpp" -#include "gc/g1/g1CollectedHeap.hpp" +#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp" #include "gc/g1/g1FullCollector.inline.hpp" #include "gc/g1/g1FullGCCompactionPoint.hpp" #include "gc/g1/g1FullGCMarker.hpp" #include "gc/g1/g1FullGCOopClosures.inline.hpp" -#include "gc/g1/g1FullGCPrepareTask.hpp" +#include "gc/g1/g1FullGCPrepareTask.inline.hpp" #include "gc/g1/g1HotCardCache.hpp" #include "gc/g1/heapRegion.inline.hpp" #include "gc/shared/gcTraceTime.inline.hpp" @@ -39,114 +39,84 @@ #include "oops/oop.inline.hpp" #include "utilities/ticks.hpp" -template -void G1FullGCPrepareTask::G1CalculatePointersClosure::free_pinned_region(HeapRegion* hr) { - _regions_freed = true; - if (is_humongous) { - _g1h->free_humongous_region(hr, nullptr); - } else { - _g1h->free_region(hr, nullptr); - } - _collector->set_free(hr->hrm_index()); - prepare_for_compaction(hr); -} +G1DetermineCompactionQueueClosure::G1DetermineCompactionQueueClosure(G1FullCollector* collector) : + _g1h(G1CollectedHeap::heap()), + _collector(collector), + _cur_worker(0) { } bool G1FullGCPrepareTask::G1CalculatePointersClosure::do_heap_region(HeapRegion* hr) { - bool force_not_compacted = false; - if (should_compact(hr)) { - assert(!hr->is_humongous(), "moving humongous objects not supported."); - prepare_for_compaction(hr); - } else { - // There is no need to iterate and forward objects in pinned regions ie. - // prepare them for compaction. The adjust pointers phase will skip - // work for them. - assert(hr->containing_set() == nullptr, "already cleared by PrepareRegionsClosure"); - if (hr->is_humongous()) { - oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); - if (!_bitmap->is_marked(obj)) { - free_pinned_region(hr); - } - } else if (hr->is_open_archive()) { - bool is_empty = _collector->live_words(hr->hrm_index()) == 0; - if (is_empty) { - free_pinned_region(hr); - } - } else if (hr->is_closed_archive()) { - // nothing to do with closed archive region - } else { - assert(MarkSweepDeadRatio > 0, - "only skip compaction for other regions when MarkSweepDeadRatio > 0"); - - // Too many live objects; skip compacting it. - _collector->update_from_compacting_to_skip_compacting(hr->hrm_index()); - if (hr->is_young()) { - // G1 updates the BOT for old region contents incrementally, but young regions - // lack BOT information for performance reasons. - // Recreate BOT information of high live ratio young regions here to keep expected - // performance during scanning their card tables in the collection pauses later. - hr->update_bot(); - } - log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT, - hr->hrm_index(), _collector->live_words(hr->hrm_index())); - } - } + uint region_idx = hr->hrm_index(); + assert(_collector->is_compaction_target(region_idx), "must be"); - // Reset data structures not valid after Full GC. - reset_region_metadata(hr); + assert(!hr->is_pinned(), "must be"); + assert(!hr->is_closed_archive(), "must be"); + assert(!hr->is_open_archive(), "must be"); + + prepare_for_compaction(hr); return false; } G1FullGCPrepareTask::G1FullGCPrepareTask(G1FullCollector* collector) : G1FullGCTask("G1 Prepare Compact Task", collector), - _freed_regions(false), + _has_free_compaction_targets(false), _hrclaimer(collector->workers()) { } -void G1FullGCPrepareTask::set_freed_regions() { - if (!_freed_regions) { - _freed_regions = true; +void G1FullGCPrepareTask::set_has_free_compaction_targets() { + if (!_has_free_compaction_targets) { + _has_free_compaction_targets = true; } } -bool G1FullGCPrepareTask::has_freed_regions() { - return _freed_regions; +bool G1FullGCPrepareTask::has_free_compaction_targets() { + return _has_free_compaction_targets; } void G1FullGCPrepareTask::work(uint worker_id) { Ticks start = Ticks::now(); - G1FullGCCompactionPoint* compaction_point = collector()->compaction_point(worker_id); - G1CalculatePointersClosure closure(collector(), compaction_point); - G1CollectedHeap::heap()->heap_region_par_iterate_from_start(&closure, &_hrclaimer); - - compaction_point->update(); + // Calculate the target locations for the objects in the non-free regions of + // the compaction queues provided by the associate compaction point. + { + G1FullGCCompactionPoint* compaction_point = collector()->compaction_point(worker_id); + G1CalculatePointersClosure closure(collector(), compaction_point); + + for (GrowableArrayIterator it = compaction_point->regions()->begin(); + it != compaction_point->regions()->end(); + ++it) { + closure.do_heap_region(*it); + } + compaction_point->update(); + // Determine if there are any unused compaction targets. This is only the case if + // there are + // - any regions in queue, so no free ones either. + // - and the current region is not the last one in the list. + if (compaction_point->has_regions() && + compaction_point->current_region() != compaction_point->regions()->last()) { + set_has_free_compaction_targets(); + } + } - // Check if any regions was freed by this worker and store in task. - if (closure.freed_regions()) { - set_freed_regions(); + // Clear region metadata that is invalid after GC for all regions. + { + G1ResetMetadataClosure closure(collector()); + G1CollectedHeap::heap()->heap_region_par_iterate_from_start(&closure, &_hrclaimer); } log_task("Prepare compaction task", worker_id, start); } G1FullGCPrepareTask::G1CalculatePointersClosure::G1CalculatePointersClosure(G1FullCollector* collector, G1FullGCCompactionPoint* cp) : - _g1h(G1CollectedHeap::heap()), - _collector(collector), - _bitmap(collector->mark_bitmap()), - _cp(cp), - _regions_freed(false) { } - -bool G1FullGCPrepareTask::G1CalculatePointersClosure::should_compact(HeapRegion* hr) { - if (hr->is_pinned()) { - return false; - } - size_t live_words = _collector->live_words(hr->hrm_index()); - size_t live_words_threshold = _collector->scope()->region_compaction_threshold(); - // High live ratio region will not be compacted. - return live_words <= live_words_threshold; -} + _g1h(G1CollectedHeap::heap()), + _collector(collector), + _bitmap(collector->mark_bitmap()), + _cp(cp) { } -void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(HeapRegion* hr) { +G1FullGCPrepareTask::G1ResetMetadataClosure::G1ResetMetadataClosure(G1FullCollector* collector) : + _g1h(G1CollectedHeap::heap()), + _collector(collector) { } + +void G1FullGCPrepareTask::G1ResetMetadataClosure::reset_region_metadata(HeapRegion* hr) { hr->rem_set()->clear(); hr->clear_cardtable(); @@ -156,6 +126,26 @@ void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(Heap } } +bool G1FullGCPrepareTask::G1ResetMetadataClosure::do_heap_region(HeapRegion* hr) { + uint const region_idx = hr->hrm_index(); + if (!_collector->is_compaction_target(region_idx)) { + assert(!hr->is_free(), "all free regions should be compaction targets"); + assert(_collector->is_skip_compacting(region_idx) || hr->is_closed_archive(), "must be"); + if (hr->is_young()) { + // G1 updates the BOT for old region contents incrementally, but young regions + // lack BOT information for performance reasons. + // Recreate BOT information of high live ratio young regions here to keep expected + // performance during scanning their card tables in the collection pauses later. + hr->update_bot(); + } + } + + // Reset data structures not valid after Full GC. + reset_region_metadata(hr); + + return false; +} + G1FullGCPrepareTask::G1PrepareCompactLiveClosure::G1PrepareCompactLiveClosure(G1FullGCCompactionPoint* cp) : _cp(cp) { } @@ -165,87 +155,9 @@ size_t G1FullGCPrepareTask::G1PrepareCompactLiveClosure::apply(oop object) { return size; } -size_t G1FullGCPrepareTask::G1RePrepareClosure::apply(oop obj) { - // We only re-prepare objects forwarded within the current region, so - // skip objects that are already forwarded to another region. - if (obj->is_forwarded() && !_current->is_in(obj->forwardee())) { - return obj->size(); - } - - // Get size and forward. - size_t size = obj->size(); - _cp->forward(obj, size); - - return size; -} - -void G1FullGCPrepareTask::G1CalculatePointersClosure::prepare_for_compaction_work(G1FullGCCompactionPoint* cp, - HeapRegion* hr) { - hr->set_compaction_top(hr->bottom()); +void G1FullGCPrepareTask::G1CalculatePointersClosure::prepare_for_compaction(HeapRegion* hr) { if (!_collector->is_free(hr->hrm_index())) { - G1PrepareCompactLiveClosure prepare_compact(cp); + G1PrepareCompactLiveClosure prepare_compact(_cp); hr->apply_to_marked_objects(_bitmap, &prepare_compact); } } - -void G1FullGCPrepareTask::G1CalculatePointersClosure::prepare_for_compaction(HeapRegion* hr) { - if (!_cp->is_initialized()) { - hr->set_compaction_top(hr->bottom()); - _cp->initialize(hr, true); - } - // Add region to the compaction queue and prepare it. - _cp->add(hr); - prepare_for_compaction_work(_cp, hr); -} - -void G1FullGCPrepareTask::prepare_serial_compaction() { - GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare Serial Compaction", collector()->scope()->timer()); - // At this point we know that no regions were completely freed by - // the parallel compaction. That means that the last region of - // all compaction queues still have data in them. We try to compact - // these regions in serial to avoid a premature OOM. - for (uint i = 0; i < collector()->workers(); i++) { - G1FullGCCompactionPoint* cp = collector()->compaction_point(i); - if (cp->has_regions()) { - collector()->serial_compaction_point()->add(cp->remove_last()); - } - } - - // Update the forwarding information for the regions in the serial - // compaction point. - G1FullGCCompactionPoint* cp = collector()->serial_compaction_point(); - for (GrowableArrayIterator it = cp->regions()->begin(); it != cp->regions()->end(); ++it) { - HeapRegion* current = *it; - if (!cp->is_initialized()) { - // Initialize the compaction point. Nothing more is needed for the first heap region - // since it is already prepared for compaction. - cp->initialize(current, false); - } else { - assert(!current->is_humongous(), "Should be no humongous regions in compaction queue"); - G1RePrepareClosure re_prepare(cp, current); - current->set_compaction_top(current->bottom()); - current->apply_to_marked_objects(collector()->mark_bitmap(), &re_prepare); - } - } - cp->update(); -} - -bool G1FullGCPrepareTask::G1CalculatePointersClosure::freed_regions() { - if (_regions_freed) { - return true; - } - - if (!_cp->has_regions()) { - // No regions in queue, so no free ones either. - return false; - } - - if (_cp->current_region() != _cp->regions()->last()) { - // The current region used for compaction is not the last in the - // queue. That means there is at least one free region in the queue. - return true; - } - - // No free regions in the queue. - return false; -} diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp index d694fc6ffcaf66fe13536561903eafbb6bfad658..41c0c67d87cf66482933081a88b11775a57c85f3 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,53 +25,81 @@ #ifndef SHARE_GC_G1_G1FULLGCPREPARETASK_HPP #define SHARE_GC_G1_G1FULLGCPREPARETASK_HPP -#include "gc/g1/g1FullGCCompactionPoint.hpp" -#include "gc/g1/g1FullGCScope.hpp" #include "gc/g1/g1FullGCTask.hpp" -#include "gc/g1/g1RootProcessor.hpp" -#include "gc/g1/heapRegionManager.hpp" -#include "gc/shared/referenceProcessor.hpp" +#include "gc/g1/heapRegion.hpp" +#include "memory/allocation.hpp" +class G1CollectedHeap; class G1CMBitMap; class G1FullCollector; +class G1FullGCCompactionPoint; +class HeapRegion; + +// Determines the regions in the heap that should be part of the compaction and +// distributes them among the compaction queues in round-robin fashion. +class G1DetermineCompactionQueueClosure : public HeapRegionClosure { + G1CollectedHeap* _g1h; + G1FullCollector* _collector; + uint _cur_worker; + + template + inline void free_pinned_region(HeapRegion* hr); + + inline bool should_compact(HeapRegion* hr) const; + + // Returns the current worker id to assign a compaction point to, and selects + // the next one round-robin style. + inline uint next_worker(); + + inline G1FullGCCompactionPoint* next_compaction_point(); + + inline void add_to_compaction_queue(HeapRegion* hr); + +public: + G1DetermineCompactionQueueClosure(G1FullCollector* collector); + + inline bool do_heap_region(HeapRegion* hr) override; +}; class G1FullGCPrepareTask : public G1FullGCTask { -protected: - volatile bool _freed_regions; + volatile bool _has_free_compaction_targets; HeapRegionClaimer _hrclaimer; - void set_freed_regions(); + void set_has_free_compaction_targets(); public: G1FullGCPrepareTask(G1FullCollector* collector); void work(uint worker_id); - void prepare_serial_compaction(); - bool has_freed_regions(); + // After the Prepare phase, are there any unused (empty) regions (compaction + // targets) at the end of any compaction queues? + bool has_free_compaction_targets(); -protected: +private: class G1CalculatePointersClosure : public HeapRegionClosure { - private: - template - void free_pinned_region(HeapRegion* hr); - protected: G1CollectedHeap* _g1h; G1FullCollector* _collector; G1CMBitMap* _bitmap; G1FullGCCompactionPoint* _cp; - bool _regions_freed; - bool should_compact(HeapRegion* hr); void prepare_for_compaction(HeapRegion* hr); - void prepare_for_compaction_work(G1FullGCCompactionPoint* cp, HeapRegion* hr); - - void reset_region_metadata(HeapRegion* hr); public: G1CalculatePointersClosure(G1FullCollector* collector, G1FullGCCompactionPoint* cp); bool do_heap_region(HeapRegion* hr); - bool freed_regions(); + }; + + class G1ResetMetadataClosure : public HeapRegionClosure { + G1CollectedHeap* _g1h; + G1FullCollector* _collector; + + void reset_region_metadata(HeapRegion* hr); + + public: + G1ResetMetadataClosure(G1FullCollector* collector); + + bool do_heap_region(HeapRegion* hr); }; class G1PrepareCompactLiveClosure : public StackObj { @@ -81,19 +109,20 @@ protected: G1PrepareCompactLiveClosure(G1FullGCCompactionPoint* cp); size_t apply(oop object); }; +}; - class G1RePrepareClosure : public StackObj { - G1FullGCCompactionPoint* _cp; - HeapRegion* _current; +// Closure to re-prepare objects in the serial compaction point queue regions for +// serial compaction. +class G1SerialRePrepareClosure : public StackObj { + G1FullGCCompactionPoint* _cp; + HeapRegion* _current; - public: - G1RePrepareClosure(G1FullGCCompactionPoint* hrcp, - HeapRegion* hr) : - _cp(hrcp), - _current(hr) { } +public: + G1SerialRePrepareClosure(G1FullGCCompactionPoint* hrcp, HeapRegion* hr) : + _cp(hrcp), + _current(hr) { } - size_t apply(oop object); - }; + inline size_t apply(oop obj); }; #endif // SHARE_GC_G1_G1FULLGCPREPARETASK_HPP diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a5807c33c37c0b63c293ebe0f2d3185a8958116b --- /dev/null +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_G1_G1FULLGCPREPARETASK_INLINE_HPP +#define SHARE_GC_G1_G1FULLGCPREPARETASK_INLINE_HPP + +#include "gc/g1/g1FullGCPrepareTask.hpp" + +#include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1FullCollector.hpp" +#include "gc/g1/g1FullGCCompactionPoint.hpp" +#include "gc/g1/g1FullGCScope.hpp" +#include "gc/g1/heapRegion.inline.hpp" + +template +void G1DetermineCompactionQueueClosure::free_pinned_region(HeapRegion* hr) { + if (is_humongous) { + _g1h->free_humongous_region(hr, nullptr); + } else { + _g1h->free_region(hr, nullptr); + } + _collector->set_free(hr->hrm_index()); + add_to_compaction_queue(hr); +} + +inline bool G1DetermineCompactionQueueClosure::should_compact(HeapRegion* hr) const { + // There is no need to iterate and forward objects in pinned regions ie. + // prepare them for compaction. + if (hr->is_pinned()) { + return false; + } + size_t live_words = _collector->live_words(hr->hrm_index()); + size_t live_words_threshold = _collector->scope()->region_compaction_threshold(); + // High live ratio region will not be compacted. + return live_words <= live_words_threshold; +} + +inline uint G1DetermineCompactionQueueClosure::next_worker() { + uint result = _cur_worker; + _cur_worker = (_cur_worker + 1) % _collector->workers(); + return result; +} + +inline G1FullGCCompactionPoint* G1DetermineCompactionQueueClosure::next_compaction_point() { + return _collector->compaction_point(next_worker()); +} + +inline void G1DetermineCompactionQueueClosure::add_to_compaction_queue(HeapRegion* hr) { + hr->set_compaction_top(hr->bottom()); + G1FullGCCompactionPoint* cp = next_compaction_point(); + if (!cp->is_initialized()) { + cp->initialize(hr); + } + // Add region to the compaction queue. + cp->add(hr); +} + +inline bool G1DetermineCompactionQueueClosure::do_heap_region(HeapRegion* hr) { + if (should_compact(hr)) { + assert(!hr->is_humongous(), "moving humongous objects not supported."); + add_to_compaction_queue(hr); + } else { + assert(hr->containing_set() == nullptr, "already cleared by PrepareRegionsClosure"); + if (hr->is_humongous()) { + oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); + bool is_empty = !_collector->mark_bitmap()->is_marked(obj); + if (is_empty) { + free_pinned_region(hr); + } + } else if (hr->is_open_archive()) { + bool is_empty = _collector->live_words(hr->hrm_index()) == 0; + if (is_empty) { + free_pinned_region(hr); + } + } else if (hr->is_closed_archive()) { + // nothing to do with closed archive region + } else { + assert(MarkSweepDeadRatio > 0, + "only skip compaction for other regions when MarkSweepDeadRatio > 0"); + + // Too many live objects in the region; skip compacting it. + _collector->update_from_compacting_to_skip_compacting(hr->hrm_index()); + log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT, + hr->hrm_index(), _collector->live_words(hr->hrm_index())); + } + } + + return false; +} + +inline size_t G1SerialRePrepareClosure::apply(oop obj) { + // We only re-prepare objects forwarded within the current region, so + // skip objects that are already forwarded to another region. + if (obj->is_forwarded() && !_current->is_in(obj->forwardee())) { + return obj->size(); + } + + // Get size and forward. + size_t size = obj->size(); + _cp->forward(obj, size); + + return size; +} + +#endif // SHARE_GC_G1_G1FULLGCPREPARETASK_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.cpp b/src/hotspot/share/gc/g1/g1FullGCScope.cpp index b4d3b3656034b5bc7cd6b3567494d25bfb9b0191..0437d157eb008aaa3d271393820798ae32a4e5de 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,6 +70,6 @@ G1FullGCTracer* G1FullGCScope::tracer() { return &_tracer; } -size_t G1FullGCScope::region_compaction_threshold() { +size_t G1FullGCScope::region_compaction_threshold() const { return _region_compaction_threshold; } diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.hpp b/src/hotspot/share/gc/g1/g1FullGCScope.hpp index c0035b9052aa7e8136e3ef825f739629e6caeeb1..a6e079f4d63dde8ccc7dbd9207bf2218bf4ac6b4 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,7 @@ public: STWGCTimer* timer(); G1FullGCTracer* tracer(); G1HeapTransition* heap_transition(); - size_t region_compaction_threshold(); + size_t region_compaction_threshold() const; }; #endif // SHARE_GC_G1_G1FULLGCSCOPE_HPP diff --git a/src/hotspot/share/gc/g1/g1GCParPhaseTimesTracker.hpp b/src/hotspot/share/gc/g1/g1GCParPhaseTimesTracker.hpp index 11a62b03825ee34b9e724287836d95ad6028a514..af626e99fd413566e70c5715b730e6e1842e6017 100644 --- a/src/hotspot/share/gc/g1/g1GCParPhaseTimesTracker.hpp +++ b/src/hotspot/share/gc/g1/g1GCParPhaseTimesTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,10 +36,10 @@ protected: G1GCPhaseTimes* _phase_times; uint _worker_id; EventGCPhaseParallel _event; - bool _must_record; + bool _allow_multiple_record; public: - G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record = true); + G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool allow_multiple_record = false); virtual ~G1GCParPhaseTimesTracker(); }; diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp index 7c3eba2be94b0f29592a56aaa43178b3761c31fc..4a45a3eca651b5a09e982c4abc5a500b66648fe3 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp @@ -102,7 +102,7 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) : _gc_par_phases[GCWorkerEnd] = new WorkerDataArray("GCWorkerEnd", "GC Worker End (ms):", max_gc_threads); _gc_par_phases[Other] = new WorkerDataArray("Other", "GC Worker Other (ms):", max_gc_threads); _gc_par_phases[MergePSS] = new WorkerDataArray("MergePSS", "Merge Per-Thread State (ms):", max_gc_threads); - _gc_par_phases[RemoveSelfForwardingPtr] = new WorkerDataArray("RemoveSelfForwardingPtr", "Remove Self Forwards (ms):", max_gc_threads); + _gc_par_phases[RestoreRetainedRegions] = new WorkerDataArray("RestoreRetainedRegions", "Restore Retained Regions (ms):", max_gc_threads); _gc_par_phases[ClearCardTable] = new WorkerDataArray("ClearLoggedCards", "Clear Logged Cards (ms):", max_gc_threads); _gc_par_phases[RecalculateUsed] = new WorkerDataArray("RecalculateUsed", "Recalculate Used Memory (ms):", max_gc_threads); _gc_par_phases[ResetHotCardCache] = new WorkerDataArray("ResetHotCardCache", "Reset Hot Card Cache (ms):", max_gc_threads); @@ -132,6 +132,8 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) : _gc_par_phases[MergePSS]->create_thread_work_items("LAB Waste", MergePSSLABWasteBytes); _gc_par_phases[MergePSS]->create_thread_work_items("LAB Undo Waste", MergePSSLABUndoWasteBytes); + _gc_par_phases[RestoreRetainedRegions]->create_thread_work_items("Evacuation Failure Regions:", RestoreRetainedRegionsNum); + _gc_par_phases[EagerlyReclaimHumongousObjects]->create_thread_work_items("Humongous Total", EagerlyReclaimNumTotal); _gc_par_phases[EagerlyReclaimHumongousObjects]->create_thread_work_items("Humongous Candidates", EagerlyReclaimNumCandidates); _gc_par_phases[EagerlyReclaimHumongousObjects]->create_thread_work_items("Humongous Reclaimed", EagerlyReclaimNumReclaimed); @@ -266,11 +268,7 @@ void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_id, double sec } void G1GCPhaseTimes::record_or_add_time_secs(GCParPhases phase, uint worker_id, double secs) { - if (_gc_par_phases[phase]->get(worker_id) == _gc_par_phases[phase]->uninitialized()) { - record_time_secs(phase, worker_id, secs); - } else { - add_time_secs(phase, worker_id, secs); - } + _gc_par_phases[phase]->set_or_add(worker_id, secs); } double G1GCPhaseTimes::get_time_secs(GCParPhases phase, uint worker_id) { @@ -484,7 +482,7 @@ double G1GCPhaseTimes::print_post_evacuate_collection_set(bool evacuation_failed debug_phase(_gc_par_phases[ClearCardTable], 1); debug_phase(_gc_par_phases[RecalculateUsed], 1); if (evacuation_failed) { - debug_phase(_gc_par_phases[RemoveSelfForwardingPtr], 1); + debug_phase(_gc_par_phases[RestoreRetainedRegions], 1); } trace_phase(_gc_par_phases[RedirtyCards]); @@ -578,8 +576,8 @@ void G1EvacPhaseWithTrimTimeTracker::stop() { _stopped = true; } -G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record) : - _start_time(), _phase(phase), _phase_times(phase_times), _worker_id(worker_id), _event(), _must_record(must_record) { +G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool allow_multiple_record) : + _start_time(), _phase(phase), _phase_times(phase_times), _worker_id(worker_id), _event(), _allow_multiple_record(allow_multiple_record) { if (_phase_times != NULL) { _start_time = Ticks::now(); } @@ -587,10 +585,10 @@ G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCParPhaseTimesTracker::~G1GCParPhaseTimesTracker() { if (_phase_times != NULL) { - if (_must_record) { - _phase_times->record_time_secs(_phase, _worker_id, (Ticks::now() - _start_time).seconds()); - } else { + if (_allow_multiple_record) { _phase_times->record_or_add_time_secs(_phase, _worker_id, (Ticks::now() - _start_time).seconds()); + } else { + _phase_times->record_time_secs(_phase, _worker_id, (Ticks::now() - _start_time).seconds()); } _event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_phase)); } diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp index 9db7f18dd347469be15aacad9b0e47fac1fbdb65..0cd6aebc8ccec453d72e39774769f0d7ff8f1c6f 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp @@ -77,7 +77,7 @@ class G1GCPhaseTimes : public CHeapObj { RebuildFreeList, SampleCollectionSetCandidates, MergePSS, - RemoveSelfForwardingPtr, + RestoreRetainedRegions, ClearCardTable, RecalculateUsed, ResetHotCardCache, @@ -144,6 +144,10 @@ class G1GCPhaseTimes : public CHeapObj { MergePSSLABUndoWasteBytes }; + enum RestoreRetainedRegionsWorkItems { + RestoreRetainedRegionsNum, + }; + enum GCEagerlyReclaimHumongousObjectsItems { EagerlyReclaimNumTotal, EagerlyReclaimNumCandidates, diff --git a/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp b/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp index 2b8fb3532ee0ea574a32d4e546ddb21648b8eaa4..d59d7e1c0fbf25c21cce7046838ba32617fa6e08 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp @@ -32,13 +32,7 @@ // lookups for that information all over the place. struct G1HeapRegionAttr { public: -#if defined(_M_ARM64)&& defined(_MSC_VER) && _MSC_VER <= 1927 - // workaround for MSCV ARM64 bug - // https://developercommunity.visualstudio.com/content/problem/1079221/arm64-bad-code-generation-around-signed-char-arith.html - typedef int32_t region_type_t; -#else typedef int8_t region_type_t; -#endif // remset_is_tracked_t is essentially bool, but we need precise control // on the size, and sizeof(bool) is implementation specific. typedef uint8_t remset_is_tracked_t; diff --git a/src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp b/src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp index c8518a5172e2e31a0773e145b7f2d86a13e1be5e..eb3d60656d4a9c0c39d69d49d3a3ca2ad1a24341 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_G1_G1HEAPREGIONEVENTSENDER_HPP #define SHARE_GC_G1_G1HEAPREGIONEVENTSENDER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class G1HeapRegionEventSender : public AllStatic { public: diff --git a/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp b/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp index ab3ee03137c76a661d859787218b5bed7b10886c..1c5690e566d8a1200e444f65fcab091654134988 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_G1_G1HEAPREGIONTRACETYPE_HPP #define SHARE_GC_G1_G1HEAPREGIONTRACETYPE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" class G1HeapRegionTraceType : AllStatic { diff --git a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp index 2c18b4a7346ad8f4c52571c1218fff5c568a4a8c..1cf2c01a0e26eca5f396f596840810b582115104 100644 --- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp +++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp @@ -114,9 +114,9 @@ class G1VerifyCodeRootOopClosure: public OopClosure { // Now fetch the region containing the object HeapRegion* hr = _g1h->heap_region_containing(obj); HeapRegionRemSet* hrrs = hr->rem_set(); - // Verify that the strong code root list for this region + // Verify that the code root list for this region // contains the nmethod - if (!hrrs->strong_code_roots_list_contains(_nm)) { + if (!hrrs->code_roots_list_contains(_nm)) { log_error(gc, verify)("Code root location " PTR_FORMAT " " "from nmethod " PTR_FORMAT " not in strong " "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")", diff --git a/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.cpp b/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.cpp index 6289bc82f243ae043974183f5c09203331d22684..d0a0542152ed51b4cb5e79553afd27d4a09af0cf 100644 --- a/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.cpp +++ b/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.hpp b/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.hpp index 0c934f4d31ec77f943acb3a2c52add4b9f35be23..ed55c0f9bed913f61ea764c94d5af575114ea704 100644 --- a/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.hpp +++ b/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp index 2cd41d4255f2df5edba66b269bc37849e417281a..c368130bfcae013dc6f8a32c90711fc4876a3740 100644 --- a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp +++ b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp @@ -274,7 +274,9 @@ template void G1RebuildRemSetClosure::do_oop_work(T* p) { HeapRegion* to = _g1h->heap_region_containing(obj); HeapRegionRemSet* rem_set = to->rem_set(); - rem_set->add_reference(p, _worker_id); + if (rem_set->is_tracked()) { + rem_set->add_reference(p, _worker_id); + } } #endif // SHARE_GC_G1_G1OOPCLOSURES_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp index 7a164e6461f43dd3176f37b7cc7b3e4e4566033e..94f51c8fdd1bb00d26f816bc7d9f9b25521ae064 100644 --- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp +++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * 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,13 +178,6 @@ char* G1PageBasedVirtualSpace::bounded_end_addr(size_t end_page) const { return MIN2(_high_boundary, page_start(end_page)); } -void G1PageBasedVirtualSpace::pretouch_internal(size_t start_page, size_t end_page) { - guarantee(start_page < end_page, - "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page); - - os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page), _page_size); -} - bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) { // We need to make sure to commit all pages covered by the given area. guarantee(is_area_uncommitted(start_page, size_in_pages), diff --git a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp index 8b68ad60e560a3e702ea2f4e50fa332f13e1585d..0b97656c883933abf603398c14a01f7727d948e7 100644 --- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp +++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,9 +87,6 @@ class G1PageBasedVirtualSpace { // Uncommit the given memory range. void uncommit_internal(size_t start_page, size_t end_page); - // Pretouch the given memory range. - void pretouch_internal(size_t start_page, size_t end_page); - // Returns the index of the page which contains the given address. size_t addr_to_page_index(char* addr) const; diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index da24578f9df691178f521522b5a031c1bab24b23..3cc3c5c0120ba15101507cd3d60511d22b4bbb51 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -434,6 +434,12 @@ void G1ParScanThreadState::undo_allocation(G1HeapRegionAttr dest_attr, _plab_allocator->undo_allocation(dest_attr, obj_ptr, word_sz, node_index); } +void G1ParScanThreadState::update_bot_after_copying(oop obj, size_t word_sz) { + HeapWord* obj_start = cast_from_oop(obj); + HeapRegion* region = _g1h->heap_region_containing(obj_start); + region->update_bot_for_obj(obj_start, word_sz); +} + // Private inline function, for direct internal use and providing the // implementation of the public not-inline function. MAYBE_INLINE_EVACUATION @@ -503,10 +509,7 @@ oop G1ParScanThreadState::do_copy_to_survivor_space(G1HeapRegionAttr const regio } _age_table.add(age, word_sz); } else { - // Currently we only have two destinations and we only need BOT updates for - // old. If the current allocation was done outside the PLAB this call will - // have no effect since the _top of the PLAB has not changed. - _plab_allocator->update_bot_for_plab_allocation(dest_attr, word_sz, node_index); + update_bot_after_copying(obj, word_sz); } // Most objects are not arrays, so do one array check rather than @@ -616,9 +619,11 @@ oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markWord m, siz if (forward_ptr == NULL) { // Forward-to-self succeeded. We are the "owner" of the object. HeapRegion* r = _g1h->heap_region_containing(old); - // Records evac failure objs, this will help speed up iteration - // of these objs later in *remove self forward* phase of post evacuation. - r->record_evac_failure_obj(old); + + // Objects failing evacuation will turn into old objects since the regions + // are relabeled as such. We mark the failing objects in the prev bitmap and + // later use it to handle all failed objects. + _g1h->mark_evac_failure_object(old, _worker_id); if (_evac_failure_regions->record(r->hrm_index())) { _g1h->hr_printer()->evac_failure(r); diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp index f40ca519268fb4f477cbfc9d00972af9f8dfee67..dab2d718b7cfd0625646e76c4fa867216492d04f 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp @@ -169,6 +169,8 @@ private: size_t word_sz, uint node_index); + void update_bot_after_copying(oop obj, size_t word_sz); + oop do_copy_to_survivor_space(G1HeapRegionAttr region_attr, oop obj, markWord old_mark); diff --git a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp index a1802e01821fe75d5bacc28acdc99fe07922c9cd..d6c2ae148be5adb800b11f2820642e6e4b2ea2f8 100644 --- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp +++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ void G1RedirtyCardsLocalQueueSet::enqueue(void* value) { void G1RedirtyCardsLocalQueueSet::flush() { flush_queue(_queue); _shared_qset->add_bufferlist(_buffers); - _buffers = G1BufferNodeList(); + _buffers = BufferNodeList(); } // G1RedirtyCardsLocalQueueSet::Queue @@ -109,9 +109,9 @@ BufferNode* G1RedirtyCardsQueueSet::all_completed_buffers() const { return _list.top(); } -G1BufferNodeList G1RedirtyCardsQueueSet::take_all_completed_buffers() { +BufferNodeList G1RedirtyCardsQueueSet::take_all_completed_buffers() { DEBUG_ONLY(_collecting = false;) - G1BufferNodeList result(_list.pop_all(), _tail, _entry_count); + BufferNodeList result(_list.pop_all(), _tail, _entry_count); _tail = NULL; _entry_count = 0; DEBUG_ONLY(_collecting = true;) @@ -135,7 +135,7 @@ void G1RedirtyCardsQueueSet::enqueue_completed_buffer(BufferNode* node) { update_tail(node); } -void G1RedirtyCardsQueueSet::add_bufferlist(const G1BufferNodeList& buffers) { +void G1RedirtyCardsQueueSet::add_bufferlist(const BufferNodeList& buffers) { assert(_collecting, "precondition"); if (buffers._head != NULL) { assert(buffers._tail != NULL, "invariant"); diff --git a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp index 26bb78c4096e54a4d9f716256213a48e27ba0e8a..b464d3772985fd7afecd72da81e47d9002824623 100644 --- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp +++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP #define SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP -#include "gc/g1/g1BufferNodeList.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "gc/shared/ptrQueue.hpp" #include "memory/padded.hpp" #include "utilities/macros.hpp" @@ -42,7 +42,7 @@ class G1RedirtyCardsLocalQueueSet : private PtrQueueSet { }; G1RedirtyCardsQueueSet* _shared_qset; - G1BufferNodeList _buffers; + BufferNodeList _buffers; Queue _queue; // Add the buffer to the local list. @@ -84,12 +84,12 @@ public: // Collect buffers. These functions are thread-safe. // precondition: Must not be concurrent with buffer processing. virtual void enqueue_completed_buffer(BufferNode* node); - void add_bufferlist(const G1BufferNodeList& buffers); + void add_bufferlist(const BufferNodeList& buffers); // Processing phase operations. // precondition: Must not be concurrent with buffer collection. BufferNode* all_completed_buffers() const; - G1BufferNodeList take_all_completed_buffers(); + BufferNodeList take_all_completed_buffers(); }; #endif // SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP diff --git a/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp b/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp index f8ce06237c1bcf9dd6915649dc5f99086090745e..6cabe460065314bcdd88bdee1440e18c3c5919f6 100644 --- a/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp +++ b/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp @@ -30,15 +30,13 @@ G1RegionMarkStatsCache::G1RegionMarkStatsCache(G1RegionMarkStats* target, uint num_cache_entries) : _target(target), - _cache(NULL), _num_cache_entries(num_cache_entries), - _cache_hits(0), - _cache_misses(0), _num_cache_entries_mask(_num_cache_entries - 1) { guarantee(is_power_of_2(num_cache_entries), "Number of cache entries must be power of two, but is %u", num_cache_entries); _cache = NEW_C_HEAP_ARRAY(G1RegionMarkStatsCacheEntry, _num_cache_entries, mtGC); + reset(); } G1RegionMarkStatsCache::~G1RegionMarkStatsCache() { diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index dcde1bd8fa5b2eebf50142f0a0d7e577d81373a3..6496b6eaf64924cc8ca813dc691befc0d22a4b6f 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,7 @@ #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionRemSet.inline.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/ptrQueue.hpp" #include "gc/shared/suspendibleThreadSet.hpp" @@ -106,7 +107,7 @@ class G1RemSetScanState : public CHeapObj { // within a region to claim. Dependent on the region size as proxy for the heap // size, we limit the total number of chunks to limit memory usage and maintenance // effort of that table vs. granularity of distributing scanning work. - // Testing showed that 8 for 1M/2M region, 16 for 4M/8M regions, 32 for 16/32M regions, + // Testing showed that 64 for 1M/2M region, 128 for 4M/8M regions, 256 for 16/32M regions, // and so on seems to be such a good trade-off. static uint get_chunks_per_region(uint log_region_size) { // Limit the expected input values to current known possible values of the @@ -114,7 +115,7 @@ class G1RemSetScanState : public CHeapObj { // values for region size. assert(log_region_size >= 20 && log_region_size <= 29, "expected value in [20,29], but got %u", log_region_size); - return 1u << (log_region_size / 2 - 7); + return 1u << (log_region_size / 2 - 4); } uint _scan_chunks_per_region; // Number of chunks per region. @@ -808,7 +809,7 @@ class G1ScanHRForRegionClosure : public HeapRegionClosure { return; } - HeapWord* scan_end = MIN2(card_start + (num_cards << BOTConstants::LogN_words), top); + HeapWord* scan_end = MIN2(card_start + (num_cards << BOTConstants::log_card_size_in_words()), top); if (_scanned_to >= scan_end) { return; } @@ -945,8 +946,8 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { size_t _opt_refs_scanned; size_t _opt_refs_memory_used; - Tickspan _strong_code_root_scan_time; - Tickspan _strong_code_trim_partially_time; + Tickspan _code_root_scan_time; + Tickspan _code_trim_partially_time; Tickspan _rem_set_opt_root_scan_time; Tickspan _rem_set_opt_trim_partially_time; @@ -978,8 +979,8 @@ public: _opt_roots_scanned(0), _opt_refs_scanned(0), _opt_refs_memory_used(0), - _strong_code_root_scan_time(), - _strong_code_trim_partially_time(), + _code_root_scan_time(), + _code_trim_partially_time(), _rem_set_opt_root_scan_time(), _rem_set_opt_trim_partially_time() { } @@ -996,9 +997,9 @@ public: if (_scan_state->claim_collection_set_region(region_idx)) { EventGCPhaseParallel event; - G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time); - // Scan the strong code root list attached to the current region - r->strong_code_roots_do(_pss->closures()->weak_codeblobs()); + G1EvacPhaseWithTrimTimeTracker timer(_pss, _code_root_scan_time, _code_trim_partially_time); + // Scan the code root list attached to the current region + r->code_roots_do(_pss->closures()->weak_codeblobs()); event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_code_roots_phase)); } @@ -1006,8 +1007,8 @@ public: return false; } - Tickspan strong_code_root_scan_time() const { return _strong_code_root_scan_time; } - Tickspan strong_code_root_trim_partially_time() const { return _strong_code_trim_partially_time; } + Tickspan code_root_scan_time() const { return _code_root_scan_time; } + Tickspan code_root_trim_partially_time() const { return _code_trim_partially_time; } Tickspan rem_set_opt_root_scan_time() const { return _rem_set_opt_root_scan_time; } Tickspan rem_set_opt_trim_partially_time() const { return _rem_set_opt_trim_partially_time; } @@ -1030,8 +1031,8 @@ void G1RemSet::scan_collection_set_regions(G1ParScanThreadState* pss, p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_root_scan_time().seconds()); p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_trim_partially_time().seconds()); - p->record_or_add_time_secs(coderoots_phase, worker_id, cl.strong_code_root_scan_time().seconds()); - p->add_time_secs(objcopy_phase, worker_id, cl.strong_code_root_trim_partially_time().seconds()); + p->record_or_add_time_secs(coderoots_phase, worker_id, cl.code_root_scan_time().seconds()); + p->add_time_secs(objcopy_phase, worker_id, cl.code_root_trim_partially_time().seconds()); // At this time we record some metrics only for the evacuations after the initial one. if (scan_phase == G1GCPhaseTimes::OptScanHR) { @@ -1259,6 +1260,46 @@ class G1MergeHeapRootsTask : public WorkerTask { G1MergeCardSetStats stats() const { return _stats; } }; + // Closure to clear the prev bitmap for any old region in the collection set. + // This is needed to be able to use the bitmap for evacuation failure handling. + class G1ClearBitmapClosure : public HeapRegionClosure { + G1CollectedHeap* _g1h; + void assert_bitmap_clear(HeapRegion* hr, const G1CMBitMap* bitmap) { + assert(bitmap->get_next_marked_addr(hr->bottom(), hr->end()) == hr->end(), + "Bitmap should have no mark for young regions"); + } + public: + G1ClearBitmapClosure(G1CollectedHeap* g1h) : _g1h(g1h) { } + + bool do_heap_region(HeapRegion* hr) { + assert(_g1h->is_in_cset(hr), "Should only be used iterating the collection set"); + // Young regions should always have cleared bitmaps, so only clear old. + if (hr->is_old()) { + _g1h->clear_prev_bitmap_for_region(hr); + } else { + assert(hr->is_young(), "Should only be young and old regions in collection set"); + assert_bitmap_clear(hr, _g1h->concurrent_mark()->prev_mark_bitmap()); + } + return false; + } + }; + + // Helper to allow two closure to be applied when + // iterating through the collection set. + class G1CombinedClosure : public HeapRegionClosure { + HeapRegionClosure* _closure1; + HeapRegionClosure* _closure2; + public: + G1CombinedClosure(HeapRegionClosure* cl1, HeapRegionClosure* cl2) : + _closure1(cl1), + _closure2(cl2) { } + + bool do_heap_region(HeapRegion* hr) { + return _closure1->do_heap_region(hr) || + _closure2->do_heap_region(hr); + } + }; + // Visitor for the remembered sets of humongous candidate regions to merge their // remembered set into the card table. class G1FlushHumongousCandidateRemSets : public HeapRegionClosure { @@ -1389,7 +1430,7 @@ public: { if (initial_evacuation) { G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); - G1BufferNodeList buffers = dcqs.take_all_completed_buffers(); + BufferNodeList buffers = dcqs.take_all_completed_buffers(); if (buffers._entry_count != 0) { _dirty_card_buffers.prepend(*buffers._head, *buffers._tail); } @@ -1423,12 +1464,15 @@ public: // Merge remembered sets of current candidates. { - G1GCParPhaseTimesTracker x(p, merge_remset_phase, worker_id, _initial_evacuation /* must_record */); + G1GCParPhaseTimesTracker x(p, merge_remset_phase, worker_id, !_initial_evacuation /* allow_multiple_record */); G1MergeCardSetStats stats; { - G1MergeCardSetClosure cl(_scan_state); - g1h->collection_set_iterate_increment_from(&cl, &_hr_claimer, worker_id); - stats = cl.stats(); + G1MergeCardSetClosure merge(_scan_state); + G1ClearBitmapClosure clear(g1h); + G1CombinedClosure combined(&merge, &clear); + + g1h->collection_set_iterate_increment_from(&combined, &_hr_claimer, worker_id); + stats = merge.stats(); } for (uint i = 0; i < G1GCPhaseTimes::MergeRSContainersSentinel; i++) { @@ -1674,7 +1718,7 @@ void G1RemSet::refine_card_concurrently(CardValue* const card_ptr, // Don't use addr_for(card_ptr + 1) which can ask for // a card beyond the heap. - HeapWord* end = start + G1CardTable::card_size_in_words; + HeapWord* end = start + G1CardTable::card_size_in_words(); MemRegion dirty_region(start, MIN2(scan_limit, end)); assert(!dirty_region.is_empty(), "sanity"); @@ -1914,7 +1958,7 @@ public: HeapWord* const top_at_mark_start = hr->prev_top_at_mark_start(); HeapWord* cur = hr->bottom(); - while (cur < hr->end()) { + while (true) { // After every iteration (yield point) we need to check whether the region's // TARS changed due to e.g. eager reclaim. HeapWord* const top_at_rebuild_start = _cm->top_at_rebuild_start(region_idx); diff --git a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp index cae7df6f90285a03474d8812566bc227abebdad8..faf09063bc05f232bf47b220814260d00ea05c24 100644 --- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp @@ -233,7 +233,7 @@ public: HeapRegionRemSet* hrrs = r->rem_set(); // HeapRegionRemSet::mem_size() includes the - // size of the strong code roots + // size of the code roots size_t rs_wasted_mem_sz = hrrs->wasted_mem_size(); size_t rs_mem_sz = hrrs->mem_size(); if (rs_mem_sz > _max_rs_mem_sz) { @@ -241,12 +241,12 @@ public: _max_rs_mem_sz_region = r; } size_t occupied_cards = hrrs->occupied(); - size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size(); + size_t code_root_mem_sz = hrrs->code_roots_mem_size(); if (code_root_mem_sz > max_code_root_mem_sz()) { _max_code_root_mem_sz = code_root_mem_sz; _max_code_root_mem_sz_region = r; } - size_t code_root_elems = hrrs->strong_code_roots_list_length(); + size_t code_root_elems = hrrs->code_roots_list_length(); RegionTypeCounter* current = NULL; if (r->is_free()) { @@ -300,14 +300,14 @@ public: HeapRegionRemSet::print_static_mem_size(out); G1CardSetFreePool::free_list_pool()->print_on(out); - // Strong code root statistics + // Code root statistics HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set(); out->print_cr(" Total heap region code root sets sizes = " SIZE_FORMAT "%s." " Max = " SIZE_FORMAT "%s.", byte_size_in_proper_unit(total_code_root_mem_sz()), proper_unit_for_byte_size(total_code_root_mem_sz()), - byte_size_in_proper_unit(max_code_root_rem_set->strong_code_roots_mem_size()), - proper_unit_for_byte_size(max_code_root_rem_set->strong_code_roots_mem_size())); + byte_size_in_proper_unit(max_code_root_rem_set->code_roots_mem_size()), + proper_unit_for_byte_size(max_code_root_rem_set->code_roots_mem_size())); for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz()); } @@ -321,9 +321,9 @@ public: out->print_cr(" Region with largest amount of code roots = " HR_FORMAT ", " "size = " SIZE_FORMAT "%s, num_slots = " SIZE_FORMAT ".", HR_FORMAT_PARAMS(max_code_root_mem_sz_region()), - byte_size_in_proper_unit(max_code_root_rem_set->strong_code_roots_mem_size()), - proper_unit_for_byte_size(max_code_root_rem_set->strong_code_roots_mem_size()), - max_code_root_rem_set->strong_code_roots_list_length()); + byte_size_in_proper_unit(max_code_root_rem_set->code_roots_mem_size()), + proper_unit_for_byte_size(max_code_root_rem_set->code_roots_mem_size()), + max_code_root_rem_set->code_roots_list_length()); } }; diff --git a/src/hotspot/share/gc/g1/g1SegmentedArray.inline.hpp b/src/hotspot/share/gc/g1/g1SegmentedArray.inline.hpp index 1829f47e2169df6c0a63ec12b21498a5e2240e5c..17be55fe6abeca85ff1cfbb51689f9cfffcd253a 100644 --- a/src/hotspot/share/gc/g1/g1SegmentedArray.inline.hpp +++ b/src/hotspot/share/gc/g1/g1SegmentedArray.inline.hpp @@ -34,12 +34,12 @@ template G1SegmentedArraySegment::G1SegmentedArraySegment(uint slot_size, uint num_slots, G1SegmentedArraySegment* next) : _slot_size(slot_size), _num_slots(num_slots), _next(next), _next_allocate(0) { - _segment = NEW_C_HEAP_ARRAY(char, (size_t)_num_slots * slot_size, mtGCCardSet); + _segment = NEW_C_HEAP_ARRAY(char, (size_t)_num_slots * slot_size, flag); } template G1SegmentedArraySegment::~G1SegmentedArraySegment() { - FREE_C_HEAP_ARRAY(mtGCCardSet, _segment); + FREE_C_HEAP_ARRAY(flag, _segment); } template diff --git a/src/hotspot/share/gc/g1/g1SharedClosures.hpp b/src/hotspot/share/gc/g1/g1SharedClosures.hpp index 55b9a1e62c53a543b0719774dd2c1c5a40b4a731..4808f0ae84f6c128813ef494377cd877581819a7 100644 --- a/src/hotspot/share/gc/g1/g1SharedClosures.hpp +++ b/src/hotspot/share/gc/g1/g1SharedClosures.hpp @@ -37,7 +37,7 @@ public: G1ParCopyClosure _oops_in_cld; // We do not need (and actually should not) collect oops from nmethods into the // optional collection set as we already automatically collect the corresponding - // nmethods in the region's strong code roots set. So set G1BarrierNoOptRoots in + // nmethods in the region's code roots set. So set G1BarrierNoOptRoots in // this closure. // If these were present there would be opportunity for multiple threads to try // to change this oop* at the same time. Since embedded oops are not necessarily diff --git a/src/hotspot/share/gc/g1/g1VMOperations.cpp b/src/hotspot/share/gc/g1/g1VMOperations.cpp index 75d209b94a5717f72c56f27703ef4715f5aecde6..94699a0c718fb013c7f2ab46a662ec6fe6eca7ce 100644 --- a/src/hotspot/share/gc/g1/g1VMOperations.cpp +++ b/src/hotspot/share/gc/g1/g1VMOperations.cpp @@ -170,7 +170,7 @@ void VM_G1CollectForAllocation::doit() { } } -void VM_G1Concurrent::doit() { +void VM_G1PauseConcurrent::doit() { GCIdMark gc_id_mark(_gc_id); GCTraceCPUTime tcpu; G1CollectedHeap* g1h = G1CollectedHeap::heap(); @@ -184,17 +184,28 @@ void VM_G1Concurrent::doit() { TraceCollectorStats tcs(g1h->monitoring_support()->conc_collection_counters()); SvcGCMarker sgcm(SvcGCMarker::CONCURRENT); IsGCActiveMark x; - _cl->do_void(); + + work(); } -bool VM_G1Concurrent::doit_prologue() { +bool VM_G1PauseConcurrent::doit_prologue() { Heap_lock->lock(); return true; } -void VM_G1Concurrent::doit_epilogue() { +void VM_G1PauseConcurrent::doit_epilogue() { if (Universe::has_reference_pending_list()) { Heap_lock->notify_all(); } Heap_lock->unlock(); } + +void VM_G1PauseRemark::work() { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + g1h->concurrent_mark()->remark(); +} + +void VM_G1PauseCleanup::work() { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + g1h->concurrent_mark()->cleanup(); +} diff --git a/src/hotspot/share/gc/g1/g1VMOperations.hpp b/src/hotspot/share/gc/g1/g1VMOperations.hpp index b5f36a51b789c5661d946601c40f29badcc95b71..72f450ad3bc2de66c86c356b8a05ddbfbdc3a6cc 100644 --- a/src/hotspot/share/gc/g1/g1VMOperations.hpp +++ b/src/hotspot/share/gc/g1/g1VMOperations.hpp @@ -87,18 +87,33 @@ private: }; // Concurrent G1 stop-the-world operations such as remark and cleanup. -class VM_G1Concurrent : public VM_Operation { - VoidClosure* _cl; - const char* _message; +class VM_G1PauseConcurrent : public VM_Operation { uint _gc_id; + const char* _message; + +protected: + VM_G1PauseConcurrent(const char* message) : + _gc_id(GCId::current()), _message(message) { } + virtual void work() = 0; public: - VM_G1Concurrent(VoidClosure* cl, const char* message) : - _cl(cl), _message(message), _gc_id(GCId::current()) { } - virtual VMOp_Type type() const { return VMOp_G1Concurrent; } - virtual void doit(); - virtual bool doit_prologue(); - virtual void doit_epilogue(); + bool doit_prologue() override; + void doit_epilogue() override; + void doit() override; +}; + +class VM_G1PauseRemark : public VM_G1PauseConcurrent { +public: + VM_G1PauseRemark() : VM_G1PauseConcurrent("Pause Remark") { } + VMOp_Type type() const override { return VMOp_G1PauseRemark; } + void work() override; +}; + +class VM_G1PauseCleanup : public VM_G1PauseConcurrent { +public: + VM_G1PauseCleanup() : VM_G1PauseConcurrent("Pause Cleanup") { } + VMOp_Type type() const override { return VMOp_G1PauseCleanup; } + void work() override; }; #endif // SHARE_GC_G1_G1VMOPERATIONS_HPP diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.cpp b/src/hotspot/share/gc/g1/g1YoungCollector.cpp index d476c981d7134782d1459bbc74bc6f52674e5712..d5e1774a8bd208596fcfb557c995c0cd31a4ac44 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.cpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,47 +59,6 @@ #include "memory/resourceArea.hpp" #include "utilities/ticks.hpp" -#if TASKQUEUE_STATS -uint G1YoungCollector::num_task_queues() const { - return task_queues()->size(); -} - -void G1YoungCollector::print_taskqueue_stats_hdr(outputStream* const st) { - st->print_raw_cr("GC Task Stats"); - st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr(); - st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr(); -} - -void G1YoungCollector::print_taskqueue_stats() const { - if (!log_is_enabled(Trace, gc, task, stats)) { - return; - } - Log(gc, task, stats) log; - ResourceMark rm; - LogStream ls(log.trace()); - outputStream* st = &ls; - - print_taskqueue_stats_hdr(st); - - TaskQueueStats totals; - const uint n = num_task_queues(); - for (uint i = 0; i < n; ++i) { - st->print("%3u ", i); _g1h->task_queue(i)->stats.print(st); st->cr(); - totals += _g1h->task_queue(i)->stats; - } - st->print_raw("tot "); totals.print(st); st->cr(); - - DEBUG_ONLY(totals.verify()); -} - -void G1YoungCollector::reset_taskqueue_stats() { - const uint n = num_task_queues(); - for (uint i = 0; i < n; ++i) { - _g1h->task_queue(i)->stats.reset(); - } -} -#endif // TASKQUEUE_STATS - // GCTraceTime wrapper that constructs the message according to GC pause type and // GC cause. // The code relies on the fact that GCTraceTimeWrapper stores the string passed @@ -436,7 +395,7 @@ class G1PrepareEvacuationTask : public WorkerTask { cast_to_oop(hr->bottom())->size() * HeapWordSize, p2i(hr->bottom()), hr->rem_set()->occupied(), - hr->rem_set()->strong_code_roots_list_length(), + hr->rem_set()->code_roots_list_length(), _g1h->concurrent_mark()->next_mark_bitmap()->is_marked(hr->bottom()), _g1h->is_humongous_reclaim_candidate(index), cast_to_oop(hr->bottom())->is_typeArray() @@ -1147,6 +1106,5 @@ void G1YoungCollector::collect() { policy()->record_young_collection_end(_concurrent_operation_is_full_mark, evacuation_failed()); } - TASKQUEUE_STATS_ONLY(print_taskqueue_stats()); - TASKQUEUE_STATS_ONLY(reset_taskqueue_stats()); + TASKQUEUE_STATS_ONLY(_g1h->task_queues()->print_and_reset_taskqueue_stats("Oop Queue");) } diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.hpp b/src/hotspot/share/gc/g1/g1YoungCollector.hpp index 055803a3352289117fadd975fbffaee5145c714f..c5ad5c452358ad2dec096d1d3bd3c79340647a40 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.hpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,13 +134,6 @@ class G1YoungCollector { // True iff an evacuation has failed in the most-recent collection. bool evacuation_failed() const; -#if TASKQUEUE_STATS - uint num_task_queues() const; - static void print_taskqueue_stats_hdr(outputStream* const st); - void print_taskqueue_stats() const; - void reset_taskqueue_stats(); -#endif // TASKQUEUE_STATS - public: G1YoungCollector(GCCause::Cause gc_cause, double target_pause_time_ms); diff --git a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp index f8e260e21e69d3368c0c5b20949b6d59d9c859e3..669b3a8ae761ec207724f24fd1f2cb81cb442792 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp +++ b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp @@ -103,7 +103,7 @@ class G1PostEvacuateCollectionSetCleanupTask1::RemoveSelfForwardPtrsTask : publi public: RemoveSelfForwardPtrsTask(G1EvacFailureRegions* evac_failure_regions) : - G1AbstractSubTask(G1GCPhaseTimes::RemoveSelfForwardingPtr), + G1AbstractSubTask(G1GCPhaseTimes::RestoreRetainedRegions), _task(evac_failure_regions), _evac_failure_regions(evac_failure_regions) { } diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index 78ca4ad8bf97fcdea9536075b6bdb198539ba49f..93baa2383510b21821d5384ff44bb48ff86c2825 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -91,7 +91,7 @@ void HeapRegion::setup_heap_region_size(size_t max_heap_size) { GrainWords = GrainBytes >> LogHeapWordSize; guarantee(CardsPerRegion == 0, "we should only set it once"); - CardsPerRegion = GrainBytes >> G1CardTable::card_shift; + CardsPerRegion = GrainBytes >> G1CardTable::card_shift(); LogCardsPerRegion = log2i(CardsPerRegion); @@ -107,10 +107,6 @@ void HeapRegion::handle_evacuation_failure() { _next_marked_bytes = 0; } -void HeapRegion::process_and_drop_evac_failure_objs(ObjectClosure* closure) { - _evac_failure_objs.process_and_drop(closure); -} - void HeapRegion::unlink_from_list() { set_next(NULL); set_prev(NULL); @@ -214,8 +210,6 @@ void HeapRegion::set_continues_humongous(HeapRegion* first_hr) { report_region_type_change(G1HeapRegionTraceType::ContinuesHumongous); _type.set_continues_humongous(); _humongous_start_region = first_hr; - - _bot_part.set_object_can_span(true); } void HeapRegion::clear_humongous() { @@ -223,8 +217,6 @@ void HeapRegion::clear_humongous() { assert(capacity() == HeapRegion::GrainBytes, "pre-condition"); _humongous_start_region = NULL; - - _bot_part.set_object_can_span(false); } HeapRegion::HeapRegion(uint hrm_index, @@ -250,8 +242,7 @@ HeapRegion::HeapRegion(uint hrm_index, _prev_marked_bytes(0), _next_marked_bytes(0), _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(G1SurvRateGroup::InvalidAgeIndex), _gc_efficiency(-1.0), - _node_index(G1NUMA::UnknownNodeIndex), - _evac_failure_objs(hrm_index, _bottom) + _node_index(G1NUMA::UnknownNodeIndex) { assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end()), "invalid space boundaries"); @@ -269,7 +260,6 @@ void HeapRegion::initialize(bool clear_space, bool mangle_space) { set_top(bottom()); set_compaction_top(bottom()); - reset_bot(); hr_clear(false /*clear_space*/); } @@ -313,28 +303,28 @@ void HeapRegion::note_self_forwarding_removal_end(size_t marked_bytes) { // Code roots support -void HeapRegion::add_strong_code_root(nmethod* nm) { +void HeapRegion::add_code_root(nmethod* nm) { HeapRegionRemSet* hrrs = rem_set(); - hrrs->add_strong_code_root(nm); + hrrs->add_code_root(nm); } -void HeapRegion::add_strong_code_root_locked(nmethod* nm) { +void HeapRegion::add_code_root_locked(nmethod* nm) { assert_locked_or_safepoint(CodeCache_lock); HeapRegionRemSet* hrrs = rem_set(); - hrrs->add_strong_code_root_locked(nm); + hrrs->add_code_root_locked(nm); } -void HeapRegion::remove_strong_code_root(nmethod* nm) { +void HeapRegion::remove_code_root(nmethod* nm) { HeapRegionRemSet* hrrs = rem_set(); - hrrs->remove_strong_code_root(nm); + hrrs->remove_code_root(nm); } -void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const { +void HeapRegion::code_roots_do(CodeBlobClosure* blk) const { HeapRegionRemSet* hrrs = rem_set(); - hrrs->strong_code_roots_do(blk); + hrrs->code_roots_do(blk); } -class VerifyStrongCodeRootOopClosure: public OopClosure { +class VerifyCodeRootOopClosure: public OopClosure { const HeapRegion* _hr; bool _failures; bool _has_oops_in_region; @@ -362,7 +352,7 @@ class VerifyStrongCodeRootOopClosure: public OopClosure { } public: - VerifyStrongCodeRootOopClosure(const HeapRegion* hr): + VerifyCodeRootOopClosure(const HeapRegion* hr): _hr(hr), _failures(false), _has_oops_in_region(false) {} void do_oop(narrowOop* p) { do_oop_work(p); } @@ -372,11 +362,11 @@ public: bool has_oops_in_region() { return _has_oops_in_region; } }; -class VerifyStrongCodeRootCodeBlobClosure: public CodeBlobClosure { +class VerifyCodeRootCodeBlobClosure: public CodeBlobClosure { const HeapRegion* _hr; bool _failures; public: - VerifyStrongCodeRootCodeBlobClosure(const HeapRegion* hr) : + VerifyCodeRootCodeBlobClosure(const HeapRegion* hr) : _hr(hr), _failures(false) {} void do_code_blob(CodeBlob* cb) { @@ -384,14 +374,14 @@ public: if (nm != NULL) { // Verify that the nemthod is live if (!nm->is_alive()) { - log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod " PTR_FORMAT " in its strong code roots", + log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod " PTR_FORMAT " in its code roots", p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm)); _failures = true; } else { - VerifyStrongCodeRootOopClosure oop_cl(_hr); + VerifyCodeRootOopClosure oop_cl(_hr); nm->oops_do(&oop_cl); if (!oop_cl.has_oops_in_region()) { - log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod " PTR_FORMAT " in its strong code roots with no pointers into region", + log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod " PTR_FORMAT " in its code roots with no pointers into region", p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm)); _failures = true; } else if (oop_cl.failures()) { @@ -406,47 +396,47 @@ public: bool failures() { return _failures; } }; -void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const { +void HeapRegion::verify_code_roots(VerifyOption vo, bool* failures) const { if (!G1VerifyHeapRegionCodeRoots) { // We're not verifying code roots. return; } if (vo == VerifyOption_G1UseFullMarking) { // Marking verification during a full GC is performed after class - // unloading, code cache unloading, etc so the strong code roots + // unloading, code cache unloading, etc so the code roots // attached to each heap region are in an inconsistent state. They won't - // be consistent until the strong code roots are rebuilt after the - // actual GC. Skip verifying the strong code roots in this particular + // be consistent until the code roots are rebuilt after the + // actual GC. Skip verifying the code roots in this particular // time. assert(VerifyDuringGC, "only way to get here"); return; } HeapRegionRemSet* hrrs = rem_set(); - size_t strong_code_roots_length = hrrs->strong_code_roots_list_length(); + size_t code_roots_length = hrrs->code_roots_list_length(); // if this region is empty then there should be no entries - // on its strong code root list + // on its code root list if (is_empty()) { - if (strong_code_roots_length > 0) { + if (code_roots_length > 0) { log_error(gc, verify)("region " HR_FORMAT " is empty but has " SIZE_FORMAT " code root entries", - HR_FORMAT_PARAMS(this), strong_code_roots_length); + HR_FORMAT_PARAMS(this), code_roots_length); *failures = true; } return; } if (is_continues_humongous()) { - if (strong_code_roots_length > 0) { + if (code_roots_length > 0) { log_error(gc, verify)("region " HR_FORMAT " is a continuation of a humongous region but has " SIZE_FORMAT " code root entries", - HR_FORMAT_PARAMS(this), strong_code_roots_length); + HR_FORMAT_PARAMS(this), code_roots_length); *failures = true; } return; } - VerifyStrongCodeRootCodeBlobClosure cb_cl(this); - strong_code_roots_do(&cb_cl); + VerifyCodeRootCodeBlobClosure cb_cl(this); + code_roots_do(&cb_cl); if (cb_cl.failures()) { *failures = true; @@ -659,6 +649,8 @@ void HeapRegion::verify(VerifyOption vo, VerifyLiveClosure vl_cl(g1h, vo); VerifyRemSetClosure vr_cl(g1h, vo); bool is_region_humongous = is_humongous(); + // We cast p to an oop, so region-bottom must be an obj-start. + assert(!is_region_humongous || is_starts_humongous(), "invariant"); size_t object_num = 0; while (p < top()) { oop obj = cast_to_oop(p); @@ -737,12 +729,7 @@ void HeapRegion::verify(VerifyOption vo, return; } - verify_strong_code_roots(vo, failures); -} - -void HeapRegion::verify() const { - bool dummy = false; - verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy); + verify_code_roots(vo, failures); } void HeapRegion::verify_rem_set(VerifyOption vo, bool* failures) const { @@ -792,7 +779,6 @@ void HeapRegion::clear(bool mangle_space) { if (ZapUnusedHeapArea && mangle_space) { mangle_unused_area(); } - reset_bot(); } #ifndef PRODUCT @@ -801,10 +787,6 @@ void HeapRegion::mangle_unused_area() { } #endif -void HeapRegion::initialize_bot_threshold() { - _bot_part.initialize_threshold(); -} - void HeapRegion::alloc_block_in_bot(HeapWord* start, HeapWord* end) { _bot_part.alloc_block(start, end); } @@ -822,7 +804,7 @@ void HeapRegion::object_iterate(ObjectClosure* blk) { void HeapRegion::fill_with_dummy_object(HeapWord* address, size_t word_size, bool zap) { // Keep the BOT in sync for old generation regions. if (is_old()) { - update_bot_at(address, word_size); + update_bot_for_obj(address, word_size); } // Fill in the object. CollectedHeap::fill_with_object(address, word_size, zap); diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index cac95b4105fa019aa924b898a3050df9432fcb7e..d3af9faf9c739ab794e9f665a8491bef52ac1ba6 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -26,7 +26,6 @@ #define SHARE_GC_G1_HEAPREGION_HPP #include "gc/g1/g1BlockOffsetTable.hpp" -#include "gc/g1/g1EvacFailureObjectsSet.hpp" #include "gc/g1/g1HeapRegionTraceType.hpp" #include "gc/g1/g1SurvRateGroup.hpp" #include "gc/g1/heapRegionTracer.hpp" @@ -163,17 +162,11 @@ public: inline HeapWord* allocate(size_t word_size); inline HeapWord* allocate(size_t min_word_size, size_t desired_word_size, size_t* actual_size); - // Update the BOT for the given address if it crosses the next - // BOT threshold at or after obj_start. - inline void update_bot_at(HeapWord* obj_start, size_t obj_size); - // Update BOT at the given threshold for the given object. The - // given object must cross the threshold. - inline void update_bot_crossing_threshold(HeapWord** threshold, HeapWord* obj_start, HeapWord* obj_end); - inline HeapWord* bot_threshold_for_addr(const void* addr); + // Update BOT if this obj is the first entering a new card (i.e. crossing the card boundary). + inline void update_bot_for_obj(HeapWord* obj_start, size_t obj_size); // Full GC support methods. - void initialize_bot_threshold(); void alloc_block_in_bot(HeapWord* start, HeapWord* end); // Update heap region that has been compacted to be consistent after Full GC. @@ -198,18 +191,10 @@ public: template inline void apply_to_marked_objects(G1CMBitMap* bitmap, ApplyToMarkedClosure* closure); - void reset_bot() { - _bot_part.reset_bot(); - } - void update_bot() { _bot_part.update(); } - void update_bot_threshold() { - _bot_part.set_threshold(top()); - } - private: // The remembered set for this region. HeapRegionRemSet* _rem_set; @@ -268,8 +253,6 @@ private: uint _node_index; - G1EvacFailureObjectsSet _evac_failure_objs; - void report_region_type_change(G1HeapRegionTraceType::Type to); // Returns whether the given object address refers to a dead object, and either the @@ -566,11 +549,6 @@ public: // Update the region state after a failed evacuation. void handle_evacuation_failure(); - // Record an object that failed evacuation within this region. - void record_evac_failure_obj(oop obj); - // Applies the given closure to all previously recorded objects - // that failed evacuation in ascending address order. - void process_and_drop_evac_failure_objs(ObjectClosure* closure); // Iterate over the objects overlapping the given memory region, applying cl // to all references in the region. This is a helper for @@ -585,20 +563,20 @@ public: // Routines for managing a list of code roots (attached to the // this region's RSet) that point into this heap region. - void add_strong_code_root(nmethod* nm); - void add_strong_code_root_locked(nmethod* nm); - void remove_strong_code_root(nmethod* nm); + void add_code_root(nmethod* nm); + void add_code_root_locked(nmethod* nm); + void remove_code_root(nmethod* nm); // Applies blk->do_code_blob() to each of the entries in - // the strong code roots list for this region - void strong_code_roots_do(CodeBlobClosure* blk) const; + // the code roots list for this region + void code_roots_do(CodeBlobClosure* blk) const; uint node_index() const { return _node_index; } void set_node_index(uint node_index) { _node_index = node_index; } - // Verify that the entries on the strong code root list for this + // Verify that the entries on the code root list for this // region are live and include at least one pointer into this region. - void verify_strong_code_roots(VerifyOption vo, bool* failures) const; + void verify_code_roots(VerifyOption vo, bool* failures) const; void print() const; void print_on(outputStream* st) const; @@ -618,9 +596,6 @@ public: // full GC. void verify(VerifyOption vo, bool *failures) const; - // Verify using the "prev" marking information - void verify() const; - void verify_rem_set(VerifyOption vo, bool *failures) const; void verify_rem_set() const; }; diff --git a/src/hotspot/share/gc/g1/heapRegion.inline.hpp b/src/hotspot/share/gc/g1/heapRegion.inline.hpp index 120715562ab6f4dee618faa8160e7de852c84294..2f78f30b4198e24ecc2c3993be7814b820475b99 100644 --- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp @@ -30,7 +30,6 @@ #include "gc/g1/g1BlockOffsetTable.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp" -#include "gc/g1/g1EvacFailureObjectsSet.inline.hpp" #include "gc/g1/g1Predictions.hpp" #include "gc/g1/g1SegmentedArray.inline.hpp" #include "oops/oop.inline.hpp" @@ -104,12 +103,8 @@ inline bool HeapRegion::is_obj_dead_with_size(const oop obj, const G1CMBitMap* c } inline bool HeapRegion::block_is_obj(const HeapWord* p) const { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - - if (!this->is_in(p)) { - assert(is_continues_humongous(), "This case can only happen for humongous regions"); - return (p == humongous_start_region()->bottom()); - } + assert(p >= bottom() && p < top(), "precondition"); + assert(!is_continues_humongous(), "p must point to block-start"); // When class unloading is enabled it is not safe to only consider top() to conclude if the // given pointer is a valid object. The situation can occur both for class unloading in a // Full GC and during a concurrent cycle. @@ -118,9 +113,9 @@ inline bool HeapRegion::block_is_obj(const HeapWord* p) const { // During a concurrent cycle class unloading is done after marking is complete and objects // for the unloaded classes will be stale until the regions are collected. if (ClassUnloading) { - return !g1h->is_obj_dead(cast_to_oop(p), this); + return !G1CollectedHeap::heap()->is_obj_dead(cast_to_oop(p), this); } - return p < top(); + return true; } inline size_t HeapRegion::block_size_using_bitmap(const HeapWord* addr, const G1CMBitMap* const prev_bitmap) const { @@ -188,10 +183,6 @@ inline void HeapRegion::reset_skip_compacting_after_full_gc() { } inline void HeapRegion::reset_after_full_gc_common() { - if (is_empty()) { - reset_bot(); - } - // Clear unused heap memory in debug builds. if (ZapUnusedHeapArea) { mangle_unused_area(); @@ -236,33 +227,17 @@ inline HeapWord* HeapRegion::allocate(size_t min_word_size, return allocate_impl(min_word_size, desired_word_size, actual_word_size); } -inline HeapWord* HeapRegion::bot_threshold_for_addr(const void* addr) { - HeapWord* threshold = _bot_part.threshold_for_addr(addr); - assert(threshold >= addr, - "threshold must be at or after given address. " PTR_FORMAT " >= " PTR_FORMAT, - p2i(threshold), p2i(addr)); - assert(is_old(), - "Should only calculate BOT threshold for old regions. addr: " PTR_FORMAT " region:" HR_FORMAT, - p2i(addr), HR_FORMAT_PARAMS(this)); - return threshold; -} - -inline void HeapRegion::update_bot_crossing_threshold(HeapWord** threshold, HeapWord* obj_start, HeapWord* obj_end) { +inline void HeapRegion::update_bot_for_obj(HeapWord* obj_start, size_t obj_size) { assert(is_old(), "should only do BOT updates for old regions"); - assert(is_in(obj_start), "obj_start must be in this region: " HR_FORMAT - " obj_start " PTR_FORMAT " obj_end " PTR_FORMAT " threshold " PTR_FORMAT, - HR_FORMAT_PARAMS(this), - p2i(obj_start), p2i(obj_end), p2i(*threshold)); - _bot_part.alloc_block_work(threshold, obj_start, obj_end); -} -inline void HeapRegion::update_bot_at(HeapWord* obj_start, size_t obj_size) { - HeapWord* threshold = bot_threshold_for_addr(obj_start); HeapWord* obj_end = obj_start + obj_size; - if (obj_end > threshold) { - update_bot_crossing_threshold(&threshold, obj_start, obj_end); - } + assert(is_in(obj_start), "obj_start must be in this region: " HR_FORMAT + " obj_start " PTR_FORMAT " obj_end " PTR_FORMAT, + HR_FORMAT_PARAMS(this), + p2i(obj_start), p2i(obj_end)); + + _bot_part.alloc_block(obj_start, obj_end); } inline void HeapRegion::note_start_of_marking() { @@ -443,8 +418,4 @@ inline void HeapRegion::record_surv_words_in_group(size_t words_survived) { _surv_rate_group->record_surviving_words(age_in_group, words_survived); } -inline void HeapRegion::record_evac_failure_obj(oop obj) { - _evac_failure_objs.record(obj); -} - #endif // SHARE_GC_G1_HEAPREGION_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/heapRegionBounds.hpp b/src/hotspot/share/gc/g1/heapRegionBounds.hpp index 5e748de59286b814d0c9fdc6aca41535f8b42144..5a6db9fac3b145a9706ce805d37ea0629e6dff41 100644 --- a/src/hotspot/share/gc/g1/heapRegionBounds.hpp +++ b/src/hotspot/share/gc/g1/heapRegionBounds.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ #ifndef SHARE_GC_G1_HEAPREGIONBOUNDS_HPP #define SHARE_GC_G1_HEAPREGIONBOUNDS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class HeapRegionBounds : public AllStatic { private: diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp index 694496975f5d30f72ff10b2fe446630de18cd386..9e6c31ffdc11aa55a49b52de10325ce9c2b4c38f 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp @@ -60,7 +60,7 @@ void HeapRegionRemSet::initialize(MemRegion reserved) { vm_exit_during_initialization("Can not represent all cards in a card region within uint."); } - _split_card_shift = CardBitsWithinCardRegion + CardTable::card_shift; + _split_card_shift = CardBitsWithinCardRegion + CardTable::card_shift(); _split_card_mask = ((size_t)1 << _split_card_shift) - 1; // Check if the card region/region within cards combination can cover the heap. @@ -122,19 +122,19 @@ void HeapRegionRemSet::print_static_mem_size(outputStream* out) { // When concurrent readers access the contains() function // (during the evacuation phase) no removals are allowed. -void HeapRegionRemSet::add_strong_code_root(nmethod* nm) { +void HeapRegionRemSet::add_code_root(nmethod* nm) { assert(nm != NULL, "sanity"); assert((!CodeCache_lock->owned_by_self() || SafepointSynchronize::is_at_safepoint()), - "should call add_strong_code_root_locked instead. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s", + "should call add_code_root_locked instead. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s", BOOL_TO_STR(CodeCache_lock->owned_by_self()), BOOL_TO_STR(SafepointSynchronize::is_at_safepoint())); // Optimistic unlocked contains-check if (!_code_roots.contains(nm)) { MutexLocker ml(&_m, Mutex::_no_safepoint_check_flag); - add_strong_code_root_locked(nm); + add_code_root_locked(nm); } } -void HeapRegionRemSet::add_strong_code_root_locked(nmethod* nm) { +void HeapRegionRemSet::add_code_root_locked(nmethod* nm) { assert(nm != NULL, "sanity"); assert((CodeCache_lock->owned_by_self() || (SafepointSynchronize::is_at_safepoint() && @@ -145,7 +145,7 @@ void HeapRegionRemSet::add_strong_code_root_locked(nmethod* nm) { _code_roots.add(nm); } -void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) { +void HeapRegionRemSet::remove_code_root(nmethod* nm) { assert(nm != NULL, "sanity"); assert_locked_or_safepoint(CodeCache_lock); @@ -156,14 +156,14 @@ void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) { guarantee(!_code_roots.contains(nm), "duplicate entry found"); } -void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) const { +void HeapRegionRemSet::code_roots_do(CodeBlobClosure* blk) const { _code_roots.nmethods_do(blk); } -void HeapRegionRemSet::clean_strong_code_roots(HeapRegion* hr) { +void HeapRegionRemSet::clean_code_roots(HeapRegion* hr) { _code_roots.clean(hr); } -size_t HeapRegionRemSet::strong_code_roots_mem_size() { +size_t HeapRegionRemSet::code_roots_mem_size() { return _code_roots.mem_size(); } diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp index 2a1b3c5527be9ba4d073557ee41035fe0bcec228..04b585661f837b5b03c616420827415484ac8f75 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp @@ -73,11 +73,11 @@ public: } bool is_empty() const { - return (strong_code_roots_list_length() == 0) && cardset_is_empty(); + return (code_roots_list_length() == 0) && cardset_is_empty(); } bool occupancy_less_or_equal_than(size_t occ) const { - return (strong_code_roots_list_length() == 0) && _card_set.occupancy_less_or_equal_to(occ); + return (code_roots_list_length() == 0) && _card_set.occupancy_less_or_equal_to(occ); } // Iterate the card based remembered set for merging them into the card table. @@ -128,12 +128,12 @@ public: G1SegmentedArrayMemoryStats card_set_memory_stats() const; - // The actual # of bytes this hr_remset takes up. Also includes the strong code + // The actual # of bytes this hr_remset takes up. Also includes the code // root set. size_t mem_size() { return _card_set.mem_size() - + (sizeof(HeapRegionRemSet) - sizeof(G1CardSet)) // Avoid double-counting G1CardSet. - + strong_code_roots_mem_size(); + + (sizeof(HeapRegionRemSet) - sizeof(G1CardSet)) // Avoid double-counting G1CardSet. + + code_roots_mem_size(); } size_t wasted_mem_size() { @@ -154,30 +154,29 @@ public: // Routines for managing the list of code roots that point into // the heap region that owns this RSet. - void add_strong_code_root(nmethod* nm); - void add_strong_code_root_locked(nmethod* nm); - void remove_strong_code_root(nmethod* nm); + void add_code_root(nmethod* nm); + void add_code_root_locked(nmethod* nm); + void remove_code_root(nmethod* nm); - // Applies blk->do_code_blob() to each of the entries in - // the strong code roots list - void strong_code_roots_do(CodeBlobClosure* blk) const; + // Applies blk->do_code_blob() to each of the entries in _code_roots + void code_roots_do(CodeBlobClosure* blk) const; - void clean_strong_code_roots(HeapRegion* hr); + void clean_code_roots(HeapRegion* hr); - // Returns the number of elements in the strong code roots list - size_t strong_code_roots_list_length() const { + // Returns the number of elements in _code_roots + size_t code_roots_list_length() const { return _code_roots.length(); } - // Returns true if the strong code roots contains the given + // Returns true if the code roots contains the given // nmethod. - bool strong_code_roots_list_contains(nmethod* nm) { + bool code_roots_list_contains(nmethod* nm) { return _code_roots.contains(nm); } // Returns the amount of memory, in bytes, currently - // consumed by the strong code roots. - size_t strong_code_roots_mem_size(); + // consumed by the code roots. + size_t code_roots_mem_size(); static void invalidate_from_card_cache(uint start_idx, size_t num_regions) { G1FromCardCache::invalidate(start_idx, num_regions); diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.inline.hpp b/src/hotspot/share/gc/g1/heapRegionRemSet.inline.hpp index eaa2d7f1e56fa38b3387fad247c761ffe22314bd..4bb8e6c4ff90212a5bcedd8a3e9b64d8c8c94b1d 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.inline.hpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.inline.hpp @@ -118,18 +118,15 @@ inline void HeapRegionRemSet::iterate_for_merge(CardOrRangeVisitor& cl) { void HeapRegionRemSet::split_card(OopOrNarrowOopStar from, uint& card_region, uint& card_within_region) const { size_t offset = pointer_delta(from, _heap_base_address, 1); card_region = (uint)(offset >> _split_card_shift); - card_within_region = (uint)((offset & _split_card_mask) >> CardTable::card_shift); + card_within_region = (uint)((offset & _split_card_mask) >> CardTable::card_shift()); assert(card_within_region < ((uint)1 << G1CardSetContainer::LogCardsPerRegionLimit), "must be"); } void HeapRegionRemSet::add_reference(OopOrNarrowOopStar from, uint tid) { - RemSetState state = _state; - if (state == Untracked) { - return; - } + assert(_state != Untracked, "must be"); uint cur_idx = _hr->hrm_index(); - uintptr_t from_card = uintptr_t(from) >> CardTable::card_shift; + uintptr_t from_card = uintptr_t(from) >> CardTable::card_shift(); if (G1FromCardCache::contains_or_replace(tid, cur_idx, from_card)) { // We can't check whether the card is in the remembered set - the card container diff --git a/src/hotspot/share/gc/g1/heapRegionTracer.hpp b/src/hotspot/share/gc/g1/heapRegionTracer.hpp index bdfcd1cfd8e2599016e0d79daeb25d0b3ed1a4a7..647744d0d5e2362029e285109e57a3d1216db05b 100644 --- a/src/hotspot/share/gc/g1/heapRegionTracer.hpp +++ b/src/hotspot/share/gc/g1/heapRegionTracer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ #define SHARE_GC_G1_HEAPREGIONTRACER_HPP #include "gc/g1/g1HeapRegionTraceType.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class HeapRegionTracer : AllStatic { public: diff --git a/src/hotspot/share/gc/g1/heapRegionType.hpp b/src/hotspot/share/gc/g1/heapRegionType.hpp index 74807c37746598eda34e1c32c53a8a87c1528333..9e1c79ea0d052433a7993249a89cfa97797cdf1b 100644 --- a/src/hotspot/share/gc/g1/heapRegionType.hpp +++ b/src/hotspot/share/gc/g1/heapRegionType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ #define SHARE_GC_G1_HEAPREGIONTYPE_HPP #include "gc/g1/g1HeapRegionTraceType.hpp" +#include "utilities/globalDefinitions.hpp" #define hrt_assert_is_valid(tag) \ assert(is_valid((tag)), "invalid HR type: %u", (uint) (tag)) diff --git a/src/hotspot/share/gc/parallel/objectStartArray.cpp b/src/hotspot/share/gc/parallel/objectStartArray.cpp index c9c7ac6b796df37977bc38fa5852af1e618f82bf..3e4820aa9414f8b3e21d3af6fb6847928453d752 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.cpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.cpp @@ -31,26 +31,26 @@ #include "services/memTracker.hpp" #include "utilities/align.hpp" -uint ObjectStartArray::block_shift = 0; -uint ObjectStartArray::block_size = 0; -uint ObjectStartArray::block_size_in_words = 0; +uint ObjectStartArray::_card_shift = 0; +uint ObjectStartArray::_card_size = 0; +uint ObjectStartArray::_card_size_in_words = 0; void ObjectStartArray::initialize_block_size(uint card_shift) { - block_shift = card_shift; - block_size = 1 << block_shift; - block_size_in_words = block_size / sizeof(HeapWord); + _card_shift = card_shift; + _card_size = 1 << _card_shift; + _card_size_in_words = _card_size / sizeof(HeapWord); } void ObjectStartArray::initialize(MemRegion reserved_region) { // We're based on the assumption that we use the same // size blocks as the card table. - assert((int)block_size == (int)CardTable::card_size, "Sanity"); - assert(block_size <= MaxBlockSize, "block_size must be less than or equal to " UINT32_FORMAT, MaxBlockSize); + assert(_card_size == CardTable::card_size(), "Sanity"); + assert(_card_size <= MaxBlockSize, "block_size must be less than or equal to " UINT32_FORMAT, MaxBlockSize); // Calculate how much space must be reserved _reserved_region = reserved_region; - size_t bytes_to_reserve = reserved_region.word_size() / block_size_in_words; + size_t bytes_to_reserve = reserved_region.word_size() / _card_size_in_words; assert(bytes_to_reserve > 0, "Sanity"); bytes_to_reserve = @@ -68,15 +68,9 @@ void ObjectStartArray::initialize(MemRegion reserved_region) { _virtual_space.initialize(backing_store); _raw_base = (jbyte*)_virtual_space.low_boundary(); + assert(_raw_base != nullptr, "set from the backing_store"); - if (_raw_base == NULL) { - vm_exit_during_initialization("Could not get raw_base address"); - } - - MemTracker::record_virtual_memory_type((address)_raw_base, mtGC); - - - _offset_base = _raw_base - (size_t(reserved_region.start()) >> block_shift); + _offset_base = _raw_base - (size_t(reserved_region.start()) >> _card_shift); _covered_region.set_start(reserved_region.start()); _covered_region.set_word_size(0); @@ -91,10 +85,10 @@ void ObjectStartArray::set_covered_region(MemRegion mr) { HeapWord* low_bound = mr.start(); HeapWord* high_bound = mr.end(); - assert((uintptr_t(low_bound) & (block_size - 1)) == 0, "heap must start at block boundary"); - assert((uintptr_t(high_bound) & (block_size - 1)) == 0, "heap must end at block boundary"); + assert((uintptr_t(low_bound) & (_card_size - 1)) == 0, "heap must start at block boundary"); + assert((uintptr_t(high_bound) & (_card_size - 1)) == 0, "heap must end at block boundary"); - size_t requested_blocks_size_in_bytes = mr.word_size() / block_size_in_words; + size_t requested_blocks_size_in_bytes = mr.word_size() / _card_size_in_words; // Only commit memory in page sized chunks requested_blocks_size_in_bytes = @@ -138,8 +132,15 @@ bool ObjectStartArray::object_starts_in_range(HeapWord* start_addr, "Range is wrong. start_addr (" PTR_FORMAT ") is after end_addr (" PTR_FORMAT ")", p2i(start_addr), p2i(end_addr)); + assert(is_aligned(start_addr, _card_size), "precondition"); + + if (start_addr == end_addr) { + // No objects in empty range. + return false; + } + jbyte* start_block = block_for_addr(start_addr); - jbyte* end_block = block_for_addr(end_addr); + jbyte* end_block = block_for_addr(end_addr - 1); for (jbyte* block = start_block; block <= end_block; block++) { if (*block != clean_block) { diff --git a/src/hotspot/share/gc/parallel/objectStartArray.hpp b/src/hotspot/share/gc/parallel/objectStartArray.hpp index 02c91d20ded3c2b9bac53059c934a2b90d517ab9..06005fc0075616cb5a7b4cfd790ff0f9336bc75b 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.hpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.hpp @@ -41,21 +41,22 @@ class ObjectStartArray : public CHeapObj { private: PSVirtualSpace _virtual_space; MemRegion _reserved_region; + // The committed (old-gen heap) virtual space this object-start-array covers. MemRegion _covered_region; MemRegion _blocks_region; jbyte* _raw_base; jbyte* _offset_base; + static uint _card_shift; + static uint _card_size; + static uint _card_size_in_words; + public: enum BlockValueConstants { clean_block = -1 }; - static uint block_shift; - static uint block_size; - static uint block_size_in_words; - // Maximum size an offset table entry can cover. This maximum is derived from that // we need an extra bit for possible offsets in the byte for backskip values, leaving 2^7 possible offsets. // Minimum object alignment is 8 bytes (2^3), so we can at most represent 2^10 offsets within a BOT value. @@ -64,13 +65,24 @@ class ObjectStartArray : public CHeapObj { // Initialize block size based on card size static void initialize_block_size(uint card_shift); + static uint card_shift() { + return _card_shift; + } + + static uint card_size() { + return _card_size; + } + static uint card_size_in_words() { + return _card_size_in_words; + } + protected: // Mapping from address to object start array entry jbyte* block_for_addr(void* p) const { assert(_covered_region.contains(p), "out of bounds access to object start array"); - jbyte* result = &_offset_base[uintptr_t(p) >> block_shift]; + jbyte* result = &_offset_base[uintptr_t(p) >> _card_shift]; assert(_blocks_region.contains(result), "out of bounds result in byte_for"); return result; @@ -81,7 +93,7 @@ class ObjectStartArray : public CHeapObj { assert(_blocks_region.contains(p), "out of bounds access to object start array"); size_t delta = pointer_delta(p, _offset_base, sizeof(jbyte)); - HeapWord* result = (HeapWord*) (delta << block_shift); + HeapWord* result = (HeapWord*) (delta << _card_shift); assert(_covered_region.contains(result), "out of bounds accessor from card marking array"); return result; @@ -104,7 +116,7 @@ class ObjectStartArray : public CHeapObj { } size_t delta = pointer_delta(p, _offset_base, sizeof(jbyte)); - HeapWord* result = (HeapWord*) (delta << block_shift); + HeapWord* result = (HeapWord*) (delta << _card_shift); result += *p; assert(_covered_region.contains(result), @@ -153,9 +165,11 @@ class ObjectStartArray : public CHeapObj { return *block != clean_block; } - // Return true if an object starts in the range of heap addresses. - // If an object starts at an address corresponding to - // "start", the method will return true. + // Return true iff an object starts in + // [start_addr, end_addr_aligned_up) + // where + // end_addr_aligned_up = align_up(end_addr, _card_size) + // Precondition: start_addr is card-size aligned bool object_starts_in_range(HeapWord* start_addr, HeapWord* end_addr) const; }; diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index d0c1f29bd97bbca3221de369326753a201cb4a2e..3a4774d15ca5f523265c3bbbe1d23d27618ffc07 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -645,8 +645,10 @@ void ParallelScavengeHeap::prepare_for_verify() { PSHeapSummary ParallelScavengeHeap::create_ps_heap_summary() { PSOldGen* old = old_gen(); HeapWord* old_committed_end = (HeapWord*)old->virtual_space()->committed_high_addr(); - VirtualSpaceSummary old_summary(old->reserved().start(), old_committed_end, old->reserved().end()); - SpaceSummary old_space(old->reserved().start(), old_committed_end, old->used_in_bytes()); + HeapWord* old_reserved_start = old->reserved().start(); + HeapWord* old_reserved_end = old->reserved().end(); + VirtualSpaceSummary old_summary(old_reserved_start, old_committed_end, old_reserved_end); + SpaceSummary old_space(old_reserved_start, old_committed_end, old->used_in_bytes()); PSYoungGen* young = young_gen(); VirtualSpaceSummary young_summary(young->reserved().start(), diff --git a/src/hotspot/share/gc/parallel/parallel_globals.hpp b/src/hotspot/share/gc/parallel/parallel_globals.hpp index 19953ca0b618cac9bc833a09315d86c7b011188b..b9202ce7cda81b21fecebdb4cbc9e3bde324f480 100644 --- a/src/hotspot/share/gc/parallel/parallel_globals.hpp +++ b/src/hotspot/share/gc/parallel/parallel_globals.hpp @@ -55,9 +55,6 @@ "limiter (a number between 0-100)") \ range(0, 100) \ \ - develop(uintx, GCWorkerDelayMillis, 0, \ - "Delay in scheduling GC workers (in milliseconds)") \ - \ product(bool, PSChunkLargeArrays, true, \ "Process large arrays in chunks") diff --git a/src/hotspot/share/gc/parallel/psCardTable.cpp b/src/hotspot/share/gc/parallel/psCardTable.cpp index ec186aec83f0151c9c8702afcfb46f5593813260..8f851d9f26e8cca43d605751819ce443f1714a6f 100644 --- a/src/hotspot/share/gc/parallel/psCardTable.cpp +++ b/src/hotspot/share/gc/parallel/psCardTable.cpp @@ -165,7 +165,6 @@ void PSCardTable::scavenge_contents_parallel(ObjectStartArray* start_array, uint stripe_number, uint stripe_total) { int ssize = 128; // Naked constant! Work unit = 64k. - int dirty_card_count = 0; // It is a waste to get here if empty. assert(sp->bottom() < sp->top(), "Should not be called if empty"); @@ -195,16 +194,6 @@ void PSCardTable::scavenge_contents_parallel(ObjectStartArray* start_array, HeapWord* slice_start = addr_for(worker_start_card); HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card)); -#ifdef ASSERT - if (GCWorkerDelayMillis > 0) { - // Delay 1 worker so that it proceeds after all the work - // has been completed. - if (stripe_number < 2) { - os::naked_sleep(GCWorkerDelayMillis); - } - } -#endif - // If there are not objects starting within the chunk, skip it. if (!start_array->object_starts_in_range(slice_start, slice_end)) { continue; @@ -422,284 +411,6 @@ bool PSCardTable::addr_is_marked_precise(void *addr) { return false; } -// Assumes that only the base or the end changes. This allows indentification -// of the region that is being resized. The -// CardTable::resize_covered_region() is used for the normal case -// where the covered regions are growing or shrinking at the high end. -// The method resize_covered_region_by_end() is analogous to -// CardTable::resize_covered_region() but -// for regions that grow or shrink at the low end. -void PSCardTable::resize_covered_region(MemRegion new_region) { - for (int i = 0; i < _cur_covered_regions; i++) { - if (_covered[i].start() == new_region.start()) { - // Found a covered region with the same start as the - // new region. The region is growing or shrinking - // from the start of the region. - resize_covered_region_by_start(new_region); - return; - } - if (_covered[i].start() > new_region.start()) { - break; - } - } - - int changed_region = -1; - for (int j = 0; j < _cur_covered_regions; j++) { - if (_covered[j].end() == new_region.end()) { - changed_region = j; - // This is a case where the covered region is growing or shrinking - // at the start of the region. - assert(changed_region != -1, "Don't expect to add a covered region"); - assert(_covered[changed_region].byte_size() != new_region.byte_size(), - "The sizes should be different here"); - resize_covered_region_by_end(changed_region, new_region); - return; - } - } - // This should only be a new covered region (where no existing - // covered region matches at the start or the end). - assert(_cur_covered_regions < _max_covered_regions, - "An existing region should have been found"); - resize_covered_region_by_start(new_region); -} - -void PSCardTable::resize_covered_region_by_start(MemRegion new_region) { - CardTable::resize_covered_region(new_region); - debug_only(verify_guard();) -} - -void PSCardTable::resize_covered_region_by_end(int changed_region, - MemRegion new_region) { - assert(SafepointSynchronize::is_at_safepoint(), - "Only expect an expansion at the low end at a GC"); - debug_only(verify_guard();) -#ifdef ASSERT - for (int k = 0; k < _cur_covered_regions; k++) { - if (_covered[k].end() == new_region.end()) { - assert(changed_region == k, "Changed region is incorrect"); - break; - } - } -#endif - - // Commit new or uncommit old pages, if necessary. - if (resize_commit_uncommit(changed_region, new_region)) { - // Set the new start of the committed region - resize_update_committed_table(changed_region, new_region); - } - - // Update card table entries - resize_update_card_table_entries(changed_region, new_region); - - // Update the covered region - resize_update_covered_table(changed_region, new_region); - - int ind = changed_region; - log_trace(gc, barrier)("CardTable::resize_covered_region: "); - log_trace(gc, barrier)(" _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT, - ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last())); - log_trace(gc, barrier)(" _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT, - ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last())); - log_trace(gc, barrier)(" byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT, - p2i(byte_for(_covered[ind].start())), p2i(byte_for(_covered[ind].last()))); - log_trace(gc, barrier)(" addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT, - p2i(addr_for((CardValue*) _committed[ind].start())), p2i(addr_for((CardValue*) _committed[ind].last()))); - - debug_only(verify_guard();) -} - -bool PSCardTable::resize_commit_uncommit(int changed_region, - MemRegion new_region) { - bool result = false; - // Commit new or uncommit old pages, if necessary. - MemRegion cur_committed = _committed[changed_region]; - assert(_covered[changed_region].end() == new_region.end(), - "The ends of the regions are expected to match"); - // Extend the start of this _committed region to - // to cover the start of any previous _committed region. - // This forms overlapping regions, but never interior regions. - HeapWord* min_prev_start = lowest_prev_committed_start(changed_region); - if (min_prev_start < cur_committed.start()) { - // Only really need to set start of "cur_committed" to - // the new start (min_prev_start) but assertion checking code - // below use cur_committed.end() so make it correct. - MemRegion new_committed = - MemRegion(min_prev_start, cur_committed.end()); - cur_committed = new_committed; - } -#ifdef ASSERT - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - assert(cur_committed.start() == align_up(cur_committed.start(), os::vm_page_size()), - "Starts should have proper alignment"); -#endif - - CardValue* new_start = byte_for(new_region.start()); - // Round down because this is for the start address - HeapWord* new_start_aligned = align_down((HeapWord*)new_start, os::vm_page_size()); - // The guard page is always committed and should not be committed over. - // This method is used in cases where the generation is growing toward - // lower addresses but the guard region is still at the end of the - // card table. That still makes sense when looking for writes - // off the end of the card table. - if (new_start_aligned < cur_committed.start()) { - // Expand the committed region - // - // Case A - // |+ guard +| - // |+ cur committed +++++++++| - // |+ new committed +++++++++++++++++| - // - // Case B - // |+ guard +| - // |+ cur committed +| - // |+ new committed +++++++| - // - // These are not expected because the calculation of the - // cur committed region and the new committed region - // share the same end for the covered region. - // Case C - // |+ guard +| - // |+ cur committed +| - // |+ new committed +++++++++++++++++| - // Case D - // |+ guard +| - // |+ cur committed +++++++++++| - // |+ new committed +++++++| - - HeapWord* new_end_for_commit = - MIN2(cur_committed.end(), _guard_region.start()); - if(new_start_aligned < new_end_for_commit) { - MemRegion new_committed = - MemRegion(new_start_aligned, new_end_for_commit); - os::commit_memory_or_exit((char*)new_committed.start(), - new_committed.byte_size(), !ExecMem, - "card table expansion"); - } - result = true; - } else if (new_start_aligned > cur_committed.start()) { - // Shrink the committed region -#if 0 // uncommitting space is currently unsafe because of the interactions - // of growing and shrinking regions. One region A can uncommit space - // that it owns but which is being used by another region B (maybe). - // Region B has not committed the space because it was already - // committed by region A. - MemRegion uncommit_region = committed_unique_to_self(changed_region, - MemRegion(cur_committed.start(), new_start_aligned)); - if (!uncommit_region.is_empty()) { - if (!os::uncommit_memory((char*)uncommit_region.start(), - uncommit_region.byte_size())) { - // If the uncommit fails, ignore it. Let the - // committed table resizing go even though the committed - // table will over state the committed space. - } - } -#else - assert(!result, "Should be false with current workaround"); -#endif - } - assert(_committed[changed_region].end() == cur_committed.end(), - "end should not change"); - return result; -} - -void PSCardTable::resize_update_committed_table(int changed_region, - MemRegion new_region) { - - CardValue* new_start = byte_for(new_region.start()); - // Set the new start of the committed region - HeapWord* new_start_aligned = align_down((HeapWord*)new_start, os::vm_page_size()); - MemRegion new_committed = MemRegion(new_start_aligned, - _committed[changed_region].end()); - _committed[changed_region] = new_committed; - _committed[changed_region].set_start(new_start_aligned); -} - -void PSCardTable::resize_update_card_table_entries(int changed_region, - MemRegion new_region) { - debug_only(verify_guard();) - MemRegion original_covered = _covered[changed_region]; - // Initialize the card entries. Only consider the - // region covered by the card table (_whole_heap) - CardValue* entry; - if (new_region.start() < _whole_heap.start()) { - entry = byte_for(_whole_heap.start()); - } else { - entry = byte_for(new_region.start()); - } - CardValue* end = byte_for(original_covered.start()); - // If _whole_heap starts at the original covered regions start, - // this loop will not execute. - while (entry < end) { *entry++ = clean_card; } -} - -void PSCardTable::resize_update_covered_table(int changed_region, - MemRegion new_region) { - // Update the covered region - _covered[changed_region].set_start(new_region.start()); - _covered[changed_region].set_word_size(new_region.word_size()); - - // reorder regions. There should only be at most 1 out - // of order. - for (int i = _cur_covered_regions-1 ; i > 0; i--) { - if (_covered[i].start() < _covered[i-1].start()) { - MemRegion covered_mr = _covered[i-1]; - _covered[i-1] = _covered[i]; - _covered[i] = covered_mr; - MemRegion committed_mr = _committed[i-1]; - _committed[i-1] = _committed[i]; - _committed[i] = committed_mr; - break; - } - } -#ifdef ASSERT - for (int m = 0; m < _cur_covered_regions-1; m++) { - assert(_covered[m].start() <= _covered[m+1].start(), - "Covered regions out of order"); - assert(_committed[m].start() <= _committed[m+1].start(), - "Committed regions out of order"); - } -#endif -} - -// Returns the start of any committed region that is lower than -// the target committed region (index ind) and that intersects the -// target region. If none, return start of target region. -// -// ------------- -// | | -// ------------- -// ------------ -// | target | -// ------------ -// ------------- -// | | -// ------------- -// ^ returns this -// -// ------------- -// | | -// ------------- -// ------------ -// | target | -// ------------ -// ------------- -// | | -// ------------- -// ^ returns this - -HeapWord* PSCardTable::lowest_prev_committed_start(int ind) const { - assert(_cur_covered_regions >= 0, "Expecting at least on region"); - HeapWord* min_start = _committed[ind].start(); - for (int j = 0; j < ind; j++) { - HeapWord* this_start = _committed[j].start(); - if ((this_start < min_start) && - !(_committed[j].intersection(_committed[ind])).is_empty()) { - min_start = this_start; - } - } - return min_start; -} - bool PSCardTable::is_in_young(oop obj) const { return ParallelScavengeHeap::heap()->is_in_young(obj); } diff --git a/src/hotspot/share/gc/parallel/psCardTable.hpp b/src/hotspot/share/gc/parallel/psCardTable.hpp index d912c6567412503e1c08ced94824b24d4b41c401..bfbaab7d7fc29e0f78e371bb2548a3bd2714f318 100644 --- a/src/hotspot/share/gc/parallel/psCardTable.hpp +++ b/src/hotspot/share/gc/parallel/psCardTable.hpp @@ -34,14 +34,6 @@ class PSPromotionManager; class PSCardTable: public CardTable { private: - // Support methods for resizing the card table. - // resize_commit_uncommit() returns true if the pages were committed or - // uncommitted - bool resize_commit_uncommit(int changed_region, MemRegion new_region); - void resize_update_card_table_entries(int changed_region, - MemRegion new_region); - void resize_update_committed_table(int changed_region, MemRegion new_region); - void resize_update_covered_table(int changed_region, MemRegion new_region); void verify_all_young_refs_precise_helper(MemRegion mr); @@ -84,19 +76,6 @@ class PSCardTable: public CardTable { // ReduceInitialCardMarks support bool is_in_young(oop obj) const; - // Adaptive size policy support - // Allows adjustment of the base and size of the covered regions - void resize_covered_region(MemRegion new_region); - // Finds the covered region to resize based on the start address - // of the covered regions. - void resize_covered_region_by_start(MemRegion new_region); - // Finds the covered region to resize based on the end address - // of the covered regions. - void resize_covered_region_by_end(int changed_region, MemRegion new_region); - // Finds the lowest start address of a covered region that is - // previous (i.e., lower index) to the covered region with index "ind". - HeapWord* lowest_prev_committed_start(int ind) const; - #ifdef ASSERT bool is_valid_card_address(CardValue* addr) { return (addr >= _byte_map) && (addr < _byte_map + _byte_map_size); diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.cpp b/src/hotspot/share/gc/parallel/psCompactionManager.cpp index 0a71ec80e3bd5fc5ed035649b179597f1ef67a40..c6bb7bf1e996b85e2efb11bf54cbe83e6f9d0ef5 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp @@ -70,7 +70,7 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { uint parallel_gc_threads = ParallelScavengeHeap::heap()->workers().max_workers(); assert(_manager_array == NULL, "Attempt to initialize twice"); - _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1, mtGC); + _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads, mtGC); _oop_task_queues = new OopTaskQueueSet(parallel_gc_threads); _objarray_task_queues = new ObjArrayTaskQueueSet(parallel_gc_threads); @@ -84,9 +84,6 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { region_task_queues()->register_queue(i, _manager_array[i]->region_stack()); } - // The VMThread gets its own ParCompactionManager, which is not available - // for work stealing. - _manager_array[parallel_gc_threads] = new ParCompactionManager(); assert(ParallelScavengeHeap::heap()->workers().max_workers() != 0, "Not initialized?"); @@ -97,14 +94,14 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { void ParCompactionManager::reset_all_bitmap_query_caches() { uint parallel_gc_threads = ParallelScavengeHeap::heap()->workers().max_workers(); - for (uint i=0; i<=parallel_gc_threads; i++) { + for (uint i=0; ireset_bitmap_query_cache(); } } void ParCompactionManager::flush_all_string_dedup_requests() { uint parallel_gc_threads = ParallelScavengeHeap::heap()->workers().max_workers(); - for (uint i=0; i<=parallel_gc_threads; i++) { + for (uint i=0; iflush_string_dedup_requests(); } } @@ -116,12 +113,24 @@ ParCompactionManager::gc_thread_compaction_manager(uint index) { return _manager_array[index]; } +bool ParCompactionManager::transfer_from_overflow_stack(ObjArrayTask& task) { + while (_objarray_stack.pop_overflow(task)) { + if (!_objarray_stack.try_push_to_taskqueue(task)) { + return true; + } + } + return false; +} + void ParCompactionManager::follow_marking_stacks() { do { - // Drain the overflow stack first, to allow stealing from the marking stack. + // First, try to move tasks from the overflow stack into the shared buffer, so + // that other threads can steal. Otherwise process the overflow stack first. oop obj; while (marking_stack()->pop_overflow(obj)) { - follow_contents(obj); + if (!marking_stack()->try_push_to_taskqueue(obj)) { + follow_contents(obj); + } } while (marking_stack()->pop_local(obj)) { follow_contents(obj); @@ -129,7 +138,7 @@ void ParCompactionManager::follow_marking_stacks() { // Process ObjArrays one at a time to avoid marking stack bloat. ObjArrayTask task; - if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) { + if (transfer_from_overflow_stack(task) || _objarray_stack.pop_local(task)) { follow_array((objArrayOop)task.obj(), task.index()); } } while (!marking_stacks_empty()); @@ -184,14 +193,14 @@ void ParCompactionManager::remove_all_shadow_regions() { #ifdef ASSERT void ParCompactionManager::verify_all_marking_stack_empty() { uint parallel_gc_threads = ParallelGCThreads; - for (uint i = 0; i <= parallel_gc_threads; i++) { + for (uint i = 0; i < parallel_gc_threads; i++) { assert(_manager_array[i]->marking_stacks_empty(), "Marking stack should be empty"); } } void ParCompactionManager::verify_all_region_stack_empty() { uint parallel_gc_threads = ParallelGCThreads; - for (uint i = 0; i <= parallel_gc_threads; i++) { + for (uint i = 0; i < parallel_gc_threads; i++) { assert(_manager_array[i]->region_stack()->is_empty(), "Region stack should be empty"); } } diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.hpp index 2e73da920b5f0f8bc16da9b21d16cdc10e6ed5ce..0cb5d33e0f5476b6c3b517ff04d87418bc0a1d3b 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp @@ -97,6 +97,7 @@ class ParCompactionManager : public CHeapObj { static void initialize(ParMarkBitMap* mbm); + bool transfer_from_overflow_stack(ObjArrayTask& task); protected: // Array of task queues. Needed by the task terminator. static RegionTaskQueueSet* region_task_queues() { return _region_task_queues; } @@ -147,7 +148,9 @@ class ParCompactionManager : public CHeapObj { RegionTaskQueue* region_stack() { return &_region_stack; } - static ParCompactionManager* get_vmthread_cm() { return _manager_array[ParallelGCThreads]; } + // Get the compaction manager when doing evacuation work from the VM thread. + // Simply use the first compaction manager here. + static ParCompactionManager* get_vmthread_cm() { return _manager_array[0]; } ParCompactionManager(); diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp index 4f689ec72518bc156cbb9e8f3051cb6b80cda26f..591341af8619c515c3754d3c42f4d07bdd3c2789 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.cpp +++ b/src/hotspot/share/gc/parallel/psOldGen.cpp @@ -50,10 +50,6 @@ void PSOldGen::initialize(ReservedSpace rs, size_t initial_size, size_t alignmen initialize_virtual_space(rs, initial_size, alignment); initialize_work(perf_data_name, level); - // The old gen can grow to max_gen_size(). _reserve reflects only - // the current maximum that can be committed. - assert(_reserved.byte_size() <= max_gen_size(), "Consistency check"); - initialize_performance_counters(perf_data_name, level); } @@ -69,66 +65,51 @@ void PSOldGen::initialize_virtual_space(ReservedSpace rs, } void PSOldGen::initialize_work(const char* perf_data_name, int level) { - // - // Basic memory initialization - // - - MemRegion limit_reserved((HeapWord*)virtual_space()->low_boundary(), - heap_word_size(max_gen_size())); - assert(limit_reserved.byte_size() == max_gen_size(), - "word vs bytes confusion"); - // - // Object start stuff - // + MemRegion const reserved_mr = reserved(); + assert(reserved_mr.byte_size() == max_gen_size(), "invariant"); - start_array()->initialize(limit_reserved); + // Object start stuff: for all reserved memory + start_array()->initialize(reserved_mr); - _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(), - (HeapWord*)virtual_space()->high_boundary()); + // Card table stuff: for all committed memory + MemRegion committed_mr((HeapWord*)virtual_space()->low(), + (HeapWord*)virtual_space()->high()); - // - // Card table stuff - // - - MemRegion cmr((HeapWord*)virtual_space()->low(), - (HeapWord*)virtual_space()->high()); if (ZapUnusedHeapArea) { // Mangle newly committed space immediately rather than // waiting for the initialization of the space even though // mangling is related to spaces. Doing it here eliminates // the need to carry along information that a complete mangling // (bottom to end) needs to be done. - SpaceMangler::mangle_region(cmr); + SpaceMangler::mangle_region(committed_mr); } ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); PSCardTable* ct = heap->card_table(); - ct->resize_covered_region(cmr); + ct->resize_covered_region(committed_mr); // Verify that the start and end of this generation is the start of a card. // If this wasn't true, a single card could span more than one generation, // which would cause problems when we commit/uncommit memory, and when we // clear and dirty cards. - guarantee(ct->is_card_aligned(_reserved.start()), "generation must be card aligned"); - if (_reserved.end() != heap->reserved_region().end()) { - // Don't check at the very end of the heap as we'll assert that we're probing off - // the end if we try. - guarantee(ct->is_card_aligned(_reserved.end()), "generation must be card aligned"); - } + guarantee(ct->is_card_aligned(reserved_mr.start()), "generation must be card aligned"); + // Check the heap layout documented at `class ParallelScavengeHeap`. + assert(reserved_mr.end() != heap->reserved_region().end(), "invariant"); + guarantee(ct->is_card_aligned(reserved_mr.end()), "generation must be card aligned"); // // ObjectSpace stuff // _object_space = new MutableSpace(virtual_space()->alignment()); - object_space()->initialize(cmr, + object_space()->initialize(committed_mr, SpaceDecorator::Clear, SpaceDecorator::Mangle, MutableSpace::SetupPages, &ParallelScavengeHeap::heap()->workers()); // Update the start_array - start_array()->set_covered_region(cmr); + start_array()->set_covered_region(committed_mr); } void PSOldGen::initialize_performance_counters(const char* perf_data_name, int level) { @@ -152,7 +133,7 @@ size_t PSOldGen::num_iterable_blocks() const { void PSOldGen::object_iterate_block(ObjectClosure* cl, size_t block_index) { size_t block_word_size = IterateBlockSize / HeapWordSize; - assert((block_word_size % (ObjectStartArray::block_size)) == 0, + assert((block_word_size % (ObjectStartArray::card_size())) == 0, "Block size not a multiple of start_array block"); MutableSpace *space = object_space(); @@ -314,7 +295,6 @@ void PSOldGen::resize(size_t desired_free_space) { // Adjust according to our min and max new_size = clamp(new_size, min_gen_size(), max_gen_size()); - assert(max_gen_size() >= reserved().byte_size(), "max new size problem?"); new_size = align_up(new_size, alignment); const size_t current_size = capacity_in_bytes(); @@ -400,12 +380,11 @@ void PSOldGen::verify() { } class VerifyObjectStartArrayClosure : public ObjectClosure { - PSOldGen* _old_gen; ObjectStartArray* _start_array; public: - VerifyObjectStartArrayClosure(PSOldGen* old_gen, ObjectStartArray* start_array) : - _old_gen(old_gen), _start_array(start_array) { } + VerifyObjectStartArrayClosure(ObjectStartArray* start_array) : + _start_array(start_array) { } virtual void do_object(oop obj) { HeapWord* test_addr = cast_from_oop(obj) + 1; @@ -415,7 +394,7 @@ class VerifyObjectStartArrayClosure : public ObjectClosure { }; void PSOldGen::verify_object_start_array() { - VerifyObjectStartArrayClosure check( this, &_start_array ); + VerifyObjectStartArrayClosure check(&_start_array); object_iterate(&check); } diff --git a/src/hotspot/share/gc/parallel/psOldGen.hpp b/src/hotspot/share/gc/parallel/psOldGen.hpp index 53947a948984caffa548ba7dfb3880599dc96d5f..713098056c6d9939d3a5ecfc9f5b903ee78c52cb 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.hpp +++ b/src/hotspot/share/gc/parallel/psOldGen.hpp @@ -34,9 +34,7 @@ class PSOldGen : public CHeapObj { friend class VMStructs; - private: - MemRegion _reserved; // Used for simple containment tests PSVirtualSpace* _virtual_space; // Controls mapping and unmapping of virtual mem ObjectStartArray _start_array; // Keeps track of where objects start in a 512b block MutableSpace* _object_space; // Where all the objects live @@ -99,16 +97,20 @@ class PSOldGen : public CHeapObj { PSOldGen(ReservedSpace rs, size_t initial_size, size_t min_size, size_t max_size, const char* perf_data_name, int level); - MemRegion reserved() const { return _reserved; } + MemRegion reserved() const { + return MemRegion((HeapWord*)(_virtual_space->low_boundary()), + (HeapWord*)(_virtual_space->high_boundary())); + } + size_t max_gen_size() const { return _max_gen_size; } size_t min_gen_size() const { return _min_gen_size; } bool is_in(const void* p) const { - return _virtual_space->contains((void *)p); + return _virtual_space->is_in_committed((void *)p); } bool is_in_reserved(const void* p) const { - return reserved().contains(p); + return _virtual_space->is_in_reserved(p); } MutableSpace* object_space() const { return _object_space; } diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 2a3d95192b6df19b9bfe7d65ac60efa75194db89..cb8dd999f5dabbbbaef66c7a4237ba53eb1b6d8a 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1041,9 +1041,9 @@ void PSParallelCompact::post_compact() PSCardTable* ct = heap->card_table(); MemRegion old_mr = heap->old_gen()->reserved(); if (young_gen_empty) { - ct->clear(MemRegion(old_mr.start(), old_mr.end())); + ct->clear(old_mr); } else { - ct->invalidate(MemRegion(old_mr.start(), old_mr.end())); + ct->invalidate(old_mr); } // Delete metaspaces for unloaded class loaders and clean up loader_data graph @@ -1595,8 +1595,7 @@ void PSParallelCompact::summary_phase_msg(SpaceId dst_space_id, } #endif // #ifndef PRODUCT -void PSParallelCompact::summary_phase(ParCompactionManager* cm, - bool maximum_compaction) +void PSParallelCompact::summary_phase(bool maximum_compaction) { GCTraceTime(Info, gc, phases) tm("Summary Phase", &_gc_timer); @@ -1735,10 +1734,6 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { _gc_timer.register_gc_start(); _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start()); - TimeStamp marking_start; - TimeStamp compaction_start; - TimeStamp collection_exit; - GCCause::Cause gc_cause = heap->gc_cause(); PSYoungGen* young_gen = heap->young_gen(); PSOldGen* old_gen = heap->old_gen(); @@ -1760,9 +1755,6 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { const PreGenGCValues pre_gc_values = heap->get_pre_gc_values(); - // Get the compaction manager reserved for the VM thread. - ParCompactionManager* const vmthread_cm = ParCompactionManager::get_vmthread_cm(); - { const uint active_workers = WorkerPolicy::calc_active_workers(ParallelScavengeHeap::heap()->workers().max_workers(), @@ -1791,12 +1783,11 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { ref_processor()->start_discovery(maximum_heap_compaction); - marking_start.update(); - marking_phase(vmthread_cm, &_gc_tracer); + marking_phase(&_gc_tracer); bool max_on_system_gc = UseMaximumCompactionOnSystemGC && GCCause::is_user_requested_gc(gc_cause); - summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc); + summary_phase(maximum_heap_compaction || max_on_system_gc); #if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_active(), "Sanity"); @@ -1807,7 +1798,6 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { // needed by the compaction for filling holes in the dense prefix. adjust_roots(); - compaction_start.update(); compact(); ParCompactionManager::verify_all_region_stack_empty(); @@ -1922,15 +1912,9 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { old_gen->object_space()->check_mangled_unused_area_complete(); } - collection_exit.update(); - heap->print_heap_after_gc(); heap->trace_heap_after_gc(&_gc_tracer); - log_debug(gc, task, time)("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT, - marking_start.ticks(), compaction_start.ticks(), - collection_exit.ticks()); - AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections()); _gc_timer.register_gc_end(); @@ -1964,60 +1948,27 @@ public: } }; -static void mark_from_roots_work(ParallelRootType::Value root_type, uint worker_id) { - assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); - - ParCompactionManager* cm = - ParCompactionManager::gc_thread_compaction_manager(worker_id); - PCMarkAndPushClosure mark_and_push_closure(cm); - - switch (root_type) { - case ParallelRootType::class_loader_data: - { - CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong); - ClassLoaderDataGraph::always_strong_cld_do(&cld_closure); - } - break; - - case ParallelRootType::code_cache: - // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. - //ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure)); - break; - - case ParallelRootType::sentinel: - DEBUG_ONLY(default:) // DEBUG_ONLY hack will create compile error on release builds (-Wswitch) and runtime check on debug builds - fatal("Bad enumeration value: %u", root_type); - break; - } - - // Do the real work - cm->follow_marking_stacks(); -} - void steal_marking_work(TaskTerminator& terminator, uint worker_id) { assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id); - oop obj = NULL; - ObjArrayTask task; do { - while (ParCompactionManager::steal_objarray(worker_id, task)) { + oop obj = NULL; + ObjArrayTask task; + if (ParCompactionManager::steal_objarray(worker_id, task)) { cm->follow_array((objArrayOop)task.obj(), task.index()); - cm->follow_marking_stacks(); - } - while (ParCompactionManager::steal(worker_id, obj)) { + } else if (ParCompactionManager::steal(worker_id, obj)) { cm->follow_contents(obj); - cm->follow_marking_stacks(); } + cm->follow_marking_stacks(); } while (!terminator.offer_termination()); } class MarkFromRootsTask : public WorkerTask { StrongRootsScope _strong_roots_scope; // needed for Threads::possibly_parallel_threads_do OopStorageSetStrongParState _oop_storage_set_par_state; - SequentialSubTasksDone _subtasks; TaskTerminator _terminator; uint _active_workers; @@ -2025,14 +1976,19 @@ public: MarkFromRootsTask(uint active_workers) : WorkerTask("MarkFromRootsTask"), _strong_roots_scope(active_workers), - _subtasks(ParallelRootType::sentinel), _terminator(active_workers, ParCompactionManager::oop_task_queues()), - _active_workers(active_workers) { - } + _active_workers(active_workers) {} virtual void work(uint worker_id) { - for (uint task = 0; _subtasks.try_claim_task(task); /*empty*/ ) { - mark_from_roots_work(static_cast(task), worker_id); + ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id); + PCMarkAndPushClosure mark_and_push_closure(cm); + + { + CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong); + ClassLoaderDataGraph::always_strong_cld_do(&cld_closure); + + // Do the real work + cm->follow_marking_stacks(); } PCAddThreadRootsMarkingTaskClosure closure(worker_id); @@ -2040,9 +1996,7 @@ public: // Mark from OopStorages { - ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id); - PCMarkAndPushClosure closure(cm); - _oop_storage_set_par_state.oops_do(&closure); + _oop_storage_set_par_state.oops_do(&mark_and_push_closure); // Do the real work cm->follow_marking_stacks(); } @@ -2075,8 +2029,7 @@ public: } }; -void PSParallelCompact::marking_phase(ParCompactionManager* cm, - ParallelOldTracer *gc_tracer) { +void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { // Recursively traverse all live objects and mark them GCTraceTime(Info, gc, phases) tm("Marking Phase", &_gc_timer); @@ -2135,20 +2088,11 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm, } _gc_tracer.report_object_count_after_gc(is_alive_closure()); -} - -#ifdef ASSERT -void PCAdjustPointerClosure::verify_cm(ParCompactionManager* cm) { - assert(cm != NULL, "associate ParCompactionManage should not be NULL"); - auto vmthread_cm = ParCompactionManager::get_vmthread_cm(); - if (Thread::current()->is_VM_thread()) { - assert(cm == vmthread_cm, "VM threads should use ParCompactionManager from get_vmthread_cm()"); - } else { - assert(Thread::current()->is_Worker_thread(), "Must be a GC thread"); - assert(cm != vmthread_cm, "GC threads should use ParCompactionManager from gc_thread_compaction_manager()"); - } -} +#if TASKQUEUE_STATS + ParCompactionManager::oop_task_queues()->print_and_reset_taskqueue_stats("Oop Queue"); + ParCompactionManager::_objarray_task_queues->print_and_reset_taskqueue_stats("ObjArrayOop Queue"); #endif +} class PSAdjustTask final : public WorkerTask { SubTasksDone _sub_tasks; @@ -2540,9 +2484,7 @@ void PSParallelCompact::compact() { { GCTraceTime(Trace, gc, phases) tm("Deferred Updates", &_gc_timer); - // Update the deferred objects, if any. In principle, any compaction - // manager can be used. However, since the current thread is VM thread, we - // use the rightful one to keep the verification logic happy. + // Update the deferred objects, if any. ParCompactionManager* cm = ParCompactionManager::get_vmthread_cm(); for (unsigned int id = old_space_id; id < last_space_id; ++id) { update_deferred_objects(cm, SpaceId(id)); diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.hpp index 0b8eb6b01167513baf942aabe5e58a13b3915df8..77a9d44f9b6b44045c3cf41814c4a55369d03a5c 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp @@ -1062,8 +1062,7 @@ class PSParallelCompact : AllStatic { static void post_compact(); // Mark live objects - static void marking_phase(ParCompactionManager* cm, - ParallelOldTracer *gc_tracer); + static void marking_phase(ParallelOldTracer *gc_tracer); // Compute the dense prefix for the designated space. This is an experimental // implementation currently not used in production. @@ -1123,7 +1122,7 @@ class PSParallelCompact : AllStatic { static void summarize_spaces_quick(); static void summarize_space(SpaceId id, bool maximum_compaction); - static void summary_phase(ParCompactionManager* cm, bool maximum_compaction); + static void summary_phase(bool maximum_compaction); // Adjust addresses in roots. Does not adjust addresses in heap. static void adjust_roots(); diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp index 001f55c076a9f72ee5fc0109f5c4ed9f2a176600..48c5a98fd1a6447e0a8196876a3231f6872f248b 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp @@ -126,9 +126,7 @@ inline void PSParallelCompact::adjust_pointer(T* p, ParCompactionManager* cm) { class PCAdjustPointerClosure: public BasicOopIterateClosure { public: - PCAdjustPointerClosure(ParCompactionManager* cm) { - verify_cm(cm); - _cm = cm; + PCAdjustPointerClosure(ParCompactionManager* cm) : _cm(cm) { } template void do_oop_nv(T* p) { PSParallelCompact::adjust_pointer(p, _cm); } virtual void do_oop(oop* p) { do_oop_nv(p); } @@ -137,8 +135,6 @@ public: virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; } private: ParCompactionManager* _cm; - - static void verify_cm(ParCompactionManager* cm) NOT_DEBUG_RETURN; }; #endif // SHARE_GC_PARALLEL_PSPARALLELCOMPACT_INLINE_HPP diff --git a/src/hotspot/share/gc/parallel/psPromotionLAB.cpp b/src/hotspot/share/gc/parallel/psPromotionLAB.cpp index 53fac0e98a58f9d70b249ca464224ff5460d602d..312db67606a5e096d57692d252d49888a8245aa6 100644 --- a/src/hotspot/share/gc/parallel/psPromotionLAB.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionLAB.cpp @@ -29,8 +29,6 @@ #include "memory/universe.hpp" #include "oops/oop.inline.hpp" -size_t PSPromotionLAB::filler_header_size; - // This is the shared initialization code. It sets up the basic pointers, // and allows enough extra space for a filler object. We call a virtual // method, "lab_is_valid()" to handle the different asserts the old/young @@ -45,10 +43,6 @@ void PSPromotionLAB::initialize(MemRegion lab) { set_end(end); set_top(bottom); - // Initialize after VM starts up because header_size depends on compressed - // oops. - filler_header_size = align_object_size(typeArrayOopDesc::header_size(T_INT)); - // We can be initialized to a zero size! if (free() > 0) { if (ZapUnusedHeapArea) { @@ -56,8 +50,8 @@ void PSPromotionLAB::initialize(MemRegion lab) { } // NOTE! We need to allow space for a filler object. - assert(lab.word_size() >= filler_header_size, "lab is too small"); - end = end - filler_header_size; + assert(lab.word_size() >= CollectedHeap::min_dummy_object_size(), "lab is too small"); + end = end - CollectedHeap::min_dummy_object_size(); set_end(end); _state = needs_flush; @@ -81,20 +75,8 @@ void PSPromotionLAB::flush() { // PLAB's never allocate the last aligned_header_size // so they can always fill with an array. - HeapWord* tlab_end = end() + filler_header_size; - typeArrayOop filler_oop = (typeArrayOop) cast_to_oop(top()); - filler_oop->set_mark(markWord::prototype()); - filler_oop->set_klass(Universe::intArrayKlassObj()); - const size_t array_length = - pointer_delta(tlab_end, top()) - typeArrayOopDesc::header_size(T_INT); - assert( (array_length * (HeapWordSize/sizeof(jint))) < (size_t)max_jint, "array too big in PSPromotionLAB"); - filler_oop->set_length((int)(array_length * (HeapWordSize/sizeof(jint)))); - -#ifdef ASSERT - // Note that we actually DO NOT want to use the aligned header size! - HeapWord* elt_words = cast_from_oop(filler_oop) + typeArrayOopDesc::header_size(T_INT); - Copy::fill_to_words(elt_words, array_length, 0xDEAABABE); -#endif + HeapWord* tlab_end = end() + CollectedHeap::min_dummy_object_size(); + CollectedHeap::fill_with_object(top(), tlab_end, trueInDebug); set_bottom(NULL); set_end(NULL); diff --git a/src/hotspot/share/gc/parallel/psPromotionLAB.hpp b/src/hotspot/share/gc/parallel/psPromotionLAB.hpp index e51852f8a6e962f10d7fc659625e4ea1300aba9e..239a1140a8a844937df33f1876bf469db8f44860 100644 --- a/src/hotspot/share/gc/parallel/psPromotionLAB.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionLAB.hpp @@ -39,8 +39,6 @@ class ObjectStartArray; class PSPromotionLAB : public CHeapObj { protected: - static size_t filler_header_size; - enum LabState { needs_flush, flushed, @@ -106,7 +104,6 @@ class PSOldPromotionLAB : public PSPromotionLAB { public: PSOldPromotionLAB() : _start_array(NULL) { } - PSOldPromotionLAB(ObjectStartArray* start_array) : _start_array(start_array) { } void set_start_array(ObjectStartArray* start_array) { _start_array = start_array; } diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp index 7ef706aba936b3fc251dc97b4e653fdb5b0640ec..9c6b8acf62426bc27416252f2518bdbdd6fce9a4 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ void PSPromotionManager::initialize() { _old_gen = heap->old_gen(); _young_space = heap->young_gen()->to_space(); - const uint promotion_manager_num = ParallelGCThreads + 1; + const uint promotion_manager_num = ParallelGCThreads; // To prevent false sharing, we pad the PSPromotionManagers // and make sure that the first instance starts at a cache line. @@ -95,7 +95,7 @@ PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(uint index) PSPromotionManager* PSPromotionManager::vm_thread_promotion_manager() { assert(_manager_array != NULL, "Sanity"); - return &_manager_array[ParallelGCThreads]; + return &_manager_array[0]; } void PSPromotionManager::pre_scavenge() { @@ -104,7 +104,7 @@ void PSPromotionManager::pre_scavenge() { _preserved_marks_set->assert_empty(); _young_space = heap->young_gen()->to_space(); - for(uint i=0; ireset(); } } @@ -113,7 +113,7 @@ bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) { bool promotion_failure_occurred = false; TASKQUEUE_STATS_ONLY(print_taskqueue_stats()); - for (uint i = 0; i < ParallelGCThreads + 1; i++) { + for (uint i = 0; i < ParallelGCThreads; i++) { PSPromotionManager* manager = manager_array(i); assert(manager->claimed_stack_depth()->is_empty(), "should be empty"); if (manager->_promotion_failed_info.has_failed()) { @@ -147,37 +147,24 @@ static const char* const pm_stats_hdr[] = { "--- ---------- ---------- ---------- ----------" }; -void -PSPromotionManager::print_taskqueue_stats() { +void PSPromotionManager::print_taskqueue_stats() { if (!log_is_enabled(Trace, gc, task, stats)) { return; } Log(gc, task, stats) log; ResourceMark rm; LogStream ls(log.trace()); - outputStream* out = &ls; - out->print_cr("== GC Tasks Stats, GC %3d", - ParallelScavengeHeap::heap()->total_collections()); - - TaskQueueStats totals; - out->print("thr "); TaskQueueStats::print_header(1, out); out->cr(); - out->print("--- "); TaskQueueStats::print_header(2, out); out->cr(); - for (uint i = 0; i < ParallelGCThreads + 1; ++i) { - TaskQueueStats& next = manager_array(i)->_claimed_stack_depth.stats; - out->print("%3d ", i); next.print(out); out->cr(); - totals += next; - } - out->print("tot "); totals.print(out); out->cr(); + + stack_array_depth()->print_taskqueue_stats(&ls, "Oop Queue"); const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]); - for (uint i = 0; i < hlines; ++i) out->print_cr("%s", pm_stats_hdr[i]); - for (uint i = 0; i < ParallelGCThreads + 1; ++i) { - manager_array(i)->print_local_stats(out, i); + for (uint i = 0; i < hlines; ++i) ls.print_cr("%s", pm_stats_hdr[i]); + for (uint i = 0; i < ParallelGCThreads; ++i) { + manager_array(i)->print_local_stats(&ls, i); } } -void -PSPromotionManager::reset_stats() { +void PSPromotionManager::reset_stats() { claimed_stack_depth()->stats.reset(); _array_chunk_pushes = _array_chunk_steals = 0; _arrays_chunked = _array_chunks_processed = 0; @@ -216,8 +203,6 @@ void PSPromotionManager::reset() { // We need to get an assert in here to make sure the labs are always flushed. - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - // Do not prefill the LAB's, save heap wastage! HeapWord* lab_base = young_space()->top(); _young_lab.initialize(MemRegion(lab_base, (size_t)0)); @@ -244,12 +229,6 @@ void PSPromotionManager::restore_preserved_marks() { void PSPromotionManager::drain_stacks_depth(bool totally_drain) { totally_drain = totally_drain || _totally_drain; -#ifdef ASSERT - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - MutableSpace* to_space = heap->young_gen()->to_space(); - MutableSpace* old_space = heap->old_gen()->object_space(); -#endif /* ASSERT */ - PSScannerTasksQueue* const tq = claimed_stack_depth(); do { ScannerTask task; @@ -360,7 +339,10 @@ oop PSPromotionManager::oop_promotion_failed(oop obj, markWord obj_mark) { push_contents(obj); - _preserved_marks->push_if_necessary(obj, obj_mark); + // Save the markWord of promotion-failed objs in _preserved_marks for later + // restoration. This way we don't have to walk the young-gen to locate + // these promotion-failed objs. + _preserved_marks->push_always(obj, obj_mark); } else { // We lost, someone else "owns" this object guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed."); diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp index f752901594908bdd2a74136902b76c0eb384ea02..b3f1c7297f40a2261ab9cba8ad8a27fcb00337e1 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp @@ -44,7 +44,7 @@ inline PSPromotionManager* PSPromotionManager::manager_array(uint index) { assert(_manager_array != NULL, "access of NULL manager_array"); - assert(index <= ParallelGCThreads, "out of range manager_array access"); + assert(index < ParallelGCThreads, "out of range manager_array access"); return &_manager_array[index]; } @@ -219,13 +219,6 @@ inline oop PSPromotionManager::copy_unmarked_to_survivor_space(oop o, HeapWord* lab_base = old_gen()->allocate(OldPLABSize); if(lab_base != NULL) { -#ifdef ASSERT - // Delay the initialization of the promotion lab (plab). - // This exposes uninitialized plabs to card table processing. - if (GCWorkerDelayMillis > 0) { - os::naked_sleep(GCWorkerDelayMillis); - } -#endif _old_lab.initialize(MemRegion(lab_base, OldPLABSize)); // Try the old lab allocation again. new_obj = cast_to_oop(_old_lab.allocate(new_obj_size)); diff --git a/src/hotspot/share/gc/parallel/psRootType.hpp b/src/hotspot/share/gc/parallel/psRootType.hpp index 921bbfdd2b0f12b174da13ae090bd0e2023870a9..cbdc94dc9abe6fcc0b7c727497988545734d3861 100644 --- a/src/hotspot/share/gc/parallel/psRootType.hpp +++ b/src/hotspot/share/gc/parallel/psRootType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_PARALLEL_PSROOTTYPE_HPP #define SHARE_GC_PARALLEL_PSROOTTYPE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" class ParallelRootType : public AllStatic { diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index e3b3e76ca470569f7815ba58da4d365627e37d3d..b6ca29adefcae194895d2b08217fb7f4a4056ac8 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -70,8 +70,6 @@ #include "services/memoryService.hpp" #include "utilities/stack.inline.hpp" -HeapWord* PSScavenge::_to_space_top_before_gc = NULL; -int PSScavenge::_consecutive_skipped_scavenges = 0; SpanSubjectToDiscoveryClosure PSScavenge::_span_based_discoverer; ReferenceProcessor* PSScavenge::_ref_processor = NULL; PSCardTable* PSScavenge::_card_table = NULL; @@ -285,37 +283,30 @@ class ScavengeRootsTask : public WorkerTask { PSOldGen* _old_gen; HeapWord* _gen_top; uint _active_workers; - bool _is_empty; + bool _is_old_gen_empty; TaskTerminator _terminator; public: ScavengeRootsTask(PSOldGen* old_gen, - HeapWord* gen_top, - uint active_workers, - bool is_empty) : + uint active_workers) : WorkerTask("ScavengeRootsTask"), _strong_roots_scope(active_workers), _subtasks(ParallelRootType::sentinel), _old_gen(old_gen), - _gen_top(gen_top), + _gen_top(old_gen->object_space()->top()), _active_workers(active_workers), - _is_empty(is_empty), + _is_old_gen_empty(old_gen->object_space()->is_empty()), _terminator(active_workers, PSPromotionManager::vm_thread_promotion_manager()->stack_array_depth()) { + assert(_old_gen != NULL, "Sanity"); } virtual void work(uint worker_id) { + assert(worker_id < _active_workers, "Sanity"); ResourceMark rm; - if (!_is_empty) { + if (!_is_old_gen_empty) { // There are only old-to-young pointers if there are objects // in the old gen. - - assert(_old_gen != NULL, "Sanity"); - // There are no old-to-young pointers if the old gen is empty. - assert(!_old_gen->object_space()->is_empty(), "Should not be called is there is no work"); - assert(_old_gen->object_space()->contains(_gen_top) || _gen_top == _old_gen->object_space()->top(), "Sanity"); - assert(worker_id < ParallelGCThreads, "Sanity"); - { PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(worker_id); PSCardTable* card_table = ParallelScavengeHeap::heap()->card_table(); @@ -367,12 +358,6 @@ bool PSScavenge::invoke_no_policy() { _gc_timer.register_gc_start(); - TimeStamp scavenge_entry; - TimeStamp scavenge_midpoint; - TimeStamp scavenge_exit; - - scavenge_entry.update(); - if (GCLocker::check_active_before_gc()) { return false; } @@ -444,8 +429,6 @@ bool PSScavenge::invoke_no_policy() { "Attempt to scavenge with live objects in to_space"); young_gen->to_space()->clear(SpaceDecorator::Mangle); - save_to_space_top_before_gc(); - #if COMPILER2_OR_JVMCI DerivedPointerTable::clear(); #endif @@ -457,12 +440,6 @@ bool PSScavenge::invoke_no_policy() { // Reset our survivor overflow. set_survivor_overflow(false); - // We need to save the old top values before - // creating the promotion_manager. We pass the top - // values to the card_table, to prevent it from - // straying into the promotion labs. - HeapWord* old_top = old_gen->object_space()->top(); - const uint active_workers = WorkerPolicy::calc_active_workers(ParallelScavengeHeap::heap()->workers().max_workers(), ParallelScavengeHeap::heap()->workers().active_workers(), @@ -476,12 +453,10 @@ bool PSScavenge::invoke_no_policy() { { GCTraceTime(Debug, gc, phases) tm("Scavenge", &_gc_timer); - ScavengeRootsTask task(old_gen, old_top, active_workers, old_gen->object_space()->is_empty()); + ScavengeRootsTask task(old_gen, active_workers); ParallelScavengeHeap::heap()->workers().run_task(&task); } - scavenge_midpoint.update(); - // Process reference objects discovered during scavenge { GCTraceTime(Debug, gc, phases) tm("Reference Processing", &_gc_timer); @@ -686,12 +661,6 @@ bool PSScavenge::invoke_no_policy() { heap->print_heap_after_gc(); heap->trace_heap_after_gc(&_gc_tracer); - scavenge_exit.update(); - - log_debug(gc, task, time)("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT, - scavenge_entry.ticks(), scavenge_midpoint.ticks(), - scavenge_exit.ticks()); - AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections()); _gc_timer.register_gc_end(); @@ -701,19 +670,11 @@ bool PSScavenge::invoke_no_policy() { return !promotion_failure_occurred; } -// This method iterates over all objects in the young generation, -// removing all forwarding references. It then restores any preserved marks. void PSScavenge::clean_up_failed_promotion() { - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - PSYoungGen* young_gen = heap->young_gen(); - - RemoveForwardedPointerClosure remove_fwd_ptr_closure; - young_gen->object_iterate(&remove_fwd_ptr_closure); - PSPromotionManager::restore_preserved_marks(); // Reset the PromotionFailureALot counters. - NOT_PRODUCT(heap->reset_promotion_should_fail();) + NOT_PRODUCT(ParallelScavengeHeap::heap()->reset_promotion_should_fail();) } bool PSScavenge::should_attempt_scavenge() { @@ -729,7 +690,6 @@ bool PSScavenge::should_attempt_scavenge() { // Do not attempt to promote unless to_space is empty if (!young_gen->to_space()->is_empty()) { - _consecutive_skipped_scavenges++; if (UsePerfData) { counters->update_scavenge_skipped(to_space_not_empty); } @@ -753,10 +713,7 @@ bool PSScavenge::should_attempt_scavenge() { log_trace(ergo)(" padded_promoted_average is greater than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes()); } - if (result) { - _consecutive_skipped_scavenges = 0; - } else { - _consecutive_skipped_scavenges++; + if (!result) { if (UsePerfData) { counters->update_scavenge_skipped(promoted_too_large); } diff --git a/src/hotspot/share/gc/parallel/psScavenge.hpp b/src/hotspot/share/gc/parallel/psScavenge.hpp index 440519ff7076df79e823661980538135b6584195..c575e8a3f2ca4d8ad6250bbaa4539dacc27751d3 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.hpp +++ b/src/hotspot/share/gc/parallel/psScavenge.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #include "gc/parallel/psVirtualspace.hpp" #include "gc/shared/collectorCounters.hpp" #include "gc/shared/gcTrace.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" #include "utilities/stack.hpp" @@ -53,14 +53,6 @@ class PSScavenge: AllStatic { full_follows_scavenge }; - // Saved value of to_space->top(), used to prevent objects in to_space from - // being rescanned. - static HeapWord* _to_space_top_before_gc; - - // Number of consecutive attempts to scavenge that were skipped - static int _consecutive_skipped_scavenges; - - protected: // Flags/counters static SpanSubjectToDiscoveryClosure _span_based_discoverer; @@ -84,9 +76,6 @@ class PSScavenge: AllStatic { static bool should_attempt_scavenge(); - static HeapWord* to_space_top_before_gc() { return _to_space_top_before_gc; } - static inline void save_to_space_top_before_gc(); - // Private accessors static PSCardTable* const card_table() { assert(_card_table != NULL, "Sanity"); return _card_table; } static const ParallelScavengeTracer* gc_tracer() { return &_gc_tracer; } @@ -95,8 +84,6 @@ class PSScavenge: AllStatic { // Accessors static uint tenuring_threshold() { return _tenuring_threshold; } static elapsedTimer* accumulated_time() { return &_accumulated_time; } - static int consecutive_skipped_scavenges() - { return _consecutive_skipped_scavenges; } // Performance Counters static CollectorCounters* counters() { return _counters; } diff --git a/src/hotspot/share/gc/parallel/psScavenge.inline.hpp b/src/hotspot/share/gc/parallel/psScavenge.inline.hpp index 1fee9f08339ed8c5bf947e6c69b9be323f6ed310..af3ff4c616513e18bcfdedb2a28b5c58b8abb5f2 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.inline.hpp +++ b/src/hotspot/share/gc/parallel/psScavenge.inline.hpp @@ -35,11 +35,6 @@ #include "oops/oop.inline.hpp" #include "utilities/globalDefinitions.hpp" -inline void PSScavenge::save_to_space_top_before_gc() { - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - _to_space_top_before_gc = heap->young_gen()->to_space()->top(); -} - template inline bool PSScavenge::should_scavenge(T* p) { T heap_oop = RawAccess<>::oop_load(p); return PSScavenge::is_obj_in_young(heap_oop); @@ -51,7 +46,7 @@ inline bool PSScavenge::should_scavenge(T* p, MutableSpace* to_space) { oop obj = RawAccess::oop_load(p); // Skip objects copied to to_space since the scavenge started. HeapWord* const addr = cast_from_oop(obj); - return addr < to_space_top_before_gc() || addr >= to_space->end(); + return addr < to_space->bottom() || addr >= to_space->end(); } return false; } diff --git a/src/hotspot/share/gc/parallel/psVirtualspace.cpp b/src/hotspot/share/gc/parallel/psVirtualspace.cpp index 830aa54d2b1d8d8890d322584c47cce96a51bd2a..4c5733f24d940b6bce0f38c20883b3aa7fcacc92 100644 --- a/src/hotspot/share/gc/parallel/psVirtualspace.cpp +++ b/src/hotspot/share/gc/parallel/psVirtualspace.cpp @@ -37,14 +37,6 @@ PSVirtualSpace::PSVirtualSpace(ReservedSpace rs, size_t alignment) : DEBUG_ONLY(verify()); } -PSVirtualSpace::PSVirtualSpace(ReservedSpace rs) : - _alignment(os::vm_page_size()) -{ - set_reserved(rs); - set_committed(reserved_low_addr(), reserved_low_addr()); - DEBUG_ONLY(verify()); -} - // Deprecated. PSVirtualSpace::PSVirtualSpace(): _alignment(os::vm_page_size()), @@ -66,11 +58,6 @@ PSVirtualSpace::~PSVirtualSpace() { release(); } -bool PSVirtualSpace::contains(void* p) const { - char* const cp = (char*)p; - return cp >= committed_low_addr() && cp < committed_high_addr(); -} - void PSVirtualSpace::release() { DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); // This may not release memory it didn't reserve. @@ -143,13 +130,9 @@ void PSVirtualSpace::verify() const { "bad reserved addrs"); assert(committed_low_addr() <= committed_high_addr(), "bad committed addrs"); - if (grows_up()) { - assert(reserved_low_addr() == committed_low_addr(), "bad low addrs"); - assert(reserved_high_addr() >= committed_high_addr(), "bad high addrs"); - } else { - assert(reserved_high_addr() == committed_high_addr(), "bad high addrs"); - assert(reserved_low_addr() <= committed_low_addr(), "bad low addrs"); - } + // committed addr grows up + assert(reserved_low_addr() == committed_low_addr(), "bad low addrs"); + assert(reserved_high_addr() >= committed_high_addr(), "bad high addrs"); } #endif // #ifndef PRODUCT diff --git a/src/hotspot/share/gc/parallel/psVirtualspace.hpp b/src/hotspot/share/gc/parallel/psVirtualspace.hpp index 4bb0547e3f11ff29c41618ebd3c3446e791b50ff..48150293a9ee154ffee78e6c44de9e6b6d4ac7b5 100644 --- a/src/hotspot/share/gc/parallel/psVirtualspace.hpp +++ b/src/hotspot/share/gc/parallel/psVirtualspace.hpp @@ -57,25 +57,19 @@ class PSVirtualSpace : public CHeapObj { public: PSVirtualSpace(ReservedSpace rs, size_t alignment); - PSVirtualSpace(ReservedSpace rs); ~PSVirtualSpace(); - // Eventually all instances should be created with the above 1- or 2-arg - // constructors. Then the 1st constructor below should become protected and - // the 2nd ctor and initialize() removed. - PSVirtualSpace(size_t alignment): - _alignment(alignment), - _reserved_low_addr(NULL), - _reserved_high_addr(NULL), - _committed_low_addr(NULL), - _committed_high_addr(NULL), - _special(false) { - } PSVirtualSpace(); void initialize(ReservedSpace rs); - bool contains(void* p) const; + bool is_in_committed(const void* p) const { + return (p >= committed_low_addr()) && (p < committed_high_addr()); + } + + bool is_in_reserved(const void* p) const { + return (p >= reserved_low_addr()) && (p < reserved_high_addr()); + } // Accessors (all sizes are bytes). size_t alignment() const { return _alignment; } @@ -85,6 +79,7 @@ class PSVirtualSpace : public CHeapObj { char* committed_high_addr() const { return _committed_high_addr; } bool special() const { return _special; } + // Return size in bytes inline size_t committed_size() const; inline size_t reserved_size() const; inline size_t uncommitted_size() const; @@ -103,8 +98,6 @@ class PSVirtualSpace : public CHeapObj { bool is_aligned(size_t val) const; bool is_aligned(char* val) const; void verify() const; - virtual bool grows_up() const { return true; } - bool grows_down() const { return !grows_up(); } // Helper class to verify a space when entering/leaving a block. class PSVirtualSpaceVerifier: public StackObj { diff --git a/src/hotspot/share/gc/parallel/psYoungGen.hpp b/src/hotspot/share/gc/parallel/psYoungGen.hpp index 0da0592a98616c252cc09ee83cadfd59e45bbc8e..3babc311e95500622f95b74259e7e5ab6c7df7aa 100644 --- a/src/hotspot/share/gc/parallel/psYoungGen.hpp +++ b/src/hotspot/share/gc/parallel/psYoungGen.hpp @@ -90,7 +90,7 @@ class PSYoungGen : public CHeapObj { MemRegion reserved() const { return _reserved; } bool is_in(const void* p) const { - return _virtual_space->contains((void *)p); + return _virtual_space->is_in_committed(p); } bool is_in_reserved(const void* p) const { diff --git a/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp b/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp index 0f131687f5b18b92b14f74c88f78ffbcaef8c537..fa019aa5b429517615a58bb85385d157b826f0ef 100644 --- a/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp +++ b/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp @@ -57,7 +57,6 @@ nonstatic_field(PSYoungGen, _min_gen_size, const size_t) \ nonstatic_field(PSYoungGen, _max_gen_size, const size_t) \ \ - nonstatic_field(PSOldGen, _reserved, MemRegion) \ nonstatic_field(PSOldGen, _virtual_space, PSVirtualSpace*) \ nonstatic_field(PSOldGen, _object_space, MutableSpace*) \ nonstatic_field(PSOldGen, _min_gen_size, const size_t) \ diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index 4b64494d2420285c683d6506b4fcdeb823172382..dac84ffb78ad77e613242fcf7700fd1c5b6ccd5f 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -669,9 +669,21 @@ void DefNewGeneration::init_assuming_no_promotion_failure() { } void DefNewGeneration::remove_forwarding_pointers() { - RemoveForwardedPointerClosure rspc; - eden()->object_iterate(&rspc); - from()->object_iterate(&rspc); + assert(_promotion_failed, "precondition"); + + // Will enter Full GC soon due to failed promotion. Must reset the mark word + // of objs in young-gen so that no objs are marked (forwarded) when Full GC + // starts. (The mark word is overloaded: `is_marked()` == `is_forwarded()`.) + struct ResetForwardedMarkWord : ObjectClosure { + void do_object(oop obj) override { + if (obj->is_forwarded()) { + obj->init_mark(); + } + } + } cl; + eden()->object_iterate(&cl); + from()->object_iterate(&cl); + restore_preserved_marks(); } diff --git a/src/hotspot/share/gc/serial/serialHeap.hpp b/src/hotspot/share/gc/serial/serialHeap.hpp index 208a997ad5fc85ce91cfc695892754a4b11dd721..f71b4a6740cffeb4cf478e08c5340fc92c4f9794 100644 --- a/src/hotspot/share/gc/serial/serialHeap.hpp +++ b/src/hotspot/share/gc/serial/serialHeap.hpp @@ -35,6 +35,26 @@ class MemoryPool; class OopIterateClosure; class TenuredGeneration; +// SerialHeap is the implementation of CollectedHeap for Serial GC. +// +// The heap is reserved up-front in a single contiguous block, split into two +// parts, the young and old generation. The young generation resides at lower +// addresses, the old generation at higher addresses. The boundary address +// between the generations is fixed. Within a generation, committed memory +// grows towards higher addresses. +// +// +// low high +// +// +-- generation boundary (fixed after startup) +// | +// |<- young gen (reserved MaxNewSize) ->|<- old gen (reserved MaxOldSize) ->| +// +-----------------+--------+--------+--------+---------------+-------------------+ +// | eden | from | to | | old | | +// | | (to) | (from) | | | | +// +-----------------+--------+--------+--------+---------------+-------------------+ +// |<- committed ->| |<- committed ->| +// class SerialHeap : public GenCollectedHeap { private: MemoryPool* _eden_pool; @@ -85,7 +105,7 @@ public: virtual void safepoint_synchronize_end(); // Support for loading objects from CDS archive into the heap - bool can_load_archived_objects() const { return true; } + bool can_load_archived_objects() const { return UseCompressedOops; } HeapWord* allocate_loaded_archive_space(size_t size); void complete_loaded_archive_space(MemRegion archive_space); }; diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.cpp b/src/hotspot/share/gc/serial/tenuredGeneration.cpp index 1aec978b3820724b488cb725932773a618c3cbb6..fd135529157d1b4b1738d7b40578f43148df50d2 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.cpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.cpp @@ -212,9 +212,6 @@ void TenuredGeneration::assert_correct_size_change_locking() { assert_locked_or_safepoint(ExpandHeap_lock); } -// Currently nothing to do. -void TenuredGeneration::prepare_for_verify() {} - void TenuredGeneration::object_iterate(ObjectClosure* blk) { _the_space->object_iterate(blk); } diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.hpp b/src/hotspot/share/gc/serial/tenuredGeneration.hpp index 44153320f6c1fbd66251a0a6976e5a0ded107a6a..410981de7582192c85e7b07724a12e171494d2ad 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.hpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.hpp @@ -97,8 +97,6 @@ class TenuredGeneration: public CardGeneration { HeapWord* expand_and_allocate(size_t size, bool is_tlab); - virtual void prepare_for_verify(); - virtual void gc_prologue(bool full); virtual void gc_epilogue(bool full); diff --git a/src/hotspot/share/gc/shared/accessBarrierSupport.hpp b/src/hotspot/share/gc/shared/accessBarrierSupport.hpp index 58bc562d988a8551efd3e127da497033f2c4ef04..ca3b4589224bf2233335d96fcebcf08311da183a 100644 --- a/src/hotspot/share/gc/shared/accessBarrierSupport.hpp +++ b/src/hotspot/share/gc/shared/accessBarrierSupport.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_ACCESSBARRIERSUPPORT_HPP #define SHARE_GC_SHARED_ACCESSBARRIERSUPPORT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/access.hpp" class AccessBarrierSupport: AllStatic { diff --git a/src/hotspot/share/gc/shared/ageTableTracer.hpp b/src/hotspot/share/gc/shared/ageTableTracer.hpp index cca3f125bfd730f0ec0a74ca0b8ccad7d88a4e0c..02e1fe3338db210b82ed283646e3e3173da022d2 100644 --- a/src/hotspot/share/gc/shared/ageTableTracer.hpp +++ b/src/hotspot/share/gc/shared/ageTableTracer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ #ifndef SHARE_GC_SHARED_AGETABLETRACER_HPP #define SHARE_GC_SHARED_AGETABLETRACER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class AgeTableTracer : AllStatic { public: diff --git a/src/hotspot/share/gc/shared/allocTracer.hpp b/src/hotspot/share/gc/shared/allocTracer.hpp index c30628b2889705f37795fb0b7443891807c8fd68..273f20d70ea44d5e1161ff6ec1877c97d9d0f99b 100644 --- a/src/hotspot/share/gc/shared/allocTracer.hpp +++ b/src/hotspot/share/gc/shared/allocTracer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_ALLOCTRACER_HPP #define SHARE_GC_SHARED_ALLOCTRACER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" class AllocTracer : AllStatic { diff --git a/src/hotspot/share/gc/shared/blockOffsetTable.cpp b/src/hotspot/share/gc/shared/blockOffsetTable.cpp index b7d5864920810b7498f34bd1d129c13933ec9057..e350e70ad5fd5867a0b736f74f11842f44aaf222 100644 --- a/src/hotspot/share/gc/shared/blockOffsetTable.cpp +++ b/src/hotspot/share/gc/shared/blockOffsetTable.cpp @@ -33,16 +33,16 @@ #include "runtime/java.hpp" #include "services/memTracker.hpp" -uint BOTConstants::LogN = 0; -uint BOTConstants::LogN_words = 0; -uint BOTConstants::N_bytes = 0; -uint BOTConstants::N_words = 0; +uint BOTConstants::_log_card_size = 0; +uint BOTConstants::_log_card_size_in_words = 0; +uint BOTConstants::_card_size = 0; +uint BOTConstants::_card_size_in_words = 0; void BOTConstants::initialize_bot_size(uint card_shift) { - LogN = card_shift; - LogN_words = LogN - LogHeapWordSize; - N_bytes = 1 << LogN; - N_words = 1 << LogN_words; + _log_card_size = card_shift; + _log_card_size_in_words = _log_card_size - LogHeapWordSize; + _card_size = 1 << _log_card_size; + _card_size_in_words = 1 << _log_card_size_in_words; } ////////////////////////////////////////////////////////////////////// @@ -99,7 +99,7 @@ void BlockOffsetSharedArray::resize(size_t new_word_size) { bool BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const { assert(p >= _reserved.start(), "just checking"); size_t delta = pointer_delta(p, _reserved.start()); - return (delta & right_n_bits((int)BOTConstants::LogN_words)) == (size_t)NoBits; + return (delta & right_n_bits((int)BOTConstants::log_card_size_in_words())) == (size_t)NoBits; } @@ -116,7 +116,7 @@ BlockOffsetArray::BlockOffsetArray(BlockOffsetSharedArray* array, set_init_to_zero(init_to_zero_); if (!init_to_zero_) { // initialize cards to point back to mr.start() - set_remainder_to_point_to_start(mr.start() + BOTConstants::N_words, mr.end()); + set_remainder_to_point_to_start(mr.start() + BOTConstants::card_size_in_words(), mr.end()); _array->set_offset_array(0, 0); // set first card to 0 } } @@ -172,7 +172,7 @@ set_remainder_to_point_to_start(HeapWord* start, HeapWord* end, bool reducing) { size_t start_card = _array->index_for(start); size_t end_card = _array->index_for(end-1); assert(start ==_array->address_for_index(start_card), "Precondition"); - assert(end ==_array->address_for_index(end_card)+BOTConstants::N_words, "Precondition"); + assert(end ==_array->address_for_index(end_card)+BOTConstants::card_size_in_words(), "Precondition"); set_remainder_to_point_to_start_incl(start_card, end_card, reducing); // closed interval } @@ -188,7 +188,7 @@ BlockOffsetArray::set_remainder_to_point_to_start_incl(size_t start_card, size_t return; } assert(start_card > _array->index_for(_bottom), "Cannot be first card"); - assert(_array->offset_array(start_card-1) <= BOTConstants::N_words, + assert(_array->offset_array(start_card-1) <= BOTConstants::card_size_in_words(), "Offset card has an unexpected value"); size_t start_card_for_region = start_card; u_char offset = max_jubyte; @@ -197,7 +197,7 @@ BlockOffsetArray::set_remainder_to_point_to_start_incl(size_t start_card, size_t // so that the reach ends in this region and not at the start // of the next. size_t reach = start_card - 1 + (BOTConstants::power_to_cards_back(i+1) - 1); - offset = BOTConstants::N_words + i; + offset = BOTConstants::card_size_in_words() + i; if (reach >= end_card) { _array->set_offset_array(start_card_for_region, end_card, offset, reducing); start_card_for_region = reach + 1; @@ -218,13 +218,13 @@ void BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const if (end_card < start_card) { return; } - guarantee(_array->offset_array(start_card) == BOTConstants::N_words, "Wrong value in second card"); - u_char last_entry = BOTConstants::N_words; + guarantee(_array->offset_array(start_card) == BOTConstants::card_size_in_words(), "Wrong value in second card"); + u_char last_entry = BOTConstants::card_size_in_words(); for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) { u_char entry = _array->offset_array(c); guarantee(entry >= last_entry, "Monotonicity"); if (c - start_card > BOTConstants::power_to_cards_back(1)) { - guarantee(entry > BOTConstants::N_words, "Should be in logarithmic region"); + guarantee(entry > BOTConstants::card_size_in_words(), "Should be in logarithmic region"); } size_t backskip = BOTConstants::entry_to_cards_back(entry); size_t landing_card = c - backskip; @@ -234,7 +234,7 @@ void BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const } else { guarantee(landing_card == (start_card - 1), "Tautology"); // Note that N_words is the maximum offset value - guarantee(_array->offset_array(landing_card) <= BOTConstants::N_words, "Offset value"); + guarantee(_array->offset_array(landing_card) <= BOTConstants::card_size_in_words(), "Offset value"); } last_entry = entry; // remember for monotonicity test } @@ -266,7 +266,7 @@ BlockOffsetArray::do_block_internal(HeapWord* blk_start, uintptr_t start_ui = (uintptr_t)blk_start; // Calculate the last card boundary preceding end of blk intptr_t boundary_before_end = (intptr_t)end_ui; - clear_bits(boundary_before_end, right_n_bits((int)BOTConstants::LogN)); + clear_bits(boundary_before_end, right_n_bits((int)BOTConstants::log_card_size())); if (start_ui <= (uintptr_t)boundary_before_end) { // blk starts at or crosses a boundary // Calculate index of card on which blk begins @@ -279,7 +279,7 @@ BlockOffsetArray::do_block_internal(HeapWord* blk_start, if (blk_start != boundary) { // blk starts strictly after boundary // adjust card boundary and start_index forward to next card - boundary += BOTConstants::N_words; + boundary += BOTConstants::card_size_in_words(); start_index++; } assert(start_index <= end_index, "monotonicity of index_for()"); @@ -296,8 +296,8 @@ BlockOffsetArray::do_block_internal(HeapWord* blk_start, // We have finished marking the "offset card". We need to now // mark the subsequent cards that this blk spans. if (start_index < end_index) { - HeapWord* rem_st = _array->address_for_index(start_index) + BOTConstants::N_words; - HeapWord* rem_end = _array->address_for_index(end_index) + BOTConstants::N_words; + HeapWord* rem_st = _array->address_for_index(start_index) + BOTConstants::card_size_in_words(); + HeapWord* rem_end = _array->address_for_index(end_index) + BOTConstants::card_size_in_words(); set_remainder_to_point_to_start(rem_st, rem_end, reducing); } break; @@ -380,22 +380,22 @@ HeapWord* BlockOffsetArrayContigSpace::block_start_unsafe(const void* addr) cons HeapWord* q = _array->address_for_index(index); uint offset = _array->offset_array(index); // Extend u_char to uint. - while (offset > BOTConstants::N_words) { + while (offset > BOTConstants::card_size_in_words()) { // The excess of the offset from N_words indicates a power of Base // to go back by. size_t n_cards_back = BOTConstants::entry_to_cards_back(offset); - q -= (BOTConstants::N_words * n_cards_back); + q -= (BOTConstants::card_size_in_words() * n_cards_back); assert(q >= _sp->bottom(), "Went below bottom!"); index -= n_cards_back; offset = _array->offset_array(index); } - while (offset == BOTConstants::N_words) { + while (offset == BOTConstants::card_size_in_words()) { assert(q >= _sp->bottom(), "Went below bottom!"); - q -= BOTConstants::N_words; + q -= BOTConstants::card_size_in_words(); index--; offset = _array->offset_array(index); } - assert(offset < BOTConstants::N_words, "offset too large"); + assert(offset < BOTConstants::card_size_in_words(), "offset too large"); q -= offset; HeapWord* n = q; @@ -428,14 +428,14 @@ void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start, "should be past threshold"); assert(blk_start <= _next_offset_threshold, "blk_start should be at or before threshold"); - assert(pointer_delta(_next_offset_threshold, blk_start) <= BOTConstants::N_words, + assert(pointer_delta(_next_offset_threshold, blk_start) <= BOTConstants::card_size_in_words(), "offset should be <= BlockOffsetSharedArray::N"); assert(_sp->is_in_reserved(blk_start), "reference must be into the space"); assert(_sp->is_in_reserved(blk_end-1), "limit must be within the space"); assert(_next_offset_threshold == - _array->_reserved.start() + _next_offset_index*BOTConstants::N_words, + _array->_reserved.start() + _next_offset_index*BOTConstants::card_size_in_words(), "index must agree with threshold"); debug_only(size_t orig_next_offset_index = _next_offset_index;) @@ -457,7 +457,7 @@ void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start, HeapWord* rem_st = _array->address_for_index(_next_offset_index + 1); // Calculate rem_end this way because end_index // may be the last valid index in the covered region. - HeapWord* rem_end = _array->address_for_index(end_index) + BOTConstants::N_words; + HeapWord* rem_end = _array->address_for_index(end_index) + BOTConstants::card_size_in_words(); set_remainder_to_point_to_start(rem_st, rem_end); } @@ -465,7 +465,7 @@ void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start, _next_offset_index = end_index + 1; // Calculate _next_offset_threshold this way because end_index // may be the last valid index in the covered region. - _next_offset_threshold = _array->address_for_index(end_index) + BOTConstants::N_words; + _next_offset_threshold = _array->address_for_index(end_index) + BOTConstants::card_size_in_words(); assert(_next_offset_threshold >= blk_end, "Incorrect offset threshold"); #ifdef ASSERT @@ -476,11 +476,11 @@ void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start, assert((_array->offset_array(orig_next_offset_index) == 0 && blk_start == boundary) || (_array->offset_array(orig_next_offset_index) > 0 && - _array->offset_array(orig_next_offset_index) <= BOTConstants::N_words), + _array->offset_array(orig_next_offset_index) <= BOTConstants::card_size_in_words()), "offset array should have been set"); for (size_t j = orig_next_offset_index + 1; j <= end_index; j++) { assert(_array->offset_array(j) > 0 && - _array->offset_array(j) <= (u_char) (BOTConstants::N_words+BOTConstants::N_powers-1), + _array->offset_array(j) <= (u_char) (BOTConstants::card_size_in_words()+BOTConstants::N_powers-1), "offset array should have been set"); } #endif diff --git a/src/hotspot/share/gc/shared/blockOffsetTable.hpp b/src/hotspot/share/gc/shared/blockOffsetTable.hpp index fef56d3120553e3079ddf92fda35357299d01080..9a32594c123f666d233bf3033377faeaaab99054 100644 --- a/src/hotspot/share/gc/shared/blockOffsetTable.hpp +++ b/src/hotspot/share/gc/shared/blockOffsetTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ #include "gc/shared/gc_globals.hpp" #include "gc/shared/memset_with_concurrent_readers.hpp" #include "gc/shared/cardTable.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/memRegion.hpp" #include "memory/virtualspace.hpp" #include "runtime/globals.hpp" @@ -49,12 +49,12 @@ class ContiguousSpace; class BOTConstants : public AllStatic { -public: - static uint LogN; - static uint LogN_words; - static uint N_bytes; - static uint N_words; + static uint _log_card_size; + static uint _log_card_size_in_words; + static uint _card_size; + static uint _card_size_in_words; +public: // entries "e" of at least N_words mean "go back by Base^(e-N_words)." // All entries are less than "N_words + N_powers". static const uint LogBase = 4; @@ -67,9 +67,22 @@ public: static size_t power_to_cards_back(uint i) { return (size_t)1 << (LogBase * i); } + static size_t entry_to_cards_back(u_char entry) { - assert(entry >= N_words, "Precondition"); - return power_to_cards_back(entry - N_words); + assert(entry >= _card_size_in_words, "Precondition"); + return power_to_cards_back(entry - _card_size_in_words); + } + static uint log_card_size() { + return _log_card_size; + } + static uint log_card_size_in_words() { + return _log_card_size_in_words; + } + static uint card_size() { + return _card_size; + } + static uint card_size_in_words() { + return _card_size_in_words; } }; @@ -91,7 +104,7 @@ public: BlockOffsetTable(HeapWord* bottom, HeapWord* end): _bottom(bottom), _end(end) { assert(_bottom <= _end, "arguments out of order"); - assert(BOTConstants::N_bytes == CardTable::card_size, "sanity"); + assert(BOTConstants::card_size() == CardTable::card_size(), "sanity"); } // Note that the committed size of the covered space may have changed, @@ -178,7 +191,7 @@ class BlockOffsetSharedArray: public CHeapObj { check_reducing_assertion(reducing); assert(index < _vs.committed_size(), "index out of range"); assert(high >= low, "addresses out of order"); - assert(pointer_delta(high, low) <= BOTConstants::N_words, "offset too large"); + assert(pointer_delta(high, low) <= BOTConstants::card_size_in_words(), "offset too large"); assert(!reducing || _offset_array[index] >= (u_char)pointer_delta(high, low), "Not reducing"); _offset_array[index] = (u_char)pointer_delta(high, low); @@ -189,7 +202,7 @@ class BlockOffsetSharedArray: public CHeapObj { assert(index_for(right - 1) < _vs.committed_size(), "right address out of range"); assert(left < right, "Heap addresses out of order"); - size_t num_cards = pointer_delta(right, left) >> BOTConstants::LogN_words; + size_t num_cards = pointer_delta(right, left) >> BOTConstants::log_card_size_in_words(); fill_range(index_for(left), num_cards, offset); } @@ -206,7 +219,7 @@ class BlockOffsetSharedArray: public CHeapObj { void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { assert(index < _vs.committed_size(), "index out of range"); assert(high >= low, "addresses out of order"); - assert(pointer_delta(high, low) <= BOTConstants::N_words, "offset too large"); + assert(pointer_delta(high, low) <= BOTConstants::card_size_in_words(), "offset too large"); assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset"); } @@ -221,7 +234,7 @@ class BlockOffsetSharedArray: public CHeapObj { // to be reserved. size_t compute_size(size_t mem_region_words) { - size_t number_of_slots = (mem_region_words / BOTConstants::N_words) + 1; + size_t number_of_slots = (mem_region_words / BOTConstants::card_size_in_words()) + 1; return ReservedSpace::allocation_align_size_up(number_of_slots); } @@ -335,7 +348,7 @@ class BlockOffsetArray: public BlockOffsetTable { assert(_array->is_card_boundary(new_end), "new _end would not be a card boundary"); // set all the newly added cards - _array->set_offset_array(_end, new_end, BOTConstants::N_words); + _array->set_offset_array(_end, new_end, BOTConstants::card_size_in_words()); } _end = new_end; // update _end } diff --git a/src/hotspot/share/gc/shared/blockOffsetTable.inline.hpp b/src/hotspot/share/gc/shared/blockOffsetTable.inline.hpp index ceb852b4ffc4a5b21eb9e07e8a90dc450d908475..abaa0dade46e127723d4e3b2a916a7ab0c1ce0ef 100644 --- a/src/hotspot/share/gc/shared/blockOffsetTable.inline.hpp +++ b/src/hotspot/share/gc/shared/blockOffsetTable.inline.hpp @@ -50,14 +50,14 @@ inline size_t BlockOffsetSharedArray::index_for(const void* p) const { pc < (char*)_reserved.end(), "p not in range."); size_t delta = pointer_delta(pc, _reserved.start(), sizeof(char)); - size_t result = delta >> BOTConstants::LogN; + size_t result = delta >> BOTConstants::log_card_size(); assert(result < _vs.committed_size(), "bad index from address"); return result; } inline HeapWord* BlockOffsetSharedArray::address_for_index(size_t index) const { assert(index < _vs.committed_size(), "bad index"); - HeapWord* result = _reserved.start() + (index << BOTConstants::LogN_words); + HeapWord* result = _reserved.start() + (index << BOTConstants::log_card_size_in_words()); assert(result >= _reserved.start() && result < _reserved.end(), "bad address from index"); return result; diff --git a/src/hotspot/share/gc/g1/g1BufferNodeList.cpp b/src/hotspot/share/gc/shared/bufferNodeList.cpp similarity index 80% rename from src/hotspot/share/gc/g1/g1BufferNodeList.cpp rename to src/hotspot/share/gc/shared/bufferNodeList.cpp index 3b89b0c7cd7a72c7ecd5a4c6688b476706fb62a2..bcf4b42ec967bdb3cdc334dd8cebc69ff608d854 100644 --- a/src/hotspot/share/gc/g1/g1BufferNodeList.cpp +++ b/src/hotspot/share/gc/shared/bufferNodeList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * 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,15 +23,15 @@ */ #include "precompiled.hpp" -#include "gc/g1/g1BufferNodeList.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "utilities/debug.hpp" -G1BufferNodeList::G1BufferNodeList() : +BufferNodeList::BufferNodeList() : _head(NULL), _tail(NULL), _entry_count(0) {} -G1BufferNodeList::G1BufferNodeList(BufferNode* head, - BufferNode* tail, - size_t entry_count) : +BufferNodeList::BufferNodeList(BufferNode* head, + BufferNode* tail, + size_t entry_count) : _head(head), _tail(tail), _entry_count(entry_count) { assert((_head == NULL) == (_tail == NULL), "invariant"); diff --git a/src/hotspot/share/gc/g1/g1BufferNodeList.hpp b/src/hotspot/share/gc/shared/bufferNodeList.hpp similarity index 79% rename from src/hotspot/share/gc/g1/g1BufferNodeList.hpp rename to src/hotspot/share/gc/shared/bufferNodeList.hpp index 785c3118f9b8897420401d90fb2e79486c066d3b..ae66a1fcc7142f45e0f14f4452fb4f5131b467cf 100644 --- a/src/hotspot/share/gc/g1/g1BufferNodeList.hpp +++ b/src/hotspot/share/gc/shared/bufferNodeList.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * 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,21 +22,20 @@ * */ -#ifndef SHARE_GC_G1_G1BUFFERNODELIST_HPP -#define SHARE_GC_G1_G1BUFFERNODELIST_HPP +#ifndef SHARE_GC_SHARED_BUFFERNODELIST_HPP +#define SHARE_GC_SHARED_BUFFERNODELIST_HPP #include "utilities/globalDefinitions.hpp" class BufferNode; -struct G1BufferNodeList { +struct BufferNodeList { BufferNode* _head; // First node in list or NULL if empty. BufferNode* _tail; // Last node in list or NULL if empty. size_t _entry_count; // Sum of entries in nodes in list. - G1BufferNodeList(); - G1BufferNodeList(BufferNode* head, BufferNode* tail, size_t entry_count); + BufferNodeList(); + BufferNodeList(BufferNode* head, BufferNode* tail, size_t entry_count); }; -#endif // SHARE_GC_G1_G1BUFFERNODELIST_HPP - +#endif // SHARE_GC_SHARED_BUFFERNODELIST_HPP diff --git a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp index b66e94836ed43bf661ccd6ff87425f5c2692d7a5..660c324aa99b3dcf70620387ec1c7693bed98b70 100644 --- a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp +++ b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp @@ -69,9 +69,9 @@ void CardTableBarrierSetC1::post_barrier(LIRAccess& access, LIR_Opr addr, LIR_Op if (TwoOperandLIRForm) { LIR_Opr addr_opr = LIR_OprFact::address(new LIR_Address(addr, addr->type())); __ leal(addr_opr, tmp); - __ unsigned_shift_right(tmp, CardTable::card_shift, tmp); + __ unsigned_shift_right(tmp, CardTable::card_shift(), tmp); } else { - __ unsigned_shift_right(addr, CardTable::card_shift, tmp); + __ unsigned_shift_right(addr, CardTable::card_shift(), tmp); } LIR_Address* card_addr; diff --git a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp index ea5af234ed32391e10215a37bd7c27e848314b0d..3e7b43bf90334b6c3102f9b7da856b3294901676 100644 --- a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,7 +96,7 @@ Node* BarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) cons GraphKit* kit = parse_access.kit(); if (access.type() == T_DOUBLE) { - Node* new_val = kit->dstore_rounding(val.node()); + Node* new_val = kit->dprecision_rounding(val.node()); val.set_node(new_val); } diff --git a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp index 73ea620041b8672930cc13e98f555b8e36c971ea..0a7a032c117edb81203c33e777ce7f3690fe68b0 100644 --- a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp @@ -91,7 +91,7 @@ void CardTableBarrierSetC2::post_barrier(GraphKit* kit, Node* cast = __ CastPX(__ ctrl(), adr); // Divide by card size - Node* card_offset = __ URShiftX(cast, __ ConI(CardTable::card_shift)); + Node* card_offset = __ URShiftX(cast, __ ConI(CardTable::card_shift())); // Combine card table base and card offset Node* card_adr = __ AddP(__ top(), byte_map_base_node(kit), card_offset); diff --git a/src/hotspot/share/gc/shared/cardGeneration.cpp b/src/hotspot/share/gc/shared/cardGeneration.cpp index 8f691c3c46cec80a7188b4fb6886f553b90fe8db..523f65c8cc3a5475b79d32b95f38da47017c1edf 100644 --- a/src/hotspot/share/gc/shared/cardGeneration.cpp +++ b/src/hotspot/share/gc/shared/cardGeneration.cpp @@ -174,11 +174,6 @@ void CardGeneration::shrink(size_t bytes) { name(), old_mem_size/K, new_mem_size/K); } -// No young generation references, clear this generation's cards. -void CardGeneration::clear_remembered_set() { - _rs->clear(reserved()); -} - // Objects in this generation may have moved, invalidate this // generation's cards. void CardGeneration::invalidate_remembered_set() { @@ -306,9 +301,6 @@ void CardGeneration::compute_new_size() { } } -// Currently nothing to do. -void CardGeneration::prepare_for_verify() {} - void CardGeneration::space_iterate(SpaceClosure* blk, bool usedOnly) { blk->do_space(space()); diff --git a/src/hotspot/share/gc/shared/cardGeneration.hpp b/src/hotspot/share/gc/shared/cardGeneration.hpp index 7ad58cf2b699c120ce4bb6832e453e06a29c3165..084737a61466d7adc3748dbc577a3dca1ad825a1 100644 --- a/src/hotspot/share/gc/shared/cardGeneration.hpp +++ b/src/hotspot/share/gc/shared/cardGeneration.hpp @@ -71,12 +71,8 @@ class CardGeneration: public Generation { virtual void compute_new_size(); - virtual void clear_remembered_set(); - virtual void invalidate_remembered_set(); - virtual void prepare_for_verify(); - // Grow generation with specified size (returns false if unable to grow) bool grow_by(size_t bytes); // Grow generation to reserved size. diff --git a/src/hotspot/share/gc/shared/cardTable.cpp b/src/hotspot/share/gc/shared/cardTable.cpp index 10e4723934d0188110a05298190430ba7f06e7ce..b7f7ab81c36d208308826806cd06e328f560cba5 100644 --- a/src/hotspot/share/gc/shared/cardTable.cpp +++ b/src/hotspot/share/gc/shared/cardTable.cpp @@ -38,27 +38,27 @@ #include "gc/parallel/objectStartArray.hpp" #endif -uint CardTable::card_shift = 0; -uint CardTable::card_size = 0; -uint CardTable::card_size_in_words = 0; +uint CardTable::_card_shift = 0; +uint CardTable::_card_size = 0; +uint CardTable::_card_size_in_words = 0; void CardTable::initialize_card_size() { assert(UseG1GC || UseParallelGC || UseSerialGC, "Initialize card size should only be called by card based collectors."); - card_size = GCCardSizeInBytes; - card_shift = log2i_exact(card_size); - card_size_in_words = card_size / sizeof(HeapWord); + _card_size = GCCardSizeInBytes; + _card_shift = log2i_exact(_card_size); + _card_size_in_words = _card_size / sizeof(HeapWord); // Set blockOffsetTable size based on card table entry size - BOTConstants::initialize_bot_size(card_shift); + BOTConstants::initialize_bot_size(_card_shift); #if INCLUDE_PARALLELGC // Set ObjectStartArray block size based on card table entry size - ObjectStartArray::initialize_block_size(card_shift); + ObjectStartArray::initialize_block_size(_card_shift); #endif - log_info_p(gc, init)("CardTable entry size: " UINT32_FORMAT, card_size); + log_info_p(gc, init)("CardTable entry size: " UINT32_FORMAT, _card_size); } size_t CardTable::compute_byte_map_size() { @@ -82,8 +82,8 @@ CardTable::CardTable(MemRegion whole_heap) : _committed(MemRegion::create_array(_max_covered_regions, mtGC)), _guard_region() { - assert((uintptr_t(_whole_heap.start()) & (card_size - 1)) == 0, "heap must start at card boundary"); - assert((uintptr_t(_whole_heap.end()) & (card_size - 1)) == 0, "heap must end at card boundary"); + assert((uintptr_t(_whole_heap.start()) & (_card_size - 1)) == 0, "heap must start at card boundary"); + assert((uintptr_t(_whole_heap.end()) & (_card_size - 1)) == 0, "heap must end at card boundary"); } CardTable::~CardTable() { @@ -120,7 +120,7 @@ void CardTable::initialize() { // // _byte_map = _byte_map_base + (uintptr_t(low_bound) >> card_shift) _byte_map = (CardValue*) heap_rs.base(); - _byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); + _byte_map_base = _byte_map - (uintptr_t(low_bound) >> _card_shift); assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map"); assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map"); @@ -162,16 +162,6 @@ int CardTable::find_covering_region_by_base(HeapWord* base) { return res; } -int CardTable::find_covering_region_containing(HeapWord* addr) { - for (int i = 0; i < _cur_covered_regions; i++) { - if (_covered[i].contains(addr)) { - return i; - } - } - assert(0, "address outside of heap?"); - return -1; -} - HeapWord* CardTable::largest_prev_committed_end(int ind) const { HeapWord* max_end = NULL; for (int j = 0; j < ind; j++) { @@ -413,7 +403,7 @@ void CardTable::dirty_card_iterate(MemRegion mr, MemRegionClosure* cl) { next_entry <= limit && *next_entry == dirty_card; dirty_cards++, next_entry++); MemRegion cur_cards(addr_for(cur_entry), - dirty_cards*card_size_in_words); + dirty_cards*_card_size_in_words); cl->do_MemRegion(cur_cards); } } @@ -439,7 +429,7 @@ MemRegion CardTable::dirty_card_range_after_reset(MemRegion mr, next_entry <= limit && *next_entry == dirty_card; dirty_cards++, next_entry++); MemRegion cur_cards(addr_for(cur_entry), - dirty_cards*card_size_in_words); + dirty_cards * _card_size_in_words); if (reset) { for (size_t i = 0; i < dirty_cards; i++) { cur_entry[i] = reset_val; @@ -493,7 +483,7 @@ void CardTable::verify_region(MemRegion mr, CardValue val, bool val_equals) { } log_error(gc, verify)("== card " PTR_FORMAT " [" PTR_FORMAT "," PTR_FORMAT "], val: %d", p2i(curr), p2i(addr_for(curr)), - p2i((HeapWord*) (((size_t) addr_for(curr)) + card_size)), + p2i((HeapWord*) (((size_t) addr_for(curr)) + _card_size)), (int) curr_val); } } diff --git a/src/hotspot/share/gc/shared/cardTable.hpp b/src/hotspot/share/gc/shared/cardTable.hpp index bf116a1f1e73c7fc58c7fab7d2d3aab5a0c4c4fe..ca6d1ef51dda49a08b03e01e2ce838b1009385d7 100644 --- a/src/hotspot/share/gc/shared/cardTable.hpp +++ b/src/hotspot/share/gc/shared/cardTable.hpp @@ -78,10 +78,6 @@ protected: // covered regions defined in the constructor are ever in use. int find_covering_region_by_base(HeapWord* base); - // Same as above, but finds the region containing the given address - // instead of starting at a given base address. - int find_covering_region_containing(HeapWord* addr); - // Returns the leftmost end of a committed region corresponding to a // covered region before covered region "ind", or else "NULL" if "ind" is // the first covered region. @@ -111,6 +107,11 @@ protected: // a word's worth (row) of clean card values static const intptr_t clean_card_row = (intptr_t)(-1); + // CardTable entry size + static uint _card_shift; + static uint _card_size; + static uint _card_size_in_words; + public: CardTable(MemRegion whole_heap); virtual ~CardTable(); @@ -133,8 +134,8 @@ public: // in, um, words. inline size_t cards_required(size_t covered_words) { // Add one for a guard card, used to detect errors. - const size_t words = align_up(covered_words, card_size_in_words); - return words / card_size_in_words + 1; + const size_t words = align_up(covered_words, _card_size_in_words); + return words / _card_size_in_words + 1; } // Dirty the bytes corresponding to "mr" (not all of which must be @@ -157,7 +158,7 @@ public: "Attempt to access p = " PTR_FORMAT " out of bounds of " " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")", p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())); - CardValue* result = &_byte_map_base[uintptr_t(p) >> card_shift]; + CardValue* result = &_byte_map_base[uintptr_t(p) >> _card_shift]; assert(result >= _byte_map && result < _byte_map + _byte_map_size, "out of bounds accessor for card marking array"); return result; @@ -189,7 +190,7 @@ public: " _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT, p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size)); size_t delta = pointer_delta(p, _byte_map_base, sizeof(CardValue)); - HeapWord* result = (HeapWord*) (delta << card_shift); + HeapWord* result = (HeapWord*) (delta << _card_shift); assert(_whole_heap.contains(result), "Returning result = " PTR_FORMAT " out of bounds of " " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")", @@ -228,10 +229,17 @@ public: MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset, int reset_val); - // CardTable entry size - static uint card_shift; - static uint card_size; - static uint card_size_in_words; + static uint card_shift() { + return _card_shift; + } + + static uint card_size() { + return _card_size; + } + + static uint card_size_in_words() { + return _card_size_in_words; + } static constexpr CardValue clean_card_val() { return clean_card; } static constexpr CardValue dirty_card_val() { return dirty_card; } diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp index e33d464764cc33a0e259a92366a47bf5174ef333..f9ad0759b428141c89fa8b7fa38198cba0a3347a 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.cpp +++ b/src/hotspot/share/gc/shared/collectedHeap.cpp @@ -493,10 +493,6 @@ void CollectedHeap::fill_with_dummy_object(HeapWord* start, HeapWord* end, bool CollectedHeap::fill_with_object(start, end, zap); } -size_t CollectedHeap::min_dummy_object_size() const { - return oopDesc::header_size(); -} - size_t CollectedHeap::tlab_alloc_reserve() const { size_t min_size = min_dummy_object_size(); return min_size > (size_t)MinObjAlignment ? align_object_size(min_size) : 0; diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index 681a832982b6fe83237c488b3fb8bdc9acfd42d4..89cca6777d64a8f3803b384f720942d877329f61 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,7 +90,7 @@ public: // ShenandoahHeap // ZCollectedHeap // -class CollectedHeap : public CHeapObj { +class CollectedHeap : public CHeapObj { friend class VMStructs; friend class JVMCIVMStructs; friend class IsGCActiveMark; // Block structured external access to _is_gc_active @@ -289,7 +289,10 @@ class CollectedHeap : public CHeapObj { } virtual void fill_with_dummy_object(HeapWord* start, HeapWord* end, bool zap); - virtual size_t min_dummy_object_size() const; + static constexpr size_t min_dummy_object_size() { + return oopDesc::header_size(); + } + size_t tlab_alloc_reserve() const; // Some heaps may offer a contiguous region for shared non-blocking diff --git a/src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp b/src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp index c11c0e116c5886d2befc97a18c7c1552094c45bc..7af1b5746c3444136317ce3b52c531089999a955 100644 --- a/src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp +++ b/src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_CONCURRENTGCBREAKPOINTS_HPP #include "gc/shared/gcCause.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class Monitor; diff --git a/src/hotspot/share/gc/shared/gcCause.hpp b/src/hotspot/share/gc/shared/gcCause.hpp index 75f7dc73a8cbcb3262060dfae1b0270cb46cde6e..a3746fa8745dad097d036a79ba6f20429d2bcb28 100644 --- a/src/hotspot/share/gc/shared/gcCause.hpp +++ b/src/hotspot/share/gc/shared/gcCause.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ #ifndef SHARE_GC_SHARED_GCCAUSE_HPP #define SHARE_GC_SHARED_GCCAUSE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/debug.hpp" // // This class exposes implementation details of the various diff --git a/src/hotspot/share/gc/shared/gcConfig.hpp b/src/hotspot/share/gc/shared/gcConfig.hpp index 2dfbf186b7fd0bebeb3581fc99217835caa2a1ab..9b0da3ad528a87e41fcfc4f9e5d12cb403b78c47 100644 --- a/src/hotspot/share/gc/shared/gcConfig.hpp +++ b/src/hotspot/share/gc/shared/gcConfig.hpp @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_GCCONFIG_HPP #include "gc/shared/collectedHeap.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class GCArguments; diff --git a/src/hotspot/share/gc/shared/gcLocker.hpp b/src/hotspot/share/gc/shared/gcLocker.hpp index 91ed84c41a99b6ba7d8cbd5278380461686ca5e8..e567d0c1f1689b61a1ccd44eece5485206141bed 100644 --- a/src/hotspot/share/gc/shared/gcLocker.hpp +++ b/src/hotspot/share/gc/shared/gcLocker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_GCLOCKER_HPP #include "gc/shared/gcCause.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/gc/shared/gcLogPrecious.hpp b/src/hotspot/share/gc/shared/gcLogPrecious.hpp index 5f1158caca75a5f0115102534eb5aa7afe42a333..ec8b1c670f3216c69bddef99e68f0280a3be4cc6 100644 --- a/src/hotspot/share/gc/shared/gcLogPrecious.hpp +++ b/src/hotspot/share/gc/shared/gcLogPrecious.hpp @@ -26,7 +26,7 @@ #include "utilities/globalDefinitions.hpp" #include "logging/logHandle.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" class Mutex; diff --git a/src/hotspot/share/gc/shared/gcVMOperations.hpp b/src/hotspot/share/gc/shared/gcVMOperations.hpp index ce071ee16a73e6c00987ee6341d724832b611209..9144300565873b8282b28dbaca959ca1a310c1f1 100644 --- a/src/hotspot/share/gc/shared/gcVMOperations.hpp +++ b/src/hotspot/share/gc/shared/gcVMOperations.hpp @@ -42,7 +42,6 @@ // VM_GC_HeapInspection // VM_PopulateDynamicDumpSharedSpace // VM_GenCollectFull -// VM_GenCollectFullConcurrent // VM_ParallelGCSystemGC // VM_CollectForAllocation // VM_GenCollectForAllocation @@ -71,7 +70,6 @@ // allocate afterwards; // // VM_GenCollectFull -// VM_GenCollectFullConcurrent // VM_ParallelGCSystemGC // - these operations preform full collection of heaps of // different kind diff --git a/src/hotspot/share/gc/shared/gcWhen.hpp b/src/hotspot/share/gc/shared/gcWhen.hpp index ff489226f65b36759f8db765c5ed53347390448f..23e2ef6b229d745e45a5464fc9c4a7b8e4844a91 100644 --- a/src/hotspot/share/gc/shared/gcWhen.hpp +++ b/src/hotspot/share/gc/shared/gcWhen.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_GCWHEN_HPP #define SHARE_GC_SHARED_GCWHEN_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" class GCWhen : AllStatic { diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 684357297d8c5fc852eceb1f23ceb420eee19e52..555170a091aac32f6d783a1ba73acf0a2eef8b8b 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -208,7 +208,7 @@ "Maximum size of marking stack") \ range(1, (max_jint - 1)) \ \ - product(size_t, MarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M), \ + product(size_t, MarkStackSize, NOT_LP64(64*K) LP64_ONLY(4*M), \ "Size of marking stack") \ constraint(MarkStackSizeConstraintFunc,AfterErgo) \ range(1, (max_jint - 1)) \ diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index 473e5abc1dff61bf87f1c837ad80e5b8a741da6d..c840e5a666790972d5b8c554b6c64e1b6c6e1fbf 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -1045,16 +1045,8 @@ void GenCollectedHeap::release_scratch() { _old_gen->reset_scratch(); } -class GenPrepareForVerifyClosure: public GenCollectedHeap::GenClosure { - void do_generation(Generation* gen) { - gen->prepare_for_verify(); - } -}; - void GenCollectedHeap::prepare_for_verify() { ensure_parsability(false); // no need to retire TLABs - GenPrepareForVerifyClosure blk; - generation_iterate(&blk, false); } void GenCollectedHeap::generation_iterate(GenClosure* cl, diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.hpp b/src/hotspot/share/gc/shared/genCollectedHeap.hpp index 28ed627b80f205349ccc9efe855bbd8ba27aa19d..1cce08f4b0c99cbf4a27beffbad102b55c649f4f 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp @@ -48,7 +48,6 @@ class GenCollectedHeap : public CollectedHeap { friend class GenMarkSweep; friend class VM_GenCollectForAllocation; friend class VM_GenCollectFull; - friend class VM_GenCollectFullConcurrent; friend class VM_GC_HeapInspection; friend class VM_HeapDumper; friend class HeapInspection; diff --git a/src/hotspot/share/gc/shared/generation.hpp b/src/hotspot/share/gc/shared/generation.hpp index 216b38d38b7e5e24f2721327e7124c8894df5f10..b9183ec28987b5b3c1c63945acdec9decb39c417 100644 --- a/src/hotspot/share/gc/shared/generation.hpp +++ b/src/hotspot/share/gc/shared/generation.hpp @@ -364,10 +364,6 @@ class Generation: public CHeapObj { virtual void post_compact() { ShouldNotReachHere(); } #endif - // Some generations may require some cleanup actions before allowing - // a verification. - virtual void prepare_for_verify() {} - // Accessing "marks". // This function gives a generation a chance to note a point between @@ -422,11 +418,6 @@ class Generation: public CHeapObj { // each. virtual void object_iterate(ObjectClosure* cl); - // Inform a generation that it longer contains references to objects - // in any younger generation. [e.g. Because younger gens are empty, - // clear the card table.] - virtual void clear_remembered_set() { } - // Inform a generation that some of its objects have moved. [e.g. The // generation's spaces were compacted, invalidating the card table.] virtual void invalidate_remembered_set() { } diff --git a/src/hotspot/share/gc/shared/locationPrinter.hpp b/src/hotspot/share/gc/shared/locationPrinter.hpp index 2c99e4528453d62a5a46ec7f97b7aecb6222fd8a..2d5d997376d13c4741a134df010bb4e0beceefaf 100644 --- a/src/hotspot/share/gc/shared/locationPrinter.hpp +++ b/src/hotspot/share/gc/shared/locationPrinter.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_LOCATIONPRINTER_HPP #define SHARE_GC_SHARED_LOCATIONPRINTER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/shared/objectCountEventSender.hpp b/src/hotspot/share/gc/shared/objectCountEventSender.hpp index 58e6da016daf8eb1f5e389aa8cd8c4f606761bbf..115fbfdaf7d3a01d40fbd408ead25482cbf863d1 100644 --- a/src/hotspot/share/gc/shared/objectCountEventSender.hpp +++ b/src/hotspot/share/gc/shared/objectCountEventSender.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_OBJECTCOUNTEVENTSENDER_HPP #include "gc/shared/gcTrace.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" #include "utilities/ticks.hpp" diff --git a/src/hotspot/share/gc/shared/plab.hpp b/src/hotspot/share/gc/shared/plab.hpp index b3700a3b9f67bdecbc4d60f1b47820ed72c69036..ebe788122ba4b2d5473044cc162e7832451f24f2 100644 --- a/src/hotspot/share/gc/shared/plab.hpp +++ b/src/hotspot/share/gc/shared/plab.hpp @@ -94,9 +94,6 @@ public: } } - // Allocate the object aligned to "alignment_in_bytes". - inline HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes); - // Undo any allocation in the buffer, which is required to be of the // "obj" of the given "word_sz". void undo_allocation(HeapWord* obj, size_t word_sz); @@ -119,7 +116,7 @@ public: } // Sets the space of the buffer to be [buf, space+word_sz()). - virtual void set_buf(HeapWord* buf, size_t new_word_sz) { + void set_buf(HeapWord* buf, size_t new_word_sz) { assert(new_word_sz > AlignmentReserve, "Too small"); _word_sz = new_word_sz; diff --git a/src/hotspot/share/gc/shared/preservedMarks.cpp b/src/hotspot/share/gc/shared/preservedMarks.cpp index 718f97085f6789748cc4bb11dc37325499d31b89..9003ccb1697375300537cb1816fac5324e8f1a8c 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.cpp +++ b/src/hotspot/share/gc/shared/preservedMarks.cpp @@ -71,12 +71,6 @@ void PreservedMarks::assert_empty() { } #endif // ndef PRODUCT -void RemoveForwardedPointerClosure::do_object(oop obj) { - if (obj->is_forwarded()) { - PreservedMarks::init_forwarded_mark(obj); - } -} - void PreservedMarksSet::init(uint num) { assert(_stacks == nullptr && _num == 0, "do not re-initialize"); assert(num > 0, "pre-condition"); @@ -125,8 +119,10 @@ public: ~RestorePreservedMarksTask() { assert(_total_size == _total_size_before, "total_size = %zu before = %zu", _total_size, _total_size_before); - - log_trace(gc)("Restored %zu marks", _total_size); + size_t mem_size = _total_size * (sizeof(oop) + sizeof(markWord)); + log_trace(gc)("Restored %zu marks, occupying %zu %s", _total_size, + byte_size_in_proper_unit(mem_size), + proper_unit_for_byte_size(mem_size)); } }; diff --git a/src/hotspot/share/gc/shared/preservedMarks.hpp b/src/hotspot/share/gc/shared/preservedMarks.hpp index 21b40903e7fb2bc747b2e34455c1294dbb31f42b..9a09e78bd46fcb123a0e47267c10ef76bb21b7d0 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.hpp +++ b/src/hotspot/share/gc/shared/preservedMarks.hpp @@ -56,8 +56,8 @@ private: public: size_t size() const { return _stack.size(); } - inline void push(oop obj, markWord m); inline void push_if_necessary(oop obj, markWord m); + inline void push_always(oop obj, markWord m); // Iterate over the stack, restore all preserved marks, and // reclaim the memory taken up by the stack segments. void restore(); @@ -75,11 +75,6 @@ public: ~PreservedMarks() { assert_empty(); } }; -class RemoveForwardedPointerClosure: public ObjectClosure { -public: - virtual void do_object(oop obj); -}; - class PreservedMarksSet : public CHeapObj { private: // true -> _stacks will be allocated in the C heap diff --git a/src/hotspot/share/gc/shared/preservedMarks.inline.hpp b/src/hotspot/share/gc/shared/preservedMarks.inline.hpp index e3f9f513573453a6dd0df2f638004bb2b0d026bb..e35ba38e4290ed43d55f0746b96800df38e3d258 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.inline.hpp +++ b/src/hotspot/share/gc/shared/preservedMarks.inline.hpp @@ -35,18 +35,19 @@ inline bool PreservedMarks::should_preserve_mark(oop obj, markWord m) const { return obj->mark_must_be_preserved(m); } -inline void PreservedMarks::push(oop obj, markWord m) { - assert(should_preserve_mark(obj, m), "pre-condition"); - OopAndMarkWord elem(obj, m); - _stack.push(elem); -} - inline void PreservedMarks::push_if_necessary(oop obj, markWord m) { if (should_preserve_mark(obj, m)) { - push(obj, m); + OopAndMarkWord elem(obj, m); + _stack.push(elem); } } +inline void PreservedMarks::push_always(oop obj, markWord m) { + assert(!m.is_marked(), "precondition"); + OopAndMarkWord elem(obj, m); + _stack.push(elem); +} + inline void PreservedMarks::init_forwarded_mark(oop obj) { obj->init_mark(); } diff --git a/src/hotspot/share/gc/shared/referenceProcessor.cpp b/src/hotspot/share/gc/shared/referenceProcessor.cpp index 5f46d8f9568ccba483a0795ada5e859337efddd1..21b57621706ceff97280d9278d6766b1fbe30e0f 100644 --- a/src/hotspot/share/gc/shared/referenceProcessor.cpp +++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp @@ -483,7 +483,7 @@ void RefProcTask::process_discovered_list(uint worker_id, keep_alive, enqueue, do_enqueue_and_clear); - _phase_times->add_ref_cleared(ref_type, removed); + _phase_times->add_ref_dropped(ref_type, removed); } } @@ -748,8 +748,6 @@ void ReferenceProcessor::process_soft_weak_final_refs(RefProcProxyTask& proxy_ta maybe_balance_queues(_discoveredFinalRefs); } - RefProcPhaseTimeTracker tt(SoftWeakFinalRefsPhase, &phase_times); - log_reflist("SoftWeakFinalRefsPhase Soft before", _discoveredSoftRefs, _max_num_queues); log_reflist("SoftWeakFinalRefsPhase Weak before", _discoveredWeakRefs, _max_num_queues); log_reflist("SoftWeakFinalRefsPhase Final before", _discoveredFinalRefs, _max_num_queues); @@ -780,7 +778,6 @@ void ReferenceProcessor::process_final_keep_alive(RefProcProxyTask& proxy_task, } // Traverse referents of final references and keep them and followers alive. - RefProcPhaseTimeTracker tt(KeepAliveFinalRefsPhase, &phase_times); RefProcKeepAliveFinalPhaseTask phase_task(*this, &phase_times); run_task(phase_task, proxy_task, true); @@ -804,9 +801,6 @@ void ReferenceProcessor::process_phantom_refs(RefProcProxyTask& proxy_task, maybe_balance_queues(_discoveredPhantomRefs); } - // Walk phantom references appropriately. - RefProcPhaseTimeTracker tt(PhantomRefsPhase, &phase_times); - log_reflist("PhantomRefsPhase Phantom before", _discoveredPhantomRefs, _max_num_queues); RefProcPhantomPhaseTask phase_task(*this, &phase_times); @@ -821,7 +815,7 @@ inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) if (_discovery_is_mt) { // During a multi-threaded discovery phase, // each thread saves to its "own" list. - id = WorkerThread::current()->id(); + id = WorkerThread::worker_id(); } else { // single-threaded discovery, we save in round-robin // fashion to each of the lists. diff --git a/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.cpp b/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.cpp index 2c9df9f29650e1aa90d1afdaaacae0a5c9699a13..f3bfcc2269289d10c6a2c7ffa181e2c0366d0b62 100644 --- a/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.cpp +++ b/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.cpp @@ -143,16 +143,6 @@ RefProcBalanceQueuesTimeTracker::~RefProcBalanceQueuesTimeTracker() { phase_times()->set_balance_queues_time_ms(_phase_number, elapsed); } -RefProcPhaseTimeTracker::RefProcPhaseTimeTracker(ReferenceProcessor::RefProcPhases phase_number, - ReferenceProcessorPhaseTimes* phase_times) : - RefProcPhaseTimeBaseTracker(phase_enum_2_phase_string(phase_number), phase_number, phase_times) { -} - -RefProcPhaseTimeTracker::~RefProcPhaseTimeTracker() { - double elapsed = elapsed_time(); - phase_times()->set_phase_time_ms(_phase_number, elapsed); -} - RefProcTotalPhaseTimesTracker::RefProcTotalPhaseTimesTracker(ReferenceProcessor::RefProcPhases phase_number, ReferenceProcessorPhaseTimes* phase_times) : RefProcPhaseTimeBaseTracker(phase_enum_2_phase_string(phase_number), phase_number, phase_times) { @@ -207,7 +197,7 @@ void ReferenceProcessorPhaseTimes::reset() { _soft_weak_final_refs_phase_worker_time_sec->reset(); for (int i = 0; i < number_of_subclasses_of_ref; i++) { - _ref_cleared[i] = 0; + _ref_dropped[i] = 0; _ref_discovered[i] = 0; } @@ -223,9 +213,9 @@ ReferenceProcessorPhaseTimes::~ReferenceProcessorPhaseTimes() { delete _soft_weak_final_refs_phase_worker_time_sec; } -void ReferenceProcessorPhaseTimes::add_ref_cleared(ReferenceType ref_type, size_t count) { +void ReferenceProcessorPhaseTimes::add_ref_dropped(ReferenceType ref_type, size_t count) { ASSERT_REF_TYPE(ref_type); - Atomic::add(&_ref_cleared[ref_type_2_index(ref_type)], count, memory_order_relaxed); + Atomic::add(&_ref_dropped[ref_type_2_index(ref_type)], count, memory_order_relaxed); } void ReferenceProcessorPhaseTimes::set_ref_discovered(ReferenceType ref_type, size_t count) { @@ -280,13 +270,16 @@ void ReferenceProcessorPhaseTimes::print_reference(ReferenceType ref_type, uint LogStream ls(lt); ResourceMark rm; - ls.print_cr("%s%s:", Indents[base_indent], ref_type_2_string(ref_type)); - - uint const next_indent = base_indent + 1; int const ref_type_index = ref_type_2_index(ref_type); - ls.print_cr("%sDiscovered: " SIZE_FORMAT, Indents[next_indent], _ref_discovered[ref_type_index]); - ls.print_cr("%sCleared: " SIZE_FORMAT, Indents[next_indent], _ref_cleared[ref_type_index]); + size_t discovered = _ref_discovered[ref_type_index]; + size_t dropped = _ref_dropped[ref_type_index]; + assert(discovered >= dropped, "invariant"); + size_t processed = discovered - dropped; + + ls.print_cr("%s%s Discovered: %zu, Dropped: %zu, Processed: %zu", + Indents[base_indent], ref_type_2_string(ref_type), + discovered, dropped, processed); } } diff --git a/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.hpp b/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.hpp index 5b2e9e7bc7b786fadab5588dfe596e492b3cfe73..26ee4e2a918141816166d749cdee98f3f8c22f00 100644 --- a/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.hpp +++ b/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.hpp @@ -52,7 +52,7 @@ class ReferenceProcessorPhaseTimes : public CHeapObj { // Total spent time for reference processing. double _total_time_ms; - size_t _ref_cleared[number_of_subclasses_of_ref]; + size_t _ref_dropped[number_of_subclasses_of_ref]; size_t _ref_discovered[number_of_subclasses_of_ref]; bool _processing_is_mt; @@ -83,7 +83,7 @@ public: void set_total_time_ms(double total_time_ms) { _total_time_ms = total_time_ms; } - void add_ref_cleared(ReferenceType ref_type, size_t count); + void add_ref_dropped(ReferenceType ref_type, size_t count); void set_ref_discovered(ReferenceType ref_type, size_t count); size_t ref_discovered(ReferenceType ref_type); @@ -146,14 +146,6 @@ public: ~RefProcBalanceQueuesTimeTracker(); }; -// Updates phase time at ReferenceProcessorPhaseTimes and save it into GCTimer. -class RefProcPhaseTimeTracker : public RefProcPhaseTimeBaseTracker { -public: - RefProcPhaseTimeTracker(ReferenceProcessor::RefProcPhases phase_number, - ReferenceProcessorPhaseTimes* phase_times); - ~RefProcPhaseTimeTracker(); -}; - // Highest level time tracker. class RefProcTotalPhaseTimesTracker : public RefProcPhaseTimeBaseTracker { public: diff --git a/src/hotspot/share/gc/shared/scavengableNMethods.hpp b/src/hotspot/share/gc/shared/scavengableNMethods.hpp index 276ea9843c0f0b7bd596cfba3511660011c46533..4852e6d32fbf92f81579fa17f20dba5a72056164 100644 --- a/src/hotspot/share/gc/shared/scavengableNMethods.hpp +++ b/src/hotspot/share/gc/shared/scavengableNMethods.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_SCAVENGABLENMETHODS_HPP #define SHARE_GC_SHARED_SCAVENGABLENMETHODS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" class BoolObjectClosure; diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp index 560225f88b933a82d784ff5489c7609c6827ff9e..67d76173614347d220263eb3e0a2253185fc60c8 100644 --- a/src/hotspot/share/gc/shared/space.cpp +++ b/src/hotspot/share/gc/shared/space.cpp @@ -730,38 +730,6 @@ HeapWord* ContiguousSpace::par_allocate(size_t size) { return par_allocate_impl(size); } -void ContiguousSpace::allocate_temporary_filler(int factor) { - // allocate temporary type array decreasing free size with factor 'factor' - assert(factor >= 0, "just checking"); - size_t size = pointer_delta(end(), top()); - - // if space is full, return - if (size == 0) return; - - if (factor > 0) { - size -= size/factor; - } - size = align_object_size(size); - - const size_t array_header_size = typeArrayOopDesc::header_size(T_INT); - if (size >= align_object_size(array_header_size)) { - size_t length = (size - array_header_size) * (HeapWordSize / sizeof(jint)); - // allocate uninitialized int array - typeArrayOop t = (typeArrayOop) cast_to_oop(allocate(size)); - assert(t != NULL, "allocation should succeed"); - t->set_mark(markWord::prototype()); - t->set_klass(Universe::intArrayKlassObj()); - t->set_length((int)length); - } else { - assert(size == CollectedHeap::min_fill_size(), - "size for smallest fake object doesn't match"); - instanceOop obj = (instanceOop) cast_to_oop(allocate(size)); - obj->set_mark(markWord::prototype()); - obj->set_klass_gap(0); - obj->set_klass(vmClasses::Object_klass()); - } -} - void OffsetTableContigSpace::initialize_threshold() { _offsets.initialize_threshold(); } diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp index f2a9c24904ed9b6c2897652e6910a1a115b0596f..9c94a24e4254dc8823e84cf417e22df3fe1e6790 100644 --- a/src/hotspot/share/gc/shared/space.hpp +++ b/src/hotspot/share/gc/shared/space.hpp @@ -532,10 +532,6 @@ class ContiguousSpace: public CompactibleSpace { // Debugging virtual void verify() const; - - // Used to increase collection frequency. "factor" of 0 means entire - // space. - void allocate_temporary_filler(int factor); }; diff --git a/src/hotspot/share/gc/shared/spaceDecorator.hpp b/src/hotspot/share/gc/shared/spaceDecorator.hpp index d421a2a40f5ca80e7c6f5292f6572480f4b53fd7..778881f75a1a2ea9bc56ea96e3b0ed37b1a3806c 100644 --- a/src/hotspot/share/gc/shared/spaceDecorator.hpp +++ b/src/hotspot/share/gc/shared/spaceDecorator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_SPACEDECORATOR_HPP #define SHARE_GC_SHARED_SPACEDECORATOR_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/memRegion.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/shared/suspendibleThreadSet.cpp b/src/hotspot/share/gc/shared/suspendibleThreadSet.cpp index e91b1b49802094e5a67b656edb6f2750d37a7bae..2636cc920618dc967ff8773c26c5c9cdb21d08ad 100644 --- a/src/hotspot/share/gc/shared/suspendibleThreadSet.cpp +++ b/src/hotspot/share/gc/shared/suspendibleThreadSet.cpp @@ -29,10 +29,10 @@ #include "runtime/semaphore.hpp" #include "runtime/thread.inline.hpp" -uint SuspendibleThreadSet::_nthreads = 0; -uint SuspendibleThreadSet::_nthreads_stopped = 0; -bool SuspendibleThreadSet::_suspend_all = false; -double SuspendibleThreadSet::_suspend_all_start = 0.0; +uint SuspendibleThreadSet::_nthreads = 0; +uint SuspendibleThreadSet::_nthreads_stopped = 0; +volatile bool SuspendibleThreadSet::_suspend_all = false; +double SuspendibleThreadSet::_suspend_all_start = 0.0; static Semaphore* _synchronize_wakeup = NULL; @@ -50,7 +50,7 @@ bool SuspendibleThreadSet::is_synchronized() { void SuspendibleThreadSet::join() { assert(!Thread::current()->is_suspendible_thread(), "Thread already joined"); MonitorLocker ml(STS_lock, Mutex::_no_safepoint_check_flag); - while (_suspend_all) { + while (suspend_all()) { ml.wait(); } _nthreads++; @@ -63,7 +63,7 @@ void SuspendibleThreadSet::leave() { assert(_nthreads > 0, "Invalid"); DEBUG_ONLY(Thread::current()->clear_suspendible_thread();) _nthreads--; - if (_suspend_all && is_synchronized()) { + if (suspend_all() && is_synchronized()) { // This leave completes a request, so inform the requestor. _synchronize_wakeup->signal(); } @@ -72,7 +72,7 @@ void SuspendibleThreadSet::leave() { void SuspendibleThreadSet::yield() { assert(Thread::current()->is_suspendible_thread(), "Must have joined"); MonitorLocker ml(STS_lock, Mutex::_no_safepoint_check_flag); - if (_suspend_all) { + if (suspend_all()) { _nthreads_stopped++; if (is_synchronized()) { if (ConcGCYieldTimeout > 0) { @@ -82,7 +82,7 @@ void SuspendibleThreadSet::yield() { // This yield completes the request, so inform the requestor. _synchronize_wakeup->signal(); } - while (_suspend_all) { + while (suspend_all()) { ml.wait(); } assert(_nthreads_stopped > 0, "Invalid"); @@ -97,8 +97,8 @@ void SuspendibleThreadSet::synchronize() { } { MonitorLocker ml(STS_lock, Mutex::_no_safepoint_check_flag); - assert(!_suspend_all, "Only one at a time"); - _suspend_all = true; + assert(!suspend_all(), "Only one at a time"); + Atomic::store(&_suspend_all, true); if (is_synchronized()) { return; } @@ -120,7 +120,7 @@ void SuspendibleThreadSet::synchronize() { #ifdef ASSERT MonitorLocker ml(STS_lock, Mutex::_no_safepoint_check_flag); - assert(_suspend_all, "STS not synchronizing"); + assert(suspend_all(), "STS not synchronizing"); assert(is_synchronized(), "STS not synchronized"); #endif } @@ -128,8 +128,8 @@ void SuspendibleThreadSet::synchronize() { void SuspendibleThreadSet::desynchronize() { assert(Thread::current()->is_VM_thread(), "Must be the VM thread"); MonitorLocker ml(STS_lock, Mutex::_no_safepoint_check_flag); - assert(_suspend_all, "STS not synchronizing"); + assert(suspend_all(), "STS not synchronizing"); assert(is_synchronized(), "STS not synchronized"); - _suspend_all = false; + Atomic::store(&_suspend_all, false); ml.notify_all(); } diff --git a/src/hotspot/share/gc/shared/suspendibleThreadSet.hpp b/src/hotspot/share/gc/shared/suspendibleThreadSet.hpp index 1e47c3b57a87c49cd18a7a00af75d47ff5e003b4..37d27f3e9ed94b93092a6426c03cc280b217bd1f 100644 --- a/src/hotspot/share/gc/shared/suspendibleThreadSet.hpp +++ b/src/hotspot/share/gc/shared/suspendibleThreadSet.hpp @@ -26,6 +26,7 @@ #define SHARE_GC_SHARED_SUSPENDIBLETHREADSET_HPP #include "memory/allocation.hpp" +#include "runtime/atomic.hpp" // A SuspendibleThreadSet is a set of threads that can be suspended. // A thread can join and later leave the set, and periodically yield. @@ -40,9 +41,10 @@ class SuspendibleThreadSet : public AllStatic { friend class SuspendibleThreadSetLeaver; private: + static volatile bool _suspend_all; + static uint _nthreads; static uint _nthreads_stopped; - static bool _suspend_all; static double _suspend_all_start; static bool is_synchronized(); @@ -53,9 +55,11 @@ private: // Removes the current thread from the set. static void leave(); + static bool suspend_all() { return Atomic::load(&_suspend_all); } + public: // Returns true if an suspension is in progress. - static bool should_yield() { return _suspend_all; } + static bool should_yield() { return suspend_all(); } // Suspends the current thread if a suspension is in progress. static void yield(); diff --git a/src/hotspot/share/gc/shared/taskqueue.cpp b/src/hotspot/share/gc/shared/taskqueue.cpp index 2ed1c613bc83f14de65c8dc439fa5f06cf89b4b3..1a11a536683674abccc9c11757670c728063b08e 100644 --- a/src/hotspot/share/gc/shared/taskqueue.cpp +++ b/src/hotspot/share/gc/shared/taskqueue.cpp @@ -34,7 +34,9 @@ #if TASKQUEUE_STATS const char * const TaskQueueStats::_names[last_stat_id] = { - "qpush", "qpop", "qpop-s", "qattempt", "qsteal", "opush", "omax" + "push", "pop", "pop-slow", + "st-attempt", "st-empty", "st-ctdd", "st-success", "st-ctdd-max", "st-biasdrop", + "ovflw-push", "ovflw-max" }; TaskQueueStats & TaskQueueStats::operator +=(const TaskQueueStats & addend) @@ -86,20 +88,29 @@ void TaskQueueStats::print(outputStream* stream, unsigned int width) const // quiescent; they do not hold at arbitrary times. void TaskQueueStats::verify() const { - assert(get(push) == get(pop) + get(steal), - "push=" SIZE_FORMAT " pop=" SIZE_FORMAT " steal=" SIZE_FORMAT, - get(push), get(pop), get(steal)); + assert(get(push) == get(pop) + get(steal_success), + "push=%zu pop=%zu steal=%zu", + get(push), get(pop), get(steal_success)); assert(get(pop_slow) <= get(pop), - "pop_slow=" SIZE_FORMAT " pop=" SIZE_FORMAT, + "pop_slow=%zu pop=%zu", get(pop_slow), get(pop)); - assert(get(steal) <= get(steal_attempt), - "steal=" SIZE_FORMAT " steal_attempt=" SIZE_FORMAT, - get(steal), get(steal_attempt)); + assert(get(steal_empty) <= get(steal_attempt), + "steal_empty=%zu steal_attempt=%zu", + get(steal_empty), get(steal_attempt)); + assert(get(steal_contended) <= get(steal_attempt), + "steal_contended=%zu steal_attempt=%zu", + get(steal_contended), get(steal_attempt)); + assert(get(steal_success) <= get(steal_attempt), + "steal_success=%zu steal_attempt=%zu", + get(steal_success), get(steal_attempt)); + assert(get(steal_empty) + get(steal_contended) + get(steal_success) == get(steal_attempt), + "steal_empty=%zu steal_contended=%zu steal_success=%zu steal_attempt=%zu", + get(steal_empty), get(steal_contended), get(steal_success), get(steal_attempt)); assert(get(overflow) == 0 || get(push) != 0, - "overflow=" SIZE_FORMAT " push=" SIZE_FORMAT, + "overflow=%zu push=%zu", get(overflow), get(push)); assert(get(overflow_max_len) == 0 || get(overflow) != 0, - "overflow_max_len=" SIZE_FORMAT " overflow=" SIZE_FORMAT, + "overflow_max_len=%zu overflow=%zu", get(overflow_max_len), get(overflow)); } #endif // ASSERT diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index e2c21f1dc6deb812f26f6019a4ae142133e31e63..d61326bd2fd51e5c9ced6791ba5be3db18eb0616 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,11 @@ public: pop, // number of taskqueue pops pop_slow, // subset of taskqueue pops that were done slow-path steal_attempt, // number of taskqueue steal attempts - steal, // number of taskqueue steals + steal_empty, // number of empty taskqueues + steal_contended, // number of contended steals + steal_success, // number of successful steals + steal_max_contended_in_a_row, // maximum number of contended steals in a row + steal_bias_drop, // number of times the bias has been dropped overflow, // number of overflow pushes overflow_max_len, // max length of overflow stack last_stat_id @@ -68,8 +72,16 @@ public: inline void record_push() { ++_stats[push]; } inline void record_pop() { ++_stats[pop]; } inline void record_pop_slow() { record_pop(); ++_stats[pop_slow]; } - inline void record_steal_attempt() { ++_stats[steal_attempt]; } - inline void record_steal() { ++_stats[steal]; } + inline void record_steal_attempt(uint kind) { + ++_stats[steal_attempt]; + ++_stats[steal_empty + kind]; + } + inline void record_contended_in_a_row(uint in_a_row) { + if (_stats[steal_max_contended_in_a_row] < in_a_row) { + _stats[steal_max_contended_in_a_row] = in_a_row; + } + } + inline void record_bias_drop() { ++_stats[steal_bias_drop]; } inline void record_overflow(size_t new_length); TaskQueueStats & operator +=(const TaskQueueStats & addend); @@ -81,9 +93,9 @@ public: // Print the specified line of the header (does not include a line separator). static void print_header(unsigned int line, outputStream* const stream = tty, - unsigned int width = 10); + unsigned int width = 11); // Print the statistics (does not include a line separator). - void print(outputStream* const stream = tty, unsigned int width = 10) const; + void print(outputStream* const stream = tty, unsigned int width = 11) const; DEBUG_ONLY(void verify() const;) @@ -268,6 +280,16 @@ public: // in GenericTaskQueue. uint max_elems() const { return N - 2; } + // The result of a pop_global operation. The value order of this must correspond + // to the order in the corresponding TaskQueueStats StatId. + enum class PopResult : uint { + Empty = 0, // Queue has been empty. t is undefined. + Contended = 1, // Contention prevented successful retrieval, queue most likely contains elements. t is undefined. + Success = 2 // Successfully retrieved an element, t contains it. + }; + + TASKQUEUE_STATS_ONLY(void record_steal_attempt(PopResult kind) { stats.record_steal_attempt((uint)kind); }) + TASKQUEUE_STATS_ONLY(TaskQueueStats stats;) }; @@ -328,6 +350,8 @@ protected: using TaskQueueSuper::assert_not_underflow; public: + typedef typename TaskQueueSuper::PopResult PopResult; + using TaskQueueSuper::max_elems; using TaskQueueSuper::size; @@ -357,7 +381,7 @@ public: // Like pop_local(), but uses the "global" end of the queue (the least // recently pushed). - bool pop_global(E& t); + PopResult pop_global(E& t); // Delete any resource associated with the queue. ~GenericTaskQueue(); @@ -387,7 +411,10 @@ public: void set_last_stolen_queue_id(uint id) { _last_stolen_queue_id = id; } uint last_stolen_queue_id() const { return _last_stolen_queue_id; } bool is_last_stolen_queue_id_valid() const { return _last_stolen_queue_id != InvalidQueueId; } - void invalidate_last_stolen_queue_id() { _last_stolen_queue_id = InvalidQueueId; } + void invalidate_last_stolen_queue_id() { + TASKQUEUE_STATS_ONLY(stats.record_bias_drop();) + _last_stolen_queue_id = InvalidQueueId; + } }; // OverflowTaskQueue is a TaskQueue that also includes an overflow stack for @@ -447,12 +474,16 @@ template class GenericTaskQueueSet: public TaskQueueSetSuperImpl { public: typedef typename T::element_type E; + typedef typename T::PopResult PopResult; private: uint _n; T** _queues; - bool steal_best_of_2(uint queue_num, E& t); + // Attempts to steal an element from a foreign queue (!= queue_num), setting + // the result in t. Validity of this value and the return value is the same + // as for the last pop_global() operation. + PopResult steal_best_of_2(uint queue_num, E& t); public: GenericTaskQueueSet(uint n); @@ -473,6 +504,18 @@ public: virtual uint tasks() const; uint size() const { return _n; } + +#if TASKQUEUE_STATS +private: + static void print_taskqueue_stats_hdr(outputStream* const st, const char* label); +public: + void print_taskqueue_stats(outputStream* const st, const char* label); + void reset_taskqueue_stats(); + + // Prints taskqueue set statistics into gc+task+stats=trace and resets + // its statistics. + void print_and_reset_taskqueue_stats(const char* label); +#endif // TASKQUEUE_STATS }; template void diff --git a/src/hotspot/share/gc/shared/taskqueue.inline.hpp b/src/hotspot/share/gc/shared/taskqueue.inline.hpp index c0ea64ba165b9f2794541e4d318e387f5896bd7e..f544a24d5361526d4771cf64ace29cc0ed645881 100644 --- a/src/hotspot/share/gc/shared/taskqueue.inline.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,11 +27,15 @@ #include "gc/shared/taskqueue.hpp" +#include "logging/log.hpp" +#include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" +#include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "utilities/debug.hpp" +#include "utilities/ostream.hpp" #include "utilities/stack.inline.hpp" template @@ -48,6 +52,51 @@ inline GenericTaskQueueSet::~GenericTaskQueueSet() { FREE_C_HEAP_ARRAY(T*, _queues); } +#if TASKQUEUE_STATS +template +void GenericTaskQueueSet::print_taskqueue_stats_hdr(outputStream* const st, const char* label) { + st->print_cr("GC Task Stats %s", label); + st->print("thr "); TaskQueueStats::print_header(1, st); st->cr(); + st->print("--- "); TaskQueueStats::print_header(2, st); st->cr(); +} + +template +void GenericTaskQueueSet::print_taskqueue_stats(outputStream* const st, const char* label) { + print_taskqueue_stats_hdr(st, label); + + TaskQueueStats totals; + const uint n = size(); + for (uint i = 0; i < n; ++i) { + st->print("%3u ", i); queue(i)->stats.print(st); st->cr(); + totals += queue(i)->stats; + } + st->print_raw("tot "); totals.print(st); st->cr(); + + DEBUG_ONLY(totals.verify()); +} + +template +void GenericTaskQueueSet::reset_taskqueue_stats() { + const uint n = size(); + for (uint i = 0; i < n; ++i) { + queue(i)->stats.reset(); + } +} + +template +inline void GenericTaskQueueSet::print_and_reset_taskqueue_stats(const char* label) { + if (!log_is_enabled(Trace, gc, task, stats)) { + return; + } + Log(gc, task, stats) log; + ResourceMark rm; + LogStream ls(log.trace()); + + print_taskqueue_stats(&ls, label); + reset_taskqueue_stats(); +} +#endif // TASKQUEUE_STATS + template inline GenericTaskQueue::GenericTaskQueue() : _elems(ArrayAllocator::allocate(N, F)), @@ -205,7 +254,7 @@ bool OverflowTaskQueue::pop_overflow(E& t) // reads elems[oldAge.top]. The owner's bottom == the thief's oldAge.top. // (4) Thief will discard the read value, because its cmpxchg of age will fail. template -bool GenericTaskQueue::pop_global(E& t) { +typename GenericTaskQueue::PopResult GenericTaskQueue::pop_global(E& t) { Age oldAge = age_relaxed(); // Architectures with non-multi-copy-atomic memory model require a @@ -226,7 +275,7 @@ bool GenericTaskQueue::pop_global(E& t) { uint localBot = bottom_acquire(); uint n_elems = clean_size(localBot, oldAge.top()); if (n_elems == 0) { - return false; + return PopResult::Empty; } t = _elems[oldAge.top()]; @@ -240,7 +289,7 @@ bool GenericTaskQueue::pop_global(E& t) { // Note that using "bottom" here might fail, since a pop_local might // have decremented it. assert_not_underflow(localBot, newAge.top()); - return resAge == oldAge; + return resAge == oldAge ? PopResult::Success : PopResult::Contended; } inline int randomParkAndMiller(int *seed0) { @@ -267,10 +316,10 @@ int GenericTaskQueue::next_random_queue_id() { return randomParkAndMiller(&_seed); } -template bool -GenericTaskQueueSet::steal_best_of_2(uint queue_num, E& t) { +template +typename GenericTaskQueueSet::PopResult GenericTaskQueueSet::steal_best_of_2(uint queue_num, E& t) { + T* const local_queue = queue(queue_num); if (_n > 2) { - T* const local_queue = _queues[queue_num]; uint k1 = queue_num; if (local_queue->is_last_stolen_queue_id_valid()) { @@ -287,21 +336,23 @@ GenericTaskQueueSet::steal_best_of_2(uint queue_num, E& t) { k2 = local_queue->next_random_queue_id() % _n; } // Sample both and try the larger. - uint sz1 = _queues[k1]->size(); - uint sz2 = _queues[k2]->size(); + uint sz1 = queue(k1)->size(); + uint sz2 = queue(k2)->size(); uint sel_k = 0; - bool suc = false; + PopResult suc = PopResult::Empty; if (sz2 > sz1) { sel_k = k2; - suc = _queues[k2]->pop_global(t); + suc = queue(k2)->pop_global(t); + TASKQUEUE_STATS_ONLY(local_queue->record_steal_attempt(suc);) } else if (sz1 > 0) { sel_k = k1; - suc = _queues[k1]->pop_global(t); + suc = queue(k1)->pop_global(t); + TASKQUEUE_STATS_ONLY(local_queue->record_steal_attempt(suc);) } - if (suc) { + if (suc == PopResult::Success) { local_queue->set_last_stolen_queue_id(sel_k); } else { local_queue->invalidate_last_stolen_queue_id(); @@ -311,21 +362,33 @@ GenericTaskQueueSet::steal_best_of_2(uint queue_num, E& t) { } else if (_n == 2) { // Just try the other one. uint k = (queue_num + 1) % 2; - return _queues[k]->pop_global(t); + PopResult res = queue(k)->pop_global(t); + TASKQUEUE_STATS_ONLY(local_queue->record_steal_attempt(res);) + return res; } else { assert(_n == 1, "can't be zero."); - return false; + TASKQUEUE_STATS_ONLY(local_queue->record_steal_attempt(PopResult::Empty);) + return PopResult::Empty; } } -template bool -GenericTaskQueueSet::steal(uint queue_num, E& t) { - assert(queue_num < _n, "index out of range."); - for (uint i = 0; i < 2 * _n; i++) { - TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal_attempt()); - if (steal_best_of_2(queue_num, t)) { - TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal()); +template +bool GenericTaskQueueSet::steal(uint queue_num, E& t) { + uint const num_retries = 2 * _n; + + TASKQUEUE_STATS_ONLY(uint contended_in_a_row = 0;) + for (uint i = 0; i < num_retries; i++) { + PopResult sr = steal_best_of_2(queue_num, t); + if (sr == PopResult::Success) { return true; + } else if (sr == PopResult::Contended) { + TASKQUEUE_STATS_ONLY( + contended_in_a_row++; + queue(queue_num)->stats.record_contended_in_a_row(contended_in_a_row); + ) + } else { + assert(sr == PopResult::Empty, "must be"); + TASKQUEUE_STATS_ONLY(contended_in_a_row = 0;) } } return false; diff --git a/src/hotspot/share/gc/shared/vmStructs_gc.hpp b/src/hotspot/share/gc/shared/vmStructs_gc.hpp index 2de1cc8c57cd279a43bb0b6fa4646099746ae81c..f9b1c631123fc47fc4b59e9cd5cffb93003f6dc4 100644 --- a/src/hotspot/share/gc/shared/vmStructs_gc.hpp +++ b/src/hotspot/share/gc/shared/vmStructs_gc.hpp @@ -261,10 +261,6 @@ declare_constant(BarrierSet::ModRef) \ declare_constant(BarrierSet::CardTableBarrierSet) \ \ - declare_constant(BOTConstants::LogN) \ - declare_constant(BOTConstants::LogN_words) \ - declare_constant(BOTConstants::N_bytes) \ - declare_constant(BOTConstants::N_words) \ declare_constant(BOTConstants::LogBase) \ declare_constant(BOTConstants::Base) \ declare_constant(BOTConstants::N_powers) \ @@ -274,9 +270,6 @@ declare_constant(CardTable::dirty_card) \ declare_constant(CardTable::Precise) \ declare_constant(CardTable::ObjHeadPreciseArray) \ - declare_constant(CardTable::card_shift) \ - declare_constant(CardTable::card_size) \ - declare_constant(CardTable::card_size_in_words) \ \ declare_constant(CollectedHeap::Serial) \ declare_constant(CollectedHeap::Parallel) \ diff --git a/src/hotspot/share/gc/shared/weakProcessor.hpp b/src/hotspot/share/gc/shared/weakProcessor.hpp index 5eb2c59f3f2da460e757eb2f15e5ac6d240ef25d..b86129c9b93500abe98fbd704605bef90c3160d4 100644 --- a/src/hotspot/share/gc/shared/weakProcessor.hpp +++ b/src/hotspot/share/gc/shared/weakProcessor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ #include "gc/shared/oopStorageParState.hpp" #include "gc/shared/oopStorageSetParState.hpp" #include "gc/shared/workerThread.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class WeakProcessorTimes; class WorkerThreads; diff --git a/src/hotspot/share/gc/shared/workerPolicy.hpp b/src/hotspot/share/gc/shared/workerPolicy.hpp index 377c9135d29c5af619ab67cc525cd13eeb40185c..769b0e0ed8b3103bf56ca65a5d74b532ef0b2f9b 100644 --- a/src/hotspot/share/gc/shared/workerPolicy.hpp +++ b/src/hotspot/share/gc/shared/workerPolicy.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_WORKERPOLICY_HPP #define SHARE_GC_SHARED_WORKERPOLICY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class WorkerPolicy : public AllStatic { diff --git a/src/hotspot/share/gc/shared/workerThread.cpp b/src/hotspot/share/gc/shared/workerThread.cpp index 183349ef245ef5d61e37a7eef1e6abc36cc10333..9d141464a394be58a10231e93ea890ebaeef2ecb 100644 --- a/src/hotspot/share/gc/shared/workerThread.cpp +++ b/src/hotspot/share/gc/shared/workerThread.cpp @@ -59,8 +59,9 @@ void WorkerTaskDispatcher::worker_run_task() { // Wait for the coordinator to dispatch a task. _start_semaphore.wait(); - // Get worker id. + // Get and set worker id. const uint worker_id = Atomic::fetch_and_add(&_started, 1u); + WorkerThread::set_worker_id(worker_id); // Run task. GCIdMark gc_id_mark(_task->gc_id()); @@ -91,18 +92,20 @@ void WorkerThreads::initialize_workers() { } } -WorkerThread* WorkerThreads::create_worker(uint id) { +WorkerThread* WorkerThreads::create_worker(uint name_suffix) { if (is_init_completed() && InjectGCWorkerCreationFailure) { return NULL; } - WorkerThread* const worker = new WorkerThread(_name, id, &_dispatcher); + WorkerThread* const worker = new WorkerThread(_name, name_suffix, &_dispatcher); if (!os::create_thread(worker, os::gc_thread)) { delete worker; return NULL; } + on_create_worker(worker); + os::start_thread(worker); return worker; @@ -146,10 +149,11 @@ void WorkerThreads::run_task(WorkerTask* task, uint num_workers) { run_task(task); } -WorkerThread::WorkerThread(const char* name_prefix, uint id, WorkerTaskDispatcher* dispatcher) : - _dispatcher(dispatcher), - _id(id) { - set_name("%s#%d", name_prefix, id); +THREAD_LOCAL uint WorkerThread::_worker_id = UINT_MAX; + +WorkerThread::WorkerThread(const char* name_prefix, uint name_suffix, WorkerTaskDispatcher* dispatcher) : + _dispatcher(dispatcher) { + set_name("%s#%u", name_prefix, name_suffix); } void WorkerThread::run() { diff --git a/src/hotspot/share/gc/shared/workerThread.hpp b/src/hotspot/share/gc/shared/workerThread.hpp index d4c16c246f06b52d88ae1ed6d23caace3c248e81..bdb61f34ed9d90163441bae2ae73eecb09fb3111 100644 --- a/src/hotspot/share/gc/shared/workerThread.hpp +++ b/src/hotspot/share/gc/shared/workerThread.hpp @@ -91,8 +91,10 @@ private: uint _active_workers; WorkerTaskDispatcher _dispatcher; + WorkerThread* create_worker(uint name_suffix); + protected: - virtual WorkerThread* create_worker(uint id); + virtual void on_create_worker(WorkerThread* worker) {} public: WorkerThreads(const char* name, uint max_workers); @@ -117,23 +119,19 @@ public: }; class WorkerThread : public NamedThread { + friend class WorkerTaskDispatcher; + private: - WorkerTaskDispatcher* const _dispatcher; - const uint _id; + static THREAD_LOCAL uint _worker_id; -public: - static WorkerThread* current() { - return WorkerThread::cast(Thread::current()); - } + WorkerTaskDispatcher* const _dispatcher; - static WorkerThread* cast(Thread* t) { - assert(t->is_Worker_thread(), "incorrect cast to WorkerThread"); - return static_cast(t); - } + static void set_worker_id(uint worker_id) { _worker_id = worker_id; } - WorkerThread(const char* name_prefix, uint id, WorkerTaskDispatcher* dispatcher); +public: + static uint worker_id() { return _worker_id; } - uint id() const { return _id; } + WorkerThread(const char* name_prefix, uint which, WorkerTaskDispatcher* dispatcher); bool is_Worker_thread() const override { return true; } const char* type_name() const override { return "WorkerThread"; } diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp index 52c0182953e135238b5126f784733d2d1b7e28da..617612fde3638eeb601740091688395850a6f855 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp @@ -718,7 +718,7 @@ Node* ShenandoahBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& acces // Support for GC barriers emitted during parsing bool ShenandoahBarrierSetC2::is_gc_barrier_node(Node* node) const { - if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) return true; + if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier || node->Opcode() == Op_ShenandoahIUBarrier) return true; if (node->Opcode() != Op_CallLeaf && node->Opcode() != Op_CallLeafNoFP) { return false; } diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp index ef16bfa9376eae26f3c085bd2ed2f80984392e5e..0c42824616997c578d80662fe82067aca95aa1e7 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp @@ -65,19 +65,18 @@ void ShenandoahIUMode::initialize_flags() const { } ShenandoahHeuristics* ShenandoahIUMode::initialize_heuristics() const { - if (ShenandoahGCHeuristics != NULL) { - if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { - return new ShenandoahAggressiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { - return new ShenandoahStaticHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { - return new ShenandoahAdaptiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { - return new ShenandoahCompactHeuristics(); - } else { - vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); - } + if (ShenandoahGCHeuristics == NULL) { + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } - ShouldNotReachHere(); + if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { + return new ShenandoahAggressiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { + return new ShenandoahStaticHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { + return new ShenandoahAdaptiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { + return new ShenandoahCompactHeuristics(); + } + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); return NULL; } diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp index a864200954464e16a2346f58a1c82b86129e52b8..caa22bbe068f54a000b725a7960dc607fc4df9d5 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp @@ -28,6 +28,7 @@ #include "logging/log.hpp" #include "logging/logTag.hpp" #include "runtime/globals_extension.hpp" +#include "runtime/java.hpp" void ShenandoahPassiveMode::initialize_flags() const { // Do not allow concurrent cycles. @@ -55,9 +56,8 @@ void ShenandoahPassiveMode::initialize_flags() const { // No barriers are required to run. } ShenandoahHeuristics* ShenandoahPassiveMode::initialize_heuristics() const { - if (ShenandoahGCHeuristics != NULL) { - return new ShenandoahPassiveHeuristics(); + if (ShenandoahGCHeuristics == NULL) { + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } - ShouldNotReachHere(); - return NULL; + return new ShenandoahPassiveHeuristics(); } diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp index 7d9ecabc14e3001f67b6a2d29b3c429cb54817a1..06ed25e59c62b0ee7d9cc218d04252de5a7dc825 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp @@ -53,19 +53,18 @@ void ShenandoahSATBMode::initialize_flags() const { } ShenandoahHeuristics* ShenandoahSATBMode::initialize_heuristics() const { - if (ShenandoahGCHeuristics != NULL) { - if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { - return new ShenandoahAggressiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { - return new ShenandoahStaticHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { - return new ShenandoahAdaptiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { - return new ShenandoahCompactHeuristics(); - } else { - vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); - } + if (ShenandoahGCHeuristics == NULL) { + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } - ShouldNotReachHere(); + if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { + return new ShenandoahAggressiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { + return new ShenandoahStaticHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { + return new ShenandoahAdaptiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { + return new ShenandoahCompactHeuristics(); + } + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); return NULL; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp index f8b7489a3bbd0e7aedc4d5b1fe599f531629aedc..acc497618c9c5289b68845417464318913705a3a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021, Red Hat, Inc. All rights reserved. - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Red Hat, Inc. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHBREAKPOINT_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHBREAKPOINT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ShenandoahBreakpoint : public AllStatic { private: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp index 4e56b3e5d4f3528cd828b2e0d354169bf4999e03..d03c029a0da44f5f92c1fc1952e71eb326f41868 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp @@ -227,7 +227,7 @@ ShenandoahCodeBlobAndDisarmClosure::ShenandoahCodeBlobAndDisarmClosure(OopClosur void ShenandoahCodeBlobAndDisarmClosure::do_code_blob(CodeBlob* cb) { nmethod* const nm = cb->as_nmethod_or_null(); - if (nm != NULL && nm->oops_do_try_claim()) { + if (nm != NULL) { assert(!ShenandoahNMethod::gc_data(nm)->is_unregistered(), "Should not be here"); CodeBlobToOopClosure::do_code_blob(cb); _bs->disarm(nm); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp index 17bc5b78934425b0a9582578a5c9c9f6a1ef249e..377d768833337e2d2bdeae1cf6e9e48239b26dc0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #include "gc/shenandoah/shenandoahSharedVariables.hpp" #include "gc/shenandoah/shenandoahLock.hpp" #include "gc/shenandoah/shenandoahPadding.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/iterator.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 8cbcc86172b61a4a2444183b78e3d53ef3d3b3f6..f72d31e1f6985453a2abcd2e74571b475727a903 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -416,7 +416,7 @@ void ShenandoahHeap::initialize_mode() { vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option"); } } else { - ShouldNotReachHere(); + vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option (null)"); } _gc_mode->initialize_flags(); if (_gc_mode->is_diagnostic() && !UnlockDiagnosticVMOptions) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp index 72a87a9d3dee264403b17e373c9dfd08fbb32add..b828582336c47d021d649dfd94b7b7bd564365f4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" +#include "gc/shared/workerThread.hpp" #include "gc/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc/shenandoah/shenandoahReferenceProcessor.hpp" #include "gc/shenandoah/shenandoahThreadLocalData.hpp" @@ -337,7 +338,6 @@ bool ShenandoahReferenceProcessor::discover(oop reference, ReferenceType type, u } // Add reference to discovered list - assert(worker_id != ShenandoahThreadLocalData::INVALID_WORKER_ID, "need valid worker ID"); ShenandoahRefProcThreadLocal& refproc_data = _ref_proc_thread_locals[worker_id]; oop discovered_head = refproc_data.discovered_list_head(); if (discovered_head == NULL) { @@ -361,7 +361,7 @@ bool ShenandoahReferenceProcessor::discover_reference(oop reference, ReferenceTy } log_trace(gc, ref)("Encountered Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type)); - uint worker_id = ShenandoahThreadLocalData::worker_id(Thread::current()); + uint worker_id = WorkerThread::worker_id(); _ref_proc_thread_locals->inc_encountered(type); if (UseCompressedOops) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp index a87918ce8a1947c0bed8a4d97fbc3a2d1bd07426..21a21053c8973ba7fbc984fe61e38273085fba4b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp @@ -79,7 +79,6 @@ ShenandoahThreadRoots::~ShenandoahThreadRoots() { } ShenandoahCodeCacheRoots::ShenandoahCodeCacheRoots(ShenandoahPhaseTimings::Phase phase) : _phase(phase) { - nmethod::oops_do_marking_prologue(); } void ShenandoahCodeCacheRoots::code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id) { @@ -87,39 +86,12 @@ void ShenandoahCodeCacheRoots::code_blobs_do(CodeBlobClosure* blob_cl, uint work _coderoots_iterator.possibly_parallel_blobs_do(blob_cl); } -ShenandoahCodeCacheRoots::~ShenandoahCodeCacheRoots() { - nmethod::oops_do_marking_epilogue(); -} - ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) : _heap(ShenandoahHeap::heap()), _phase(phase), _worker_phase(phase) { } -ShenandoahRootScanner::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) : - ShenandoahRootProcessor(phase), - _thread_roots(phase, n_workers > 1) { - nmethod::oops_do_marking_prologue(); -} - -ShenandoahRootScanner::~ShenandoahRootScanner() { - nmethod::oops_do_marking_epilogue(); -} - -void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops) { - MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations); - roots_do(worker_id, oops, &blobs_cl); -} - -void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CodeBlobClosure* code, ThreadClosure *tc) { - assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); - - ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc); - ResourceMark rm; - _thread_roots.threads_do(&tc_cl, worker_id); -} - ShenandoahSTWRootScanner::ShenandoahSTWRootScanner(ShenandoahPhaseTimings::Phase phase) : ShenandoahRootProcessor(phase), _thread_roots(phase, ShenandoahHeap::heap()->workers()->active_workers() > 1), @@ -237,7 +209,6 @@ void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) { static_cast(&blobs_and_disarm_Cl) : static_cast(&code_blob_cl); CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong); - AlwaysTrueClosure always_true; // Process light-weight/limited parallel roots then _vm_roots.oops_do(oops, worker_id); @@ -250,29 +221,52 @@ void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) { } ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner(uint n_workers) : - ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots), - _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/), - _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots), - _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, n_workers, true /*heap iteration*/), - _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots), - _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) { - } - - void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) { - // Must use _claim_other to avoid interfering with concurrent CLDG iteration - CLDToOopClosure clds(oops, ClassLoaderData::_claim_other); - MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations); - ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL); - AlwaysTrueClosure always_true; - - ResourceMark rm; - - // Process light-weight/limited parallel roots then - _vm_roots.oops_do(oops, 0); - _weak_roots.oops_do(oops, 0); - _cld_roots.cld_do(&clds, 0); - - // Process heavy-weight/fully parallel roots the last - _code_roots.code_blobs_do(&code, 0); - _thread_roots.threads_do(&tc_cl, 0); - } + ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots), + _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/), + _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots), + _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, n_workers, true /*heap iteration*/), + _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots), + _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) { +} + +class ShenandoahMarkCodeBlobClosure : public CodeBlobClosure { +private: + OopClosure* const _oops; + BarrierSetNMethod* const _bs_nm; + +public: + ShenandoahMarkCodeBlobClosure(OopClosure* oops) : + _oops(oops), + _bs_nm(BarrierSet::barrier_set()->barrier_set_nmethod()) {} + + virtual void do_code_blob(CodeBlob* cb) { + nmethod* const nm = cb->as_nmethod_or_null(); + if (nm != nullptr) { + if (_bs_nm != nullptr) { + // Make sure it only sees to-space objects + _bs_nm->nmethod_entry_barrier(nm); + } + ShenandoahNMethod* const snm = ShenandoahNMethod::gc_data(nm); + assert(snm != nullptr, "Sanity"); + snm->oops_do(_oops, false /*fix_relocations*/); + } + } +}; + +void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) { + // Must use _claim_other to avoid interfering with concurrent CLDG iteration + CLDToOopClosure clds(oops, ClassLoaderData::_claim_other); + ShenandoahMarkCodeBlobClosure code(oops); + ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL); + + ResourceMark rm; + + // Process light-weight/limited parallel roots then + _vm_roots.oops_do(oops, 0); + _weak_roots.oops_do(oops, 0); + _cld_roots.cld_do(&clds, 0); + + // Process heavy-weight/fully parallel roots the last + _code_roots.code_blobs_do(&code, 0); + _thread_roots.threads_do(&tc_cl, 0); +} diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp index 1ecee9906a547f2cb66c79d811cded242cc4bf9c..75a23aea04534d53d728eb31f6260e43861898fc 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp @@ -102,7 +102,6 @@ private: ShenandoahCodeRootsIterator _coderoots_iterator; public: ShenandoahCodeCacheRoots(ShenandoahPhaseTimings::Phase phase); - ~ShenandoahCodeCacheRoots(); void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); }; @@ -143,20 +142,6 @@ public: ShenandoahHeap* heap() const { return _heap; } }; -class ShenandoahRootScanner : public ShenandoahRootProcessor { -private: - ShenandoahThreadRoots _thread_roots; - -public: - ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); - ~ShenandoahRootScanner(); - - void roots_do(uint worker_id, OopClosure* cl); - -private: - void roots_do(uint worker_id, OopClosure* oops, CodeBlobClosure* code, ThreadClosure* tc = NULL); -}; - // STW root scanner class ShenandoahSTWRootScanner : public ShenandoahRootProcessor { private: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp index e499c3543ff0623e7a030f75270e04b36b4ed1fc..5677f3daa60918982b729974110246b35c0a4326 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp @@ -82,7 +82,7 @@ ShenandoahClassLoaderDataRoots::ShenandoahClassLoaderDataRoots(Shena if (heap_iteration) { ClassLoaderDataGraph::clear_claimed_marks(ClassLoaderData::_claim_other); } else { - ClassLoaderDataGraph::clear_claimed_marks(); + ClassLoaderDataGraph::clear_claimed_marks(ClassLoaderData::_claim_strong); } if (CONCURRENT) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp index 788fe3fbeca7ee36ed7cf0dbb1729c25236e0e94..e187e4360b16b7d713149a7ee2fcc5d34753e2c1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2018, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHRUNTIME_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHRUNTIME_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" class JavaThread; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp index e34073f9b8ee76055d91e9810ee7382b641f0307..8d50bb35ee1d220fccd16b5972298902a218d1be 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp @@ -36,9 +36,6 @@ #include "utilities/sizes.hpp" class ShenandoahThreadLocalData { -public: - static const uint INVALID_WORKER_ID = uint(-1); - private: char _gc_state; // Evacuation OOM state @@ -47,7 +44,6 @@ private: SATBMarkQueue _satb_mark_queue; PLAB* _gclab; size_t _gclab_size; - uint _worker_id; int _disarmed_value; double _paced_time; @@ -58,7 +54,6 @@ private: _satb_mark_queue(&ShenandoahBarrierSet::satb_mark_queue_set()), _gclab(NULL), _gclab_size(0), - _worker_id(INVALID_WORKER_ID), _disarmed_value(0), _paced_time(0) { @@ -103,16 +98,6 @@ public: return data(thread)->_gc_state; } - static void set_worker_id(Thread* thread, uint id) { - assert(thread->is_Worker_thread(), "Must be a worker thread"); - data(thread)->_worker_id = id; - } - - static uint worker_id(Thread* thread) { - assert(thread->is_Worker_thread(), "Must be a worker thread"); - return data(thread)->_worker_id; - } - static void initialize_gclab(Thread* thread) { assert (thread->is_Java_thread() || thread->is_Worker_thread(), "Only Java and GC worker threads are allowed to get GCLABs"); assert(data(thread)->_gclab == NULL, "Only initialize once"); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp index 4881aff0bf1e46df7877ea21163a8ef222b6a7c1..89db25a80aa2a10d6ebf09e4b6a0df52081bae0a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp @@ -146,10 +146,8 @@ ShenandoahGCWorkerPhase::~ShenandoahGCWorkerPhase() { _timings->record_workers_end(_phase); } -ShenandoahWorkerSession::ShenandoahWorkerSession(uint worker_id) : _worker_id(worker_id) { - Thread* thr = Thread::current(); - assert(ShenandoahThreadLocalData::worker_id(thr) == ShenandoahThreadLocalData::INVALID_WORKER_ID, "Already set"); - ShenandoahThreadLocalData::set_worker_id(thr, worker_id); +ShenandoahWorkerSession::ShenandoahWorkerSession(uint worker_id) { + assert(worker_id == WorkerThread::worker_id(), "Wrong worker id"); } ShenandoahConcurrentWorkerSession::~ShenandoahConcurrentWorkerSession() { @@ -157,12 +155,5 @@ ShenandoahConcurrentWorkerSession::~ShenandoahConcurrentWorkerSession() { } ShenandoahParallelWorkerSession::~ShenandoahParallelWorkerSession() { - _event.commit(GCId::current(), _worker_id, ShenandoahPhaseTimings::phase_name(ShenandoahGCPhase::current_phase())); -} -ShenandoahWorkerSession::~ShenandoahWorkerSession() { -#ifdef ASSERT - Thread* thr = Thread::current(); - assert(ShenandoahThreadLocalData::worker_id(thr) != ShenandoahThreadLocalData::INVALID_WORKER_ID, "Must be set"); - ShenandoahThreadLocalData::set_worker_id(thr, ShenandoahThreadLocalData::INVALID_WORKER_ID); -#endif + _event.commit(GCId::current(), WorkerThread::worker_id(), ShenandoahPhaseTimings::phase_name(ShenandoahGCPhase::current_phase())); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp index 49ff6ca28649f8b729bc12861ef3ac4a02b6a5f5..5b593dbfd0cc99bc28e2c3297ef4157f7f792606 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ #include "gc/shared/gcVMOperations.hpp" #include "gc/shared/isGCActiveMark.hpp" #include "gc/shared/suspendibleThreadSet.hpp" +#include "gc/shared/workerThread.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahThreadLocalData.hpp" #include "jfr/jfrEvents.hpp" @@ -173,16 +174,10 @@ public: class ShenandoahWorkerSession : public StackObj { protected: - uint _worker_id; - ShenandoahWorkerSession(uint worker_id); - ~ShenandoahWorkerSession(); public: static inline uint worker_id() { - Thread* thr = Thread::current(); - uint id = ShenandoahThreadLocalData::worker_id(thr); - assert(id != ShenandoahThreadLocalData::INVALID_WORKER_ID, "Worker session has not been created"); - return id; + return WorkerThread::worker_id(); } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp index 34202dac6574b8345ce61a4d6d081d0d21770714..d842c87e405c4771ee2eb0e2f9cdea7be138eda0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp @@ -71,11 +71,9 @@ ShenandoahPushWorkerScope::~ShenandoahPushWorkerScope() { assert(nworkers == _old_workers, "Must be able to restore"); } -WorkerThread* ShenandoahWorkerThreads::create_worker(uint id) { - WorkerThread* worker = WorkerThreads::create_worker(id); +void ShenandoahWorkerThreads::on_create_worker(WorkerThread* worker) { ShenandoahThreadLocalData::create(worker); if (_initialize_gclab) { ShenandoahThreadLocalData::initialize_gclab(worker); } - return worker; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.hpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.hpp index f5bd3ea0e481b760a7a37ec93f3ce7829476ea0d..a428f26216adebe478814066d77e02c08eb6bf93 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.hpp @@ -60,9 +60,8 @@ public: WorkerThreads(name, workers), _initialize_gclab(false) { } - // Create a GC worker. // We need to initialize gclab for dynamic allocated workers - WorkerThread* create_worker(uint id); + void on_create_worker(WorkerThread* worker); void set_initialize_gclab() { assert(!_initialize_gclab, "Can only enable once"); _initialize_gclab = true; } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp index 10a6fec6535d5b800dec04d07f39dd03d85c6ec6..3f47822f2200b0e9675ed247630eaeea04c5c25b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHWORKERPOLICY_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHWORKERPOLICY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ShenandoahWorkerPolicy : AllStatic { private: diff --git a/src/hotspot/share/gc/z/zAbort.hpp b/src/hotspot/share/gc/z/zAbort.hpp index 1a5bcc15f1971516078644a4c34643e75ec00613..f87bca8c0a389d4b2e0333742d277da41a315b2e 100644 --- a/src/hotspot/share/gc/z/zAbort.hpp +++ b/src/hotspot/share/gc/z/zAbort.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZABORT_HPP #define SHARE_GC_Z_ZABORT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZAbort : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zAddress.hpp b/src/hotspot/share/gc/z/zAddress.hpp index eddd104189e1e224ba9850155239ac233416713e..2908c37bbe6f1783529dbcda9921cd1f02d9dfc0 100644 --- a/src/hotspot/share/gc/z/zAddress.hpp +++ b/src/hotspot/share/gc/z/zAddress.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ #ifndef SHARE_GC_Z_ZADDRESS_HPP #define SHARE_GC_Z_ZADDRESS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class ZAddress : public AllStatic { friend class ZAddressTest; diff --git a/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp b/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp index b6a03776f5cffaa52c423906c1836d58cc5dc7f5..ec0faf2c0870add95cb556592a9ee1e63f8c97b1 100644 --- a/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp +++ b/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ #ifndef SHARE_GC_Z_ZADDRESSSPACELIMIT_HPP #define SHARE_GC_Z_ZADDRESSSPACELIMIT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class ZAddressSpaceLimit : public AllStatic { public: diff --git a/src/hotspot/share/gc/z/zBarrier.hpp b/src/hotspot/share/gc/z/zBarrier.hpp index d57bef74f91737a2ae6b3014eea5c2b5e133d49c..2dfc1591888fa864ec883f0363093a2303256376 100644 --- a/src/hotspot/share/gc/z/zBarrier.hpp +++ b/src/hotspot/share/gc/z/zBarrier.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZBARRIER_HPP #define SHARE_GC_Z_ZBARRIER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/iterator.hpp" #include "oops/oop.hpp" diff --git a/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp b/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp index f3d4fb9c6bd84391ea224609ce3a1860cba499ca..b3a143de3e97129b7a18eafaa0d089b220add38e 100644 --- a/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp +++ b/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZBARRIERSETRUNTIME_HPP #define SHARE_GC_Z_ZBARRIERSETRUNTIME_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/accessDecorators.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/z/zBitField.hpp b/src/hotspot/share/gc/z/zBitField.hpp index 4d7171c41ac1da525e03f20a1ff5ae2167b730ad..9bec4e05594cf21355d73f99afe1ec2eef5f6e31 100644 --- a/src/hotspot/share/gc/z/zBitField.hpp +++ b/src/hotspot/share/gc/z/zBitField.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,8 +24,9 @@ #ifndef SHARE_GC_Z_ZBITFIELD_HPP #define SHARE_GC_Z_ZBITFIELD_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" // // Example diff --git a/src/hotspot/share/gc/z/zBreakpoint.hpp b/src/hotspot/share/gc/z/zBreakpoint.hpp index 14ba227e1895b8ae4d5a62aec41d172bb81ac69a..920169fb6a6716abb7db1588313f2691ee011807 100644 --- a/src/hotspot/share/gc/z/zBreakpoint.hpp +++ b/src/hotspot/share/gc/z/zBreakpoint.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZBREAKPOINT_HPP #define SHARE_GC_Z_ZBREAKPOINT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZBreakpoint : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zCPU.hpp b/src/hotspot/share/gc/z/zCPU.hpp index 65e04cc75e3bd5854149bde8a2ea1732da51a239..0acc949e508b8f8cc569fd7acdc160f7126e3e0d 100644 --- a/src/hotspot/share/gc/z/zCPU.hpp +++ b/src/hotspot/share/gc/z/zCPU.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZCPU_HPP #define SHARE_GC_Z_ZCPU_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/padded.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/z/zHash.hpp b/src/hotspot/share/gc/z/zHash.hpp index 5752d2abee3c9dbb5b741986ccb5e2eb5839273e..e6469698488901a322f6de54665af2a965ff303f 100644 --- a/src/hotspot/share/gc/z/zHash.hpp +++ b/src/hotspot/share/gc/z/zHash.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZHASH_HPP #define SHARE_GC_Z_ZHASH_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class ZHash : public AllStatic { diff --git a/src/hotspot/share/gc/z/zHeuristics.hpp b/src/hotspot/share/gc/z/zHeuristics.hpp index 5b810a84851cdddd361a78657d026800fd61bfcb..362fd775f0fa31ec0e1c01b41d901e49efe4480b 100644 --- a/src/hotspot/share/gc/z/zHeuristics.hpp +++ b/src/hotspot/share/gc/z/zHeuristics.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZHEURISTICS_HPP #define SHARE_GC_Z_ZHEURISTICS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZHeuristics : public AllStatic { public: diff --git a/src/hotspot/share/gc/z/zLargePages.hpp b/src/hotspot/share/gc/z/zLargePages.hpp index 1201b4962661348583eba7b5000c0a4b6ceed3d1..9f7c8310e50f4fc03e1daa8feba81000e858c0ee 100644 --- a/src/hotspot/share/gc/z/zLargePages.hpp +++ b/src/hotspot/share/gc/z/zLargePages.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZLARGEPAGES_HPP #define SHARE_GC_Z_ZLARGEPAGES_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZLargePages : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zNMethod.hpp b/src/hotspot/share/gc/z/zNMethod.hpp index 40ac93adb8e12ef0e903014613efa39744b2aabf..117c5e34f4ecb54ff2982f5e45ed6b35a070afd2 100644 --- a/src/hotspot/share/gc/z/zNMethod.hpp +++ b/src/hotspot/share/gc/z/zNMethod.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZNMETHOD_HPP #define SHARE_GC_Z_ZNMETHOD_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class nmethod; class NMethodClosure; diff --git a/src/hotspot/share/gc/z/zNMethodTable.hpp b/src/hotspot/share/gc/z/zNMethodTable.hpp index 26ae2d2793332567cf1416801a1e765fb525f1c4..a1af8512f698b7c6a9a06e0899975a003cc1204b 100644 --- a/src/hotspot/share/gc/z/zNMethodTable.hpp +++ b/src/hotspot/share/gc/z/zNMethodTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "gc/z/zNMethodTableIteration.hpp" #include "gc/z/zSafeDelete.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class nmethod; class NMethodClosure; diff --git a/src/hotspot/share/gc/z/zNUMA.hpp b/src/hotspot/share/gc/z/zNUMA.hpp index 0dc4390e8b475809cb809260e9d59ab62a65221a..fb29e1faaa733906983e82b62c56f7b2bea94064 100644 --- a/src/hotspot/share/gc/z/zNUMA.hpp +++ b/src/hotspot/share/gc/z/zNUMA.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ #ifndef SHARE_GC_Z_ZNUMA_HPP #define SHARE_GC_Z_ZNUMA_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class ZNUMA : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zOop.hpp b/src/hotspot/share/gc/z/zOop.hpp index cf752ba61c3aff076284280c1b016e6f639b338b..4fb0e6499e14a0c394f4074ca68cd6053d235616 100644 --- a/src/hotspot/share/gc/z/zOop.hpp +++ b/src/hotspot/share/gc/z/zOop.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZOOP_HPP #define SHARE_GC_Z_ZOOP_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" class ZOop : public AllStatic { diff --git a/src/hotspot/share/gc/z/zPhysicalMemory.cpp b/src/hotspot/share/gc/z/zPhysicalMemory.cpp index abdf7df69b08090e2ab7566e63e4082dc01787e0..eb889f4e4f2c31090124948c368e2f80f03ac1a0 100644 --- a/src/hotspot/share/gc/z/zPhysicalMemory.cpp +++ b/src/hotspot/share/gc/z/zPhysicalMemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -282,7 +282,7 @@ void ZPhysicalMemoryManager::nmt_commit(uintptr_t offset, size_t size) const { } void ZPhysicalMemoryManager::nmt_uncommit(uintptr_t offset, size_t size) const { - if (MemTracker::tracking_level() > NMT_minimal) { + if (MemTracker::enabled()) { const uintptr_t addr = ZAddress::marked0(offset); Tracker tracker(Tracker::uncommit); tracker.record((address)addr, size); diff --git a/src/hotspot/share/gc/z/zResurrection.hpp b/src/hotspot/share/gc/z/zResurrection.hpp index a88b93544692307443f18edf81167315fbc4e2cd..3d6a8f95a1cd833893a7435cb88f66136ea45a0d 100644 --- a/src/hotspot/share/gc/z/zResurrection.hpp +++ b/src/hotspot/share/gc/z/zResurrection.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZRESURRECTION_HPP #define SHARE_GC_Z_ZRESURRECTION_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZResurrection : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zThread.hpp b/src/hotspot/share/gc/z/zThread.hpp index f98b7a05fb611ca9f09d77c5cab5c2cc94d32296..c67807ff96ecdfe07b7d825b336410acd5c7a249 100644 --- a/src/hotspot/share/gc/z/zThread.hpp +++ b/src/hotspot/share/gc/z/zThread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZTHREAD_HPP #define SHARE_GC_Z_ZTHREAD_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class ZThread : public AllStatic { diff --git a/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp b/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp index d6693fceb0085b296625a70229336858aa11f884..086c8a5c351ce5b8d4ad90dc10b08732bd14bfbf 100644 --- a/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp +++ b/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "gc/shared/threadLocalAllocBuffer.hpp" #include "gc/z/zValue.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JavaThread; diff --git a/src/hotspot/share/gc/z/zUtils.hpp b/src/hotspot/share/gc/z/zUtils.hpp index f4abea9c6feeed61f5f3a6a833fd35ad8fbc2d55..470329daf0d393f658315b7960421e34c9ac075f 100644 --- a/src/hotspot/share/gc/z/zUtils.hpp +++ b/src/hotspot/share/gc/z/zUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ #ifndef SHARE_GC_Z_ZUTILS_HPP #define SHARE_GC_Z_ZUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class ZUtils : public AllStatic { public: diff --git a/src/hotspot/share/gc/z/zValue.hpp b/src/hotspot/share/gc/z/zValue.hpp index 281a2e48b8cbebb089fd8f8941be65fe3b1e60c5..e2c67e8c48d0f772a71aff833d9751e6d24454b9 100644 --- a/src/hotspot/share/gc/z/zValue.hpp +++ b/src/hotspot/share/gc/z/zValue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZVALUE_HPP #define SHARE_GC_Z_ZVALUE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" // diff --git a/src/hotspot/share/gc/z/zVerify.hpp b/src/hotspot/share/gc/z/zVerify.hpp index db2d56d00951f5e92ebc3b9f883670385bc2b123..8d7abd4a8d53152ab1ac2e24bf18600f34a48660 100644 --- a/src/hotspot/share/gc/z/zVerify.hpp +++ b/src/hotspot/share/gc/z/zVerify.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZVERIFY_HPP #define SHARE_GC_Z_ZVERIFY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class frame; class ZPageAllocator; diff --git a/src/hotspot/share/include/cds.h b/src/hotspot/share/include/cds.h index eeb45ba34c4d755996d34a081e60893363cc75d3..21a7a43b3af3c8aae189d34b09497a5f85340544 100644 --- a/src/hotspot/share/include/cds.h +++ b/src/hotspot/share/include/cds.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,8 @@ #define NUM_CDS_REGIONS 7 // this must be the same as MetaspaceShared::n_regions #define CDS_ARCHIVE_MAGIC 0xf00baba2 #define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8 -#define CURRENT_CDS_ARCHIVE_VERSION 12 +#define CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION 13 +#define CURRENT_CDS_ARCHIVE_VERSION 14 typedef struct CDSFileMapRegion { int _crc; // CRC checksum of this region. @@ -47,7 +48,7 @@ typedef struct CDSFileMapRegion { int _is_heap_region; // Used by SA and debug build. int _is_bitmap_region; // Relocation bitmap for RO/RW regions (used by SA and debug build). int _mapped_from_file; // Is this region mapped from a file? - // If false, this region was initialized using os::read(). + // If false, this region was initialized using ::read(). size_t _file_offset; // Data for this region starts at this offset in the archive file. size_t _mapping_offset; // This region should be mapped at this offset from the base address // - for non-heap regions, the base address is SharedBaseAddress @@ -59,12 +60,13 @@ typedef struct CDSFileMapRegion { char* _mapped_base; // Actually mapped address (NULL if this region is not mapped). } CDSFileMapRegion; -// This portion of the archive file header must remain unchanged for _version >= 12. +// This portion of the archive file header must remain unchanged for +// _version >= CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION (12). // This makes it possible to read important information from a CDS archive created by // a different version of HotSpot, so that we can automatically regenerate the archive as necessary. typedef struct GenericCDSFileMapHeader { unsigned int _magic; // identification of file type - int _crc; // header crc checksum + int _crc; // header crc checksum, start from _base_archive_name_offset int _version; // CURRENT_CDS_ARCHIVE_VERSION of the jdk that dumped the this archive unsigned int _header_size; // total size of the header, in bytes unsigned int _base_archive_name_offset; // offset where the base archive name is stored diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index 7783b00841d58d1a283501fd1208b0d1de8c0022..dfdd2219869aee6aa734ed461af59fa092f9d30d 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -150,6 +150,9 @@ JVM_ActiveProcessorCount(void); JNIEXPORT jboolean JNICALL JVM_IsUseContainerSupport(void); +JNIEXPORT void * JNICALL +JVM_LoadZipLibrary(); + JNIEXPORT void * JNICALL JVM_LoadLibrary(const char *name, jboolean throwException); @@ -759,6 +762,9 @@ JVM_SupportsCX8(void); JNIEXPORT void JNICALL JVM_ReportFinalizationComplete(JNIEnv *env, jobject finalizee); +JNIEXPORT jboolean JNICALL +JVM_IsFinalizationEnabled(JNIEnv *env); + /************************************************************************* PART 2: Support for the Verifier and Class File Format Checker ************************************************************************/ diff --git a/src/hotspot/share/interpreter/abstractInterpreter.cpp b/src/hotspot/share/interpreter/abstractInterpreter.cpp index 9e327c2d640101c4ffa35b54cb3b14f9388ed8a7..c39790f69f831b4b4f4dfc844b5546147ee8353f 100644 --- a/src/hotspot/share/interpreter/abstractInterpreter.cpp +++ b/src/hotspot/share/interpreter/abstractInterpreter.cpp @@ -134,6 +134,9 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(const methodHan case vmIntrinsics::_floatToRawIntBits: return java_lang_Float_floatToRawIntBits; case vmIntrinsics::_longBitsToDouble: return java_lang_Double_longBitsToDouble; case vmIntrinsics::_doubleToRawLongBits: return java_lang_Double_doubleToRawLongBits; +#ifdef AMD64 + case vmIntrinsics::_currentThread: return java_lang_Thread_currentThread; +#endif #endif // ZERO case vmIntrinsics::_dsin: return java_lang_math_sin; case vmIntrinsics::_dcos: return java_lang_math_cos; diff --git a/src/hotspot/share/interpreter/abstractInterpreter.hpp b/src/hotspot/share/interpreter/abstractInterpreter.hpp index 06d35ecd01b87ed58dcb00c9b9a8e0487582abf6..26b3fffd2b9cb71d7e3cdcec3213de1eda63b217 100644 --- a/src/hotspot/share/interpreter/abstractInterpreter.hpp +++ b/src/hotspot/share/interpreter/abstractInterpreter.hpp @@ -90,6 +90,7 @@ class AbstractInterpreter: AllStatic { java_lang_Float_floatToRawIntBits, // implementation of java.lang.Float.floatToRawIntBits() java_lang_Double_longBitsToDouble, // implementation of java.lang.Double.longBitsToDouble() java_lang_Double_doubleToRawLongBits, // implementation of java.lang.Double.doubleToRawLongBits() + java_lang_Thread_currentThread, // implementation of java.lang.Thread.currentThread() number_of_method_entries, invalid = -1 }; diff --git a/src/hotspot/share/interpreter/bytecodeHistogram.hpp b/src/hotspot/share/interpreter/bytecodeHistogram.hpp index b919227702f8e7ba5d5c74183fe02b13a47e5c9a..44ddca074d06bbd26470c0d0de78980fd4c136b1 100644 --- a/src/hotspot/share/interpreter/bytecodeHistogram.hpp +++ b/src/hotspot/share/interpreter/bytecodeHistogram.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_INTERPRETER_BYTECODEHISTOGRAM_HPP #include "interpreter/bytecodes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // BytecodeCounter counts the number of bytecodes executed diff --git a/src/hotspot/share/interpreter/bytecodeTracer.hpp b/src/hotspot/share/interpreter/bytecodeTracer.hpp index 52e91a0e7128837f754b3d113cc553f3c55c8bf5..38c2b092ce3faa3b8d6155509f1aacb6e12d43ee 100644 --- a/src/hotspot/share/interpreter/bytecodeTracer.hpp +++ b/src/hotspot/share/interpreter/bytecodeTracer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_INTERPRETER_BYTECODETRACER_HPP #define SHARE_INTERPRETER_BYTECODETRACER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/ostream.hpp" // The BytecodeTracer is a helper class used by the interpreter for run-time diff --git a/src/hotspot/share/interpreter/bytecodeUtils.cpp b/src/hotspot/share/interpreter/bytecodeUtils.cpp index 9473e87dec14b9822917e737e31166ab5d6c9c60..df5fbbe0e6b110d31042a77a212d20dad8769b41 100644 --- a/src/hotspot/share/interpreter/bytecodeUtils.cpp +++ b/src/hotspot/share/interpreter/bytecodeUtils.cpp @@ -1029,7 +1029,6 @@ int ExceptionMessageBuilder::do_instruction(int bci) { break; case Bytecodes::_arraylength: - // The return type of arraylength is wrong in the bytecodes table (T_VOID). stack->pop(1); stack->push(bci, T_INT); break; diff --git a/src/hotspot/share/interpreter/bytecodeUtils.hpp b/src/hotspot/share/interpreter/bytecodeUtils.hpp index ede99a995b7c92388e58939272a1d6a04ce52388..ff23b9c000f400f349bf79918144bf8d38488d19 100644 --- a/src/hotspot/share/interpreter/bytecodeUtils.hpp +++ b/src/hotspot/share/interpreter/bytecodeUtils.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2019 SAP SE. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #ifndef SHARE_INTERPRETER_BYTECODEUTILS_HPP #define SHARE_INTERPRETER_BYTECODEUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class Method; diff --git a/src/hotspot/share/interpreter/bytecodes.cpp b/src/hotspot/share/interpreter/bytecodes.cpp index 6711ba735db769e44260f03f08e27e88ac802cec..770934f31d8c7c9678d0dccaca64325e1727013f 100644 --- a/src/hotspot/share/interpreter/bytecodes.cpp +++ b/src/hotspot/share/interpreter/bytecodes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -471,7 +471,7 @@ void Bytecodes::initialize() { def(_new , "new" , "bkk" , NULL , T_OBJECT , 1, true ); def(_newarray , "newarray" , "bc" , NULL , T_OBJECT , 0, true ); def(_anewarray , "anewarray" , "bkk" , NULL , T_OBJECT , 0, true ); - def(_arraylength , "arraylength" , "b" , NULL , T_VOID , 0, true ); + def(_arraylength , "arraylength" , "b" , NULL , T_INT , 0, true ); def(_athrow , "athrow" , "b" , NULL , T_VOID , -1, true ); def(_checkcast , "checkcast" , "bkk" , NULL , T_OBJECT , 0, true ); def(_instanceof , "instanceof" , "bkk" , NULL , T_INT , 0, true ); diff --git a/src/hotspot/share/interpreter/bytecodes.hpp b/src/hotspot/share/interpreter/bytecodes.hpp index 9a34a227c0472abc3a35eb96d5ab12a323b9a2fc..7c70518d2b155be71846b480bdb6cca795afe8d3 100644 --- a/src/hotspot/share/interpreter/bytecodes.hpp +++ b/src/hotspot/share/interpreter/bytecodes.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ #ifndef SHARE_INTERPRETER_BYTECODES_HPP #define SHARE_INTERPRETER_BYTECODES_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" // Bytecodes specifies all bytecodes used in the VM and // provides utility functions to get bytecode attributes. diff --git a/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp b/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp index 8637da2e32d64500e5231df46ea01d3999c3ea7b..c318882dccaebb297b997c24f00e97a06e6dc8f0 100644 --- a/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp +++ b/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp @@ -201,7 +201,9 @@ void TemplateInterpreterGenerator::generate_all() { method_entry(java_lang_math_fmaF ) method_entry(java_lang_math_fmaD ) method_entry(java_lang_ref_reference_get) - +#ifdef AMD64 + method_entry(java_lang_Thread_currentThread) +#endif AbstractInterpreter::initialize_method_handle_entries(); // all native method kinds (must be one contiguous block) @@ -431,6 +433,11 @@ address TemplateInterpreterGenerator::generate_method_entry( : // fall thru case Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer : entry_point = generate_CRC32C_updateBytes_entry(kind); break; +#ifdef AMD64 + case Interpreter::java_lang_Thread_currentThread + : entry_point = generate_currentThread(); break; +#endif + #ifdef IA32 // On x86_32 platforms, a special entry is generated for the following four methods. // On other platforms the normal entry is used to enter these methods. diff --git a/src/hotspot/share/interpreter/templateInterpreterGenerator.hpp b/src/hotspot/share/interpreter/templateInterpreterGenerator.hpp index fcb50cfbe01a6754bc56b36b91059e566c97215c..a5cfb9bbad0fac86d9e34ab5520014c049509ae4 100644 --- a/src/hotspot/share/interpreter/templateInterpreterGenerator.hpp +++ b/src/hotspot/share/interpreter/templateInterpreterGenerator.hpp @@ -94,6 +94,9 @@ class TemplateInterpreterGenerator: public AbstractInterpreterGenerator { address generate_CRC32_update_entry(); address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind); address generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind); +#ifdef AMD64 + address generate_currentThread(); +#endif #ifdef IA32 address generate_Float_intBitsToFloat_entry(); address generate_Float_floatToRawIntBits_entry(); diff --git a/src/hotspot/share/interpreter/templateTable.hpp b/src/hotspot/share/interpreter/templateTable.hpp index ff5d2c338803de2011a2589b3d2539b8ad7d63e2..e7575eeb40a7f4dbea87955de8735730dfb8bd8f 100644 --- a/src/hotspot/share/interpreter/templateTable.hpp +++ b/src/hotspot/share/interpreter/templateTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_INTERPRETER_TEMPLATETABLE_HPP #include "interpreter/bytecodes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/frame.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp index a70b0092cba5e2741916aaee850c55e450aa5a81..4682c2b8129201e3ef2da800b3b369627c1bc170 100644 --- a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp +++ b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,6 +99,9 @@ #undef PREFETCH_OPCCODE #define PREFETCH_OPCCODE +JRT_ENTRY(void, at_safepoint(JavaThread* current)) {} +JRT_END + /* Interpreter safepoint: it is expected that the interpreter will have no live handles of its own creation live at an interpreter safepoint. Therefore we @@ -107,12 +110,10 @@ There really shouldn't be any handles remaining to trash but this is cheap in relation to a safepoint. */ -#define RETURN_SAFEPOINT \ - if (SafepointMechanism::should_process(THREAD)) { \ - HandleMarkCleaner __hmc(THREAD); \ - CALL_VM(SafepointMechanism::process_if_requested_with_exit_check(THREAD, true /* check asyncs */), \ - handle_exception); \ - } \ +#define RETURN_SAFEPOINT \ + if (SafepointMechanism::should_process(THREAD)) { \ + CALL_VM(at_safepoint(THREAD), handle_exception); \ + } /* * VM_JAVA_ERROR - Macro for throwing a java exception from @@ -1942,12 +1943,12 @@ run: Copy::fill_to_words(result + hdr_size, obj_size - hdr_size, 0); } - oop obj = cast_to_oop(result); + // Initialize header, mirrors MemAllocator. + oopDesc::set_mark(result, markWord::prototype()); + oopDesc::set_klass_gap(result, 0); + oopDesc::release_set_klass(result, ik); - // Initialize header - obj->set_mark(markWord::prototype()); - obj->set_klass_gap(0); - obj->set_klass(ik); + oop obj = cast_to_oop(result); // Must prevent reordering of stores for object initialization // with stores that publish the new object. diff --git a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp index 9763ed62b76cc3c3e06bc2890b6fc405b9a4c248..9b29553665716b08c51c884baee414a3f20532df 100644 --- a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp +++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp @@ -388,12 +388,12 @@ void JfrConfigureFlightRecorderDCmd::print_help(const char* name) const { out->print_cr(" been initalized. (STRING, default determined by the value for"); out->print_cr(" memorysize)"); out->print_cr(""); - out->print_cr(" maxchunksize (Optional) Maximum size of an individual data chunk in bytes if"); + out->print_cr(" maxchunksize (Optional) Maximum size of an individual data chunk in bytes if"); out->print_cr(" one of the following suffixes is not used: 'm' or 'M' for"); out->print_cr(" megabytes OR 'g' or 'G' for gigabytes. This value cannot be"); out->print_cr(" changed once JFR has been initialized. (STRING, 12M)"); out->print_cr(""); - out->print_cr(" memorysize (Optional) Overall memory size, in bytes if one of the following"); + out->print_cr(" memorysize (Optional) Overall memory size, in bytes if one of the following"); out->print_cr(" suffixes is not used: 'm' or 'M' for megabytes OR 'g' or 'G' for"); out->print_cr(" gigabytes. This value cannot be changed once JFR has been"); out->print_cr(" initialized. (STRING, 10M)"); @@ -403,7 +403,11 @@ void JfrConfigureFlightRecorderDCmd::print_help(const char* name) const { out->print_cr(" location is the temporary directory for the operating system. On"); out->print_cr(" Linux operating systems, the temporary directory is /tmp. On"); out->print_cr(" Windows, the temporary directory is specified by the TMP"); - out->print_cr(" environment variable.)"); + out->print_cr(" environment variable)"); + out->print_cr(""); + out->print_cr(" dumppath (Optional) Path to the location where a recording file is written"); + out->print_cr(" in case the VM runs into a critical error, such as a system"); + out->print_cr(" crash. (STRING, The default location is the current directory)"); out->print_cr(""); out->print_cr(" stackdepth (Optional) Stack depth for stack traces. Setting this value"); out->print_cr(" greater than the default of 64 may cause a performance"); @@ -416,8 +420,6 @@ void JfrConfigureFlightRecorderDCmd::print_help(const char* name) const { out->print_cr(" performance and is not recommended. This value cannot be changed"); out->print_cr(" once JFR has been initialized. (STRING, 8k)"); out->print_cr(""); - out->print_cr(" samplethreads (Optional) Flag for activating thread sampling. (BOOLEAN, true)"); - out->print_cr(""); out->print_cr("Options must be specified using the or = syntax."); out->print_cr(""); out->print_cr("Example usage:"); @@ -467,45 +469,47 @@ void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) { } jobject stack_depth = NULL; - if (_stack_depth.is_set()) { - stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK); - } - jobject global_buffer_count = NULL; - if (_global_buffer_count.is_set()) { - global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK); - } - jobject global_buffer_size = NULL; - if (_global_buffer_size.is_set()) { - global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value()._size, CHECK); - } - jobject thread_buffer_size = NULL; - if (_thread_buffer_size.is_set()) { - thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value()._size, CHECK); - } - jobject max_chunk_size = NULL; - if (_max_chunk_size.is_set()) { - max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value()._size, CHECK); - } - jobject memory_size = NULL; - if (_memory_size.is_set()) { - memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value()._size, CHECK); - } - jobject sample_threads = NULL; - if (_sample_threads.is_set()) { - sample_threads = JfrJavaSupport::new_java_lang_Boolean(_sample_threads.value(), CHECK); + if (!JfrRecorder::is_created()) { + if (_stack_depth.is_set()) { + stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK); + } + if (_global_buffer_count.is_set()) { + global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK); + } + if (_global_buffer_size.is_set()) { + global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value()._size, CHECK); + } + if (_thread_buffer_size.is_set()) { + thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value()._size, CHECK); + } + if (_max_chunk_size.is_set()) { + max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value()._size, CHECK); + } + if (_memory_size.is_set()) { + memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value()._size, CHECK); + } + if (_sample_threads.is_set()) { + bool startup = DCmd_Source_Internal == source; + if (startup) { + log_warning(jfr,startup)("%s", "Option samplethreads is deprecated. Use -XX:StartFlightRecording:method-profiling="); + } else { + output()->print_cr("%s", "Option samplethreads is deprecated. Use JFR.start method-profiling="); + output()->print_cr(""); + } + } } static const char klass[] = "jdk/jfr/internal/dcmd/DCmdConfigure"; static const char method[] = "execute"; static const char signature[] = "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;" "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;" - "Ljava/lang/Long;Ljava/lang/Boolean;)[Ljava/lang/String;"; + "Ljava/lang/Long;)[Ljava/lang/String;"; JfrJavaArguments execute_args(&result, klass, method, signature, CHECK); execute_args.set_receiver(h_dcmd_instance); @@ -520,7 +524,6 @@ void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) { execute_args.push_jobject(thread_buffer_size); execute_args.push_jobject(memory_size); execute_args.push_jobject(max_chunk_size); - execute_args.push_jobject(sample_threads); JfrJavaSupport::call_virtual(&execute_args, THREAD); handle_dcmd_result(output(), result.get_oop(), source, THREAD); diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.hpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.hpp index d34a4e57a78a0306726a54f35cf67f5a35087453..939c02bfdf4c113970d5b37293b01d1ec5dbd3e5 100644 --- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.hpp +++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_INSTRUMENTATION_JFREVENTCLASSTRANSFORMER_HPP #define SHARE_JFR_INSTRUMENTATION_JFREVENTCLASSTRANSFORMER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/exceptions.hpp" class ClassFileParser; diff --git a/src/hotspot/share/jfr/jfr.hpp b/src/hotspot/share/jfr/jfr.hpp index c97cc807c3b7c2b0719b29874f248f656cf4b356..b4b1ae78adc78cd15ff37d4e8144f96ec833828e 100644 --- a/src/hotspot/share/jfr/jfr.hpp +++ b/src/hotspot/share/jfr/jfr.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,13 @@ #define SHARE_JFR_JFR_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class JavaThread; class Thread; class Klass; +class outputStream; extern "C" void JNICALL jfr_register_natives(JNIEnv*, jclass); diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp index 54a4680ced84b0dbf67d8a4e8f67400f4ebed6ba..afbfaec6a96f5129d97e3037eca2b66ff76192d7 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ #include "jfr/recorder/repository/jfrRepository.hpp" #include "jfr/recorder/repository/jfrChunkRotation.hpp" #include "jfr/recorder/repository/jfrChunkWriter.hpp" +#include "jfr/recorder/repository/jfrEmergencyDump.hpp" #include "jfr/recorder/service/jfrEventThrottler.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp" @@ -120,10 +121,6 @@ NO_TRANSITION(void, jfr_set_file_notification(JNIEnv* env, jobject jvm, jlong th JfrChunkRotation::set_threshold(threshold); NO_TRANSITION_END -NO_TRANSITION(void, jfr_set_sample_threads(JNIEnv* env, jobject jvm, jboolean sampleThreads)) - JfrOptionSet::set_sample_threads(sampleThreads); -NO_TRANSITION_END - NO_TRANSITION(void, jfr_set_stack_depth(JNIEnv* env, jobject jvm, jint depth)) JfrOptionSet::set_stackdepth((jlong)depth); NO_TRANSITION_END @@ -315,6 +312,20 @@ JVM_ENTRY_NO_ENV(void, jfr_set_repository_location(JNIEnv* env, jobject repo, js return JfrRepository::set_path(location, thread); JVM_END +NO_TRANSITION(void, jfr_set_dump_path(JNIEnv* env, jobject jvm, jstring dumppath)) + if (dumppath == NULL) { + JfrEmergencyDump::set_dump_path(NULL); + } else { + const char* dump_path = env->GetStringUTFChars(dumppath, NULL); + JfrEmergencyDump::set_dump_path(dump_path); + env->ReleaseStringUTFChars(dumppath, dump_path); + } +NO_TRANSITION_END + +NO_TRANSITION(jstring, jfr_get_dump_path(JNIEnv* env, jobject jvm)) + return env->NewStringUTF(JfrEmergencyDump::get_dump_path()); +NO_TRANSITION_END + JVM_ENTRY_NO_ENV(void, jfr_uncaught_exception(JNIEnv* env, jobject jvm, jobject t, jthrowable throwable)) JfrJavaSupport::uncaught_exception(throwable, thread); JVM_END diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp index 19a676c4a22b91fd37f701c1a1803b9937cbe7d4..49286eed76f9d8951c52411ea71e39754efd834e 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,8 +87,6 @@ void JNICALL jfr_set_method_sampling_interval(JNIEnv* env, jobject jvm, jlong ty void JNICALL jfr_set_output(JNIEnv* env, jobject jvm, jstring path); -void JNICALL jfr_set_sample_threads(JNIEnv* env, jobject jvm, jboolean sampleThreads); - void JNICALL jfr_set_stack_depth(JNIEnv* env, jobject jvm, jint depth); void JNICALL jfr_set_stacktrace_enabled(JNIEnv* env, jobject jvm, jlong event_type_id, jboolean enabled); @@ -113,6 +111,10 @@ jlong JNICALL jfr_type_id(JNIEnv* env, jobject jvm, jclass jc); void JNICALL jfr_set_repository_location(JNIEnv* env, jobject repo, jstring location); +void JNICALL jfr_set_dump_path(JNIEnv* env, jobject jvm, jstring dumppath); + +jstring JNICALL jfr_get_dump_path(JNIEnv* env, jobject jvm); + jobject JNICALL jfr_get_event_writer(JNIEnv* env, jclass cls); jobject JNICALL jfr_new_event_writer(JNIEnv* env, jclass cls); diff --git a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp index db137776f654429bc06524da936acb0ad0cc6b5c..d71e2b4f25ac924d3568f974af00d4ad9a798c9c 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp @@ -59,7 +59,6 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) { (char*)"setGlobalBufferSize", (char*)"(J)V", (void*)jfr_set_global_buffer_size, (char*)"setMethodSamplingInterval", (char*)"(JJ)V", (void*)jfr_set_method_sampling_interval, (char*)"setOutput", (char*)"(Ljava/lang/String;)V", (void*)jfr_set_output, - (char*)"setSampleThreads", (char*)"(Z)V", (void*)jfr_set_sample_threads, (char*)"setStackDepth", (char*)"(I)V", (void*)jfr_set_stack_depth, (char*)"setStackTraceEnabled", (char*)"(JZ)V", (void*)jfr_set_stacktrace_enabled, (char*)"setThreadBufferSize", (char*)"(J)V", (void*)jfr_set_thread_buffer_size, @@ -75,6 +74,8 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) { (char*)"flush", (char*)"(Ljdk/jfr/internal/EventWriter;II)Z", (void*)jfr_event_writer_flush, (char*)"flush", (char*)"()V", (void*)jfr_flush, (char*)"setRepositoryLocation", (char*)"(Ljava/lang/String;)V", (void*)jfr_set_repository_location, + (char*)"setDumpPath", (char*)"(Ljava/lang/String;)V", (void*)jfr_set_dump_path, + (char*)"getDumpPath", (char*)"()Ljava/lang/String;", (void*)jfr_get_dump_path, (char*)"abort", (char*)"(Ljava/lang/String;)V", (void*)jfr_abort, (char*)"addStringConstant", (char*)"(JLjava/lang/String;)Z", (void*)jfr_add_string_constant, (char*)"uncaughtException", (char*)"(Ljava/lang/Thread;Ljava/lang/Throwable;)V", (void*)jfr_uncaught_exception, diff --git a/src/hotspot/share/jfr/jni/jfrUpcalls.cpp b/src/hotspot/share/jfr/jni/jfrUpcalls.cpp index e8b846d6021f25951b4288ba3f12e719fdc15d10..2040a34a6fae3eba707cbdfe0d9dde5cc19f7591 100644 --- a/src/hotspot/share/jfr/jni/jfrUpcalls.cpp +++ b/src/hotspot/share/jfr/jni/jfrUpcalls.cpp @@ -32,6 +32,7 @@ #include "jfr/support/jfrJdkJfrEvent.hpp" #include "logging/log.hpp" #include "memory/oopFactory.hpp" +#include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayKlass.hpp" #include "oops/typeArrayOop.inline.hpp" @@ -45,6 +46,8 @@ static Symbol* on_retransform_method_sym = NULL; static Symbol* on_retransform_signature_sym = NULL; static Symbol* bytes_for_eager_instrumentation_sym = NULL; static Symbol* bytes_for_eager_instrumentation_sig_sym = NULL; +static Symbol* unhide_internal_types_sym = NULL; +static Symbol* unhide_internal_types_sig_sym = NULL; static bool initialize(TRAPS) { static bool initialized = false; @@ -55,7 +58,9 @@ static bool initialize(TRAPS) { on_retransform_signature_sym = SymbolTable::new_permanent_symbol("(JZLjava/lang/Class;[B)[B"); bytes_for_eager_instrumentation_sym = SymbolTable::new_permanent_symbol("bytesForEagerInstrumentation"); bytes_for_eager_instrumentation_sig_sym = SymbolTable::new_permanent_symbol("(JZLjava/lang/Class;[B)[B"); - initialized = bytes_for_eager_instrumentation_sig_sym != NULL; + unhide_internal_types_sym = SymbolTable::new_permanent_symbol("unhideInternalTypes"); + unhide_internal_types_sig_sym = SymbolTable::new_permanent_symbol("()V"); + initialized = unhide_internal_types_sig_sym != NULL; } return initialized; } @@ -82,7 +87,8 @@ static const typeArrayOop invoke(jlong trace_id, args.push_oop(old_byte_array); JfrJavaSupport::call_static(&args, THREAD); if (HAS_PENDING_EXCEPTION) { - log_error(jfr, system)("JfrUpcall failed"); + ResourceMark rm(THREAD); + log_error(jfr, system)("JfrUpcall failed for %s", method_sym->as_C_string()); return NULL; } // The result should be a [B @@ -179,3 +185,19 @@ void JfrUpcalls::new_bytes_eager_instrumentation(jlong trace_id, *new_class_data_len = new_bytes_length; *new_class_data = new_bytes; } + +bool JfrUpcalls::unhide_internal_types(TRAPS) { + DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); + JavaValue result(T_VOID); + const Klass* klass = SystemDictionary::resolve_or_fail(jvm_upcalls_class_sym, true, CHECK_false); + assert(klass != NULL, "invariant"); + JfrJavaArguments args(&result, klass, unhide_internal_types_sym, unhide_internal_types_sig_sym); + JfrJavaSupport::call_static(&args, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + ResourceMark rm(THREAD); + log_error(jfr, system)("JfrUpcall failed for %s", unhide_internal_types_sym->as_C_string()); + return false; + } + return true; +} diff --git a/src/hotspot/share/jfr/jni/jfrUpcalls.hpp b/src/hotspot/share/jfr/jni/jfrUpcalls.hpp index 0bfe7074b4c4cdf7abf43d9d6f7a258dabaf2bd2..cefda39bf6b3b324877af713f7192089183a3b72 100644 --- a/src/hotspot/share/jfr/jni/jfrUpcalls.hpp +++ b/src/hotspot/share/jfr/jni/jfrUpcalls.hpp @@ -53,6 +53,8 @@ class JfrUpcalls : AllStatic { jint* new_class_data_len, unsigned char** new_class_data, TRAPS); + + static bool unhide_internal_types(TRAPS); }; #endif // SHARE_JFR_JNI_JFRUPCALLS_HPP diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp index c9a169e6edb53cc6f8d3567927595fabea62495d..0f107e7c32e2568806e5cc1be7a2f34916feebec 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_LEAKPROFILER_CHAINS_EDGEUTILS_HPP #define SHARE_JFR_LEAKPROFILER_CHAINS_EDGEUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Edge; class Symbol; diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp index 0ed82fd55c828ff949e8d76ac784e9a3b5a2452d..f9f928699e226e51ea9b6afff1a1ece6bc84a468 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_LEAKPROFILER_CHECKPOINT_OBJECTSAMPLECHECKPOINT_HPP #define SHARE_JFR_LEAKPROFILER_CHECKPOINT_OBJECTSAMPLECHECKPOINT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "jfr/utilities/jfrTypes.hpp" class EdgeStore; diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp index 63dca4afc72a1a0e52a3f0d989fac2dc04341080..279cb5032ff626e4ed1580be4e7c305940f39cfc 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "jfr/leakprofiler/utilities/rootType.hpp" #include "jfr/leakprofiler/utilities/unifiedOopRef.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" struct RootCallbackInfo { diff --git a/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp b/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp index c541ff1086db4c519e2ec3de694e5f43a5fcfec9..6290a10ff748b5401436c7c63dec60a6a128870a 100644 --- a/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp +++ b/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ #ifndef SHARE_JFR_LEAKPROFILER_LEAKPROFILER_HPP #define SHARE_JFR_LEAKPROFILER_LEAKPROFILER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class JavaThread; diff --git a/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.hpp b/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.hpp index 231c1b26df4764bd1fc5284a1a734f8088cbe36e..e42a815c10d21cd4f023c1e79e6a4f187c306089 100644 --- a/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.hpp +++ b/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_JFR_LEAKPROFILER_UTILITIES_GRANULARTIMER_HPP #include "jfr/utilities/jfrTime.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class GranularTimer : public AllStatic { private: diff --git a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp index ffc47c7b83391f80f953eeb9b3b20cc64cac3a33..ce975e9b802a34a0140cea166dad9e0ac10a5808 100644 --- a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp +++ b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_JFR_LEAKPROFILER_UTILITIES_ROOTTYPE_HPP #include "gc/shared/oopStorageSet.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/enumIterator.hpp" class OldObjectRoot : public AllStatic { diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 2cc8cc10bea4040dcf176c3234768f35e01237d4..0b17b5da71548b89858225189b7cd57262824d4e 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -26,6 +26,55 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -1034,11 +1083,6 @@ - - - - - diff --git a/src/hotspot/share/jfr/metadata/metadata.xsd b/src/hotspot/share/jfr/metadata/metadata.xsd index 017307e38473087562db1e2f327309adfa03d3f5..95aa2b94e8cc7d731686d23752f8c7f086239dbd 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xsd +++ b/src/hotspot/share/jfr/metadata/metadata.xsd @@ -1,4 +1,4 @@ - + " PTR_FORMAT, size, p2i(ptr)); - breakpoint(); - } - if (paranoid) { - verify_memory(ptr); - } -#endif + void* inner_ptr = MemTracker::record_malloc((address)outer_ptr, size, memflags, stack, level); + + DEBUG_ONLY(::memset(inner_ptr, uninitBlockPad, size);) + DEBUG_ONLY(break_if_ptr_caught(inner_ptr);) - // we do not track guard memory - return MemTracker::record_malloc((address)ptr, size, memflags, stack, level); + return inner_ptr; } void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) { @@ -716,95 +674,65 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) { void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) { -#if INCLUDE_NMT - { - void* rc = NULL; - if (NMTPreInit::handle_realloc(&rc, memblock, size)) { - return rc; - } + // Special handling for NMT preinit phase before arguments are parsed + void* rc = NULL; + if (NMTPreInit::handle_realloc(&rc, memblock, size)) { + return rc; } -#endif + + if (memblock == NULL) { + return os::malloc(size, memflags, stack); + } + + DEBUG_ONLY(check_crash_protection()); + + // On realloc(p, 0), implementators of realloc(3) have the choice to return either + // NULL or a unique non-NULL pointer. To unify libc behavior across our platforms + // we chose the latter. + size = MAX2((size_t)1, size); // For the test flag -XX:MallocMaxTestWords if (has_reached_max_malloc_test_peak(size)) { return NULL; } - if (size == 0) { - // return a valid pointer if size is zero - // if NULL is returned the calling functions assume out of memory. - size = 1; - } - -#ifndef ASSERT - NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); - NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); - // NMT support - NMT_TrackingLevel level = MemTracker::tracking_level(); - void* membase = MemTracker::record_free(memblock, level); + const NMT_TrackingLevel level = MemTracker::tracking_level(); const size_t nmt_overhead = MemTracker::malloc_header_size(level) + MemTracker::malloc_footer_size(level); - void* ptr = ::realloc(membase, size + nmt_overhead); - return MemTracker::record_malloc(ptr, size, memflags, stack, level); -#else - if (memblock == NULL) { - return os::malloc(size, memflags, stack); - } - if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { - log_warning(malloc, free)("os::realloc caught " PTR_FORMAT, p2i(memblock)); - breakpoint(); - } - // NMT support - void* membase = MemTracker::malloc_base(memblock); - verify_memory(membase); - // always move the block - void* ptr = os::malloc(size, memflags, stack); - // Copy to new memory if malloc didn't fail - if (ptr != NULL ) { - GuardedMemory guarded(MemTracker::malloc_base(memblock)); - // Guard's user data contains NMT header - NMT_TrackingLevel level = MemTracker::tracking_level(); - const size_t nmt_overhead = - MemTracker::malloc_header_size(level) + MemTracker::malloc_footer_size(level); - size_t memblock_size = guarded.get_user_size() - nmt_overhead; - memcpy(ptr, memblock, MIN2(size, memblock_size)); - if (paranoid) { - verify_memory(MemTracker::malloc_base(ptr)); - } - os::free(memblock); - } - return ptr; -#endif + + const size_t new_outer_size = size + nmt_overhead; + + // If NMT is enabled, this checks for heap overwrites, then de-accounts the old block. + void* const old_outer_ptr = MemTracker::record_free(memblock, level); + + void* const new_outer_ptr = ::realloc(old_outer_ptr, new_outer_size); + + // If NMT is enabled, this checks for heap overwrites, then de-accounts the old block. + void* const new_inner_ptr = MemTracker::record_malloc(new_outer_ptr, size, memflags, stack, level); + + DEBUG_ONLY(break_if_ptr_caught(new_inner_ptr);) + + return new_inner_ptr; } -// handles NULL pointers void os::free(void *memblock) { -#if INCLUDE_NMT + // Special handling for NMT preinit phase before arguments are parsed if (NMTPreInit::handle_free(memblock)) { return; } -#endif - NOT_PRODUCT(inc_stat_counter(&num_frees, 1)); -#ifdef ASSERT - if (memblock == NULL) return; - if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { - log_warning(malloc, free)("os::free caught " PTR_FORMAT, p2i(memblock)); - breakpoint(); + if (memblock == NULL) { + return; } - void* membase = MemTracker::record_free(memblock, MemTracker::tracking_level()); - verify_memory(membase); - GuardedMemory guarded(membase); - size_t size = guarded.get_user_size(); - inc_stat_counter(&free_bytes, size); - membase = guarded.release_for_freeing(); - ::free(membase); -#else - void* membase = MemTracker::record_free(memblock, MemTracker::tracking_level()); - ::free(membase); -#endif + DEBUG_ONLY(break_if_ptr_caught(memblock);) + + const NMT_TrackingLevel level = MemTracker::tracking_level(); + + // If NMT is enabled, this checks for heap overwrites, then de-accounts the old block. + void* const old_outer_ptr = MemTracker::record_free(memblock, level); + ::free(old_outer_ptr); } void os::init_random(unsigned int initval) { @@ -1359,10 +1287,6 @@ FILE* os::fopen(const char* path, const char* mode) { return file; } -ssize_t os::read(int fd, void *buf, unsigned int nBytes) { - return ::read(fd, buf, nBytes); -} - bool os::set_boot_path(char fileSep, char pathSep) { const char* home = Arguments::get_java_home(); int home_len = (int)strlen(home); @@ -1786,7 +1710,7 @@ void os::commit_memory_or_exit(char* addr, size_t size, size_t alignment_hint, bool os::uncommit_memory(char* addr, size_t bytes, bool executable) { bool res; - if (MemTracker::tracking_level() > NMT_minimal) { + if (MemTracker::enabled()) { Tracker tkr(Tracker::uncommit); res = pd_uncommit_memory(addr, bytes, executable); if (res) { @@ -1800,7 +1724,7 @@ bool os::uncommit_memory(char* addr, size_t bytes, bool executable) { bool os::release_memory(char* addr, size_t bytes) { bool res; - if (MemTracker::tracking_level() > NMT_minimal) { + if (MemTracker::enabled()) { // Note: Tracker contains a ThreadCritical. Tracker tkr(Tracker::release); res = pd_release_memory(addr, bytes); @@ -1869,7 +1793,7 @@ char* os::remap_memory(int fd, const char* file_name, size_t file_offset, bool os::unmap_memory(char *addr, size_t bytes) { bool result; - if (MemTracker::tracking_level() > NMT_minimal) { + if (MemTracker::enabled()) { Tracker tkr(Tracker::release); result = pd_unmap_memory(addr, bytes); if (result) { @@ -1905,7 +1829,7 @@ char* os::reserve_memory_special(size_t size, size_t alignment, size_t page_size bool os::release_memory_special(char* addr, size_t bytes) { bool res; - if (MemTracker::tracking_level() > NMT_minimal) { + if (MemTracker::enabled()) { // Note: Tracker contains a ThreadCritical. Tracker tkr(Tracker::release); res = pd_release_memory_special(addr, bytes); diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 45ed150ec7a80a67a651bba8c3c097ca3fac8f12..b63637e35767bf02653a58a65c94bca9398e76a9 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -541,9 +541,8 @@ class os: AllStatic { // File i/o operations static int open(const char *path, int oflag, int mode); - static FILE* open(int fd, const char* mode); + static FILE* fdopen(int fd, const char* mode); static FILE* fopen(const char* path, const char* mode); - static int close(int fd); static jlong lseek(int fd, jlong offset, int whence); static bool file_exists(const char* file); // This function, on Windows, canonicalizes a given path (see os_windows.cpp for details). @@ -563,9 +562,8 @@ class os: AllStatic { //File i/o operations - static ssize_t read(int fd, void *buf, unsigned int nBytes); static ssize_t read_at(int fd, void *buf, unsigned int nBytes, jlong offset); - static size_t write(int fd, const void *buf, unsigned int nBytes); + static ssize_t write(int fd, const void *buf, unsigned int nBytes); // Reading directories. static DIR* opendir(const char* dirname); @@ -784,15 +782,7 @@ class os: AllStatic { // Like strdup, but exit VM when strdup() returns NULL static char* strdup_check_oom(const char*, MEMFLAGS flags = mtInternal); -#ifndef PRODUCT - static julong num_mallocs; // # of calls to malloc/realloc - static julong alloc_bytes; // # of bytes allocated - static julong num_frees; // # of calls to free - static julong free_bytes; // # of bytes freed -#endif - // SocketInterface (ex HPI SocketInterface ) - static int socket(int domain, int type, int protocol); static int socket_close(int fd); static int recv(int fd, char* buf, size_t nBytes, uint flags); static int send(int fd, char* buf, size_t nBytes, uint flags); diff --git a/src/hotspot/share/runtime/osThread.cpp b/src/hotspot/share/runtime/osThread.cpp index dadb33fe014c3765bcc3122612bdd12d7d301d20..edaefaa1070d2f9806a2387cb54441cc6855ea5a 100644 --- a/src/hotspot/share/runtime/osThread.cpp +++ b/src/hotspot/share/runtime/osThread.cpp @@ -26,10 +26,8 @@ #include "oops/oop.inline.hpp" #include "runtime/osThread.hpp" -OSThread::OSThread(OSThreadStartFunc start_proc, void* start_parm) { +OSThread::OSThread() { pd_initialize(); - set_start_proc(start_proc); - set_start_parm(start_parm); } OSThread::~OSThread() { diff --git a/src/hotspot/share/runtime/osThread.hpp b/src/hotspot/share/runtime/osThread.hpp index 9c4c5e12735240df8a4f82493fdefb240c4bfd42..445ac097bf8f436324a964b4a557293674014c9a 100644 --- a/src/hotspot/share/runtime/osThread.hpp +++ b/src/hotspot/share/runtime/osThread.hpp @@ -61,8 +61,6 @@ class OSThread: public CHeapObj { friend class VMStructs; friend class JVMCIVMStructs; private: - OSThreadStartFunc _start_proc; // Thread start routine - void* _start_parm; // Thread start routine parameter volatile ThreadState _state; // Thread state *hint* // Methods @@ -70,18 +68,9 @@ class OSThread: public CHeapObj { void set_state(ThreadState state) { _state = state; } ThreadState get_state() { return _state; } - OSThread(OSThreadStartFunc start_proc, void* start_parm); + OSThread(); ~OSThread(); - // Accessors - OSThreadStartFunc start_proc() const { return _start_proc; } - void set_start_proc(OSThreadStartFunc start_proc) { _start_proc = start_proc; } - void* start_parm() const { return _start_parm; } - void set_start_parm(void* start_parm) { _start_parm = start_parm; } - // This is specialized on Windows. -#ifndef _WINDOWS - void set_interrupted(bool z) { /* nothing to do */ } -#endif // Printing void print_on(outputStream* st) const; void print() const; @@ -90,8 +79,6 @@ class OSThread: public CHeapObj { #include OS_HEADER(osThread) public: - static ByteSize thread_id_offset() { return byte_offset_of(OSThread, _thread_id); } - static size_t thread_id_size() { return sizeof(thread_id_t); } thread_id_t thread_id() const { return _thread_id; } diff --git a/src/hotspot/share/runtime/prefetch.hpp b/src/hotspot/share/runtime/prefetch.hpp index dac34f6cd26634a93b0ed6c19fb5e5a4cea546c3..d949899813c77ef7be07fb3c316c7e8a7f6d6a72 100644 --- a/src/hotspot/share/runtime/prefetch.hpp +++ b/src/hotspot/share/runtime/prefetch.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_PREFETCH_HPP #define SHARE_RUNTIME_PREFETCH_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // If calls to prefetch methods are in a loop, the loop should be cloned // such that if Prefetch{Scan,Copy}Interval and/or PrefetchFieldInterval diff --git a/src/hotspot/share/runtime/reflectionUtils.hpp b/src/hotspot/share/runtime/reflectionUtils.hpp index a928c50596e82ef298a2ea045f26cdf77b0ee0fc..ef9f8bbd62e7de5fd70fcf0e995d4010f8def361 100644 --- a/src/hotspot/share/runtime/reflectionUtils.hpp +++ b/src/hotspot/share/runtime/reflectionUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_REFLECTIONUTILS_HPP #define SHARE_RUNTIME_REFLECTIONUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/instanceKlass.hpp" #include "oops/objArrayOop.hpp" #include "oops/oopsHierarchy.hpp" diff --git a/src/hotspot/share/runtime/safepoint.cpp b/src/hotspot/share/runtime/safepoint.cpp index 064a9f64b75930e022e5f261a2d8d36acec0cd79..44240f85b71cc92bb20d9b26e9651c1e3313303d 100644 --- a/src/hotspot/share/runtime/safepoint.cpp +++ b/src/hotspot/share/runtime/safepoint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -754,6 +754,7 @@ void SafepointSynchronize::block(JavaThread *thread) { void SafepointSynchronize::handle_polling_page_exception(JavaThread *thread) { assert(thread->thread_state() == _thread_in_Java, "should come from Java code"); + thread->set_thread_state(_thread_in_vm); // Enable WXWrite: the function is called implicitly from java code. MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread)); @@ -765,6 +766,8 @@ void SafepointSynchronize::handle_polling_page_exception(JavaThread *thread) { ThreadSafepointState* state = thread->safepoint_state(); state->handle_polling_page_exception(); + + thread->set_thread_state(_thread_in_Java); } @@ -970,7 +973,6 @@ void ThreadSafepointState::handle_polling_page_exception() { // If we have a pending async exception deoptimize the frame // as otherwise we may never deliver it. if (self->has_async_exception_condition()) { - ThreadInVMfromJava __tiv(self, false /* check asyncs */); Deoptimization::deoptimize_frame(self, caller_fr.id()); } diff --git a/src/hotspot/share/runtime/safepoint.hpp b/src/hotspot/share/runtime/safepoint.hpp index 268a315dd7bf0adf7f65c0bb63e2fd45da838475..e67c960626ba3d9ace17807fa5b66b48544358ff 100644 --- a/src/hotspot/share/runtime/safepoint.hpp +++ b/src/hotspot/share/runtime/safepoint.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_SAFEPOINT_HPP #define SHARE_RUNTIME_SAFEPOINT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/os.hpp" #include "runtime/thread.hpp" #include "runtime/vmOperation.hpp" @@ -126,10 +126,6 @@ class SafepointSynchronize : AllStatic { JavaThread *thread, uint64_t safepoint_count); - static bool is_a_block_safe_state(JavaThreadState state) { - // Check that we have a valid thread_state before blocking for safepoints - return state == _thread_in_vm || state == _thread_in_Java; - } // Called when a thread voluntarily blocks static void block(JavaThread *thread); diff --git a/src/hotspot/share/runtime/safepointMechanism.cpp b/src/hotspot/share/runtime/safepointMechanism.cpp index b092f050539bc3cbd3d87d2eed8a7caaa49b4ac6..0a4d9a436c05871182d1686109ebfc90bdd7036e 100644 --- a/src/hotspot/share/runtime/safepointMechanism.cpp +++ b/src/hotspot/share/runtime/safepointMechanism.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,7 +119,7 @@ void SafepointMechanism::process(JavaThread *thread, bool allow_suspend) { bool need_rechecking; do { JavaThreadState state = thread->thread_state(); - guarantee(SafepointSynchronize::is_a_block_safe_state(state), "Illegal threadstate encountered: %d", state); + guarantee(state == _thread_in_vm, "Illegal threadstate encountered: %d", state); if (global_poll()) { // Any load in ::block() must not pass the global poll load. // Otherwise we might load an old safepoint counter (for example). diff --git a/src/hotspot/share/runtime/sharedRuntime.hpp b/src/hotspot/share/runtime/sharedRuntime.hpp index 1adc96619855c5c6a18bb794fdd78980e087254a..10e4b0ec0af8cad5796a8bfbca8f4576b642bde4 100644 --- a/src/hotspot/share/runtime/sharedRuntime.hpp +++ b/src/hotspot/share/runtime/sharedRuntime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #include "code/vmreg.hpp" #include "interpreter/bytecodeTracer.hpp" #include "interpreter/linkResolver.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/resourceArea.hpp" #include "utilities/hashtable.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/runtime/stackWatermark.hpp b/src/hotspot/share/runtime/stackWatermark.hpp index 3cf7ce59cd98e1c7c0f3c946859fda743c3bc732..6210a0bc2bf3a79491dcfb447e18fcdc52e1b47e 100644 --- a/src/hotspot/share/runtime/stackWatermark.hpp +++ b/src/hotspot/share/runtime/stackWatermark.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_STACKWATERMARK_HPP #define SHARE_RUNTIME_STACKWATERMARK_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/mutex.hpp" #include "runtime/stackWatermarkKind.hpp" diff --git a/src/hotspot/share/runtime/stubCodeGenerator.cpp b/src/hotspot/share/runtime/stubCodeGenerator.cpp index 68a82d78326fe69230094b1edb07192fb6196d83..fb546bc8ebee7fb7ac6ccfb57b8915fe3754c368 100644 --- a/src/hotspot/share/runtime/stubCodeGenerator.cpp +++ b/src/hotspot/share/runtime/stubCodeGenerator.cpp @@ -69,7 +69,7 @@ void StubCodeDesc::print() const { print_on(tty); } // Implementation of StubCodeGenerator StubCodeGenerator::StubCodeGenerator(CodeBuffer* code, bool print_code) { - _masm = new MacroAssembler(code ); + _masm = new MacroAssembler(code); _print_code = PrintStubCode || print_code; } diff --git a/src/hotspot/share/runtime/sweeper.cpp b/src/hotspot/share/runtime/sweeper.cpp index 31c9220ea784ee68eac6696ace2307703e38c39f..ec39455924725342529c15d4afe57b46a4a7def5 100644 --- a/src/hotspot/share/runtime/sweeper.cpp +++ b/src/hotspot/share/runtime/sweeper.cpp @@ -55,9 +55,9 @@ // Sweeper logging code class SweeperRecord { public: - int traversal; + int64_t traversal; int compile_id; - long traversal_mark; + int64_t traversal_mark; int state; const char* kind; address vep; @@ -65,8 +65,8 @@ class SweeperRecord { int line; void print() { - tty->print_cr("traversal = %d compile_id = %d %s uep = " PTR_FORMAT " vep = " - PTR_FORMAT " state = %d traversal_mark %ld line = %d", + tty->print_cr("traversal = " INT64_FORMAT " compile_id = %d %s uep = " PTR_FORMAT " vep = " + PTR_FORMAT " state = %d traversal_mark " INT64_FORMAT " line = %d", traversal, compile_id, kind == NULL ? "" : kind, @@ -107,8 +107,8 @@ void NMethodSweeper::init_sweeper_log() { #endif CompiledMethodIterator NMethodSweeper::_current(CompiledMethodIterator::all_blobs); // Current compiled method -long NMethodSweeper::_traversals = 0; // Stack scan count, also sweep ID. -long NMethodSweeper::_total_nof_code_cache_sweeps = 0; // Total number of full sweeps of the code cache +int64_t NMethodSweeper::_traversals = 0; // Stack scan count, also sweep ID. +int64_t NMethodSweeper::_total_nof_code_cache_sweeps = 0; // Total number of full sweeps of the code cache int NMethodSweeper::_seen = 0; // Nof. nmethod we have currently processed in current pass of CodeCache size_t NMethodSweeper::_sweep_threshold_bytes = 0; // Threshold for when to sweep. Updated after ergonomics @@ -119,8 +119,8 @@ volatile size_t NMethodSweeper::_bytes_changed = 0; // Counts the tot // 2) not_entrant -> zombie int NMethodSweeper::_hotness_counter_reset_val = 0; -long NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed -long NMethodSweeper::_total_nof_c2_methods_reclaimed = 0; // Accumulated nof methods flushed +int64_t NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed +int64_t NMethodSweeper::_total_nof_c2_methods_reclaimed = 0; // Accumulated nof methods flushed size_t NMethodSweeper::_total_flushed_size = 0; // Total number of bytes flushed from the code cache Tickspan NMethodSweeper::_total_time_sweeping; // Accumulated time sweeping Tickspan NMethodSweeper::_total_time_this_sweep; // Total time this sweep @@ -187,7 +187,7 @@ CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() { _total_time_this_sweep = Tickspan(); if (PrintMethodFlushing) { - tty->print_cr("### Sweep: stack traversal %ld", _traversals); + tty->print_cr("### Sweep: stack traversal " INT64_FORMAT, _traversals); } return &mark_activation_closure; } @@ -217,7 +217,7 @@ void NMethodSweeper::sweeper_loop() { { ThreadBlockInVM tbivm(JavaThread::current()); MonitorLocker waiter(CodeSweeper_lock, Mutex::_no_safepoint_check_flag); - const long wait_time = 60*60*24 * 1000; + const int64_t wait_time = 60*60*24 * 1000; timeout = waiter.wait(wait_time); } if (!timeout && (_should_sweep || _force_sweep)) { @@ -646,7 +646,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { CodeCache::log_state(&s); ttyLocker ttyl; - xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count()); + xtty->begin_elem("sweeper state='%s' traversals='" INT64_FORMAT "' ", msg, traversal_count()); if (format != NULL) { va_list ap; va_start(ap, format); @@ -664,8 +664,9 @@ void NMethodSweeper::print(outputStream* out) { out = (out == NULL) ? tty : out; out->print_cr("Code cache sweeper statistics:"); out->print_cr(" Total sweep time: %1.0lf ms", (double)_total_time_sweeping.value()/1000000); - out->print_cr(" Total number of full sweeps: %ld", _total_nof_code_cache_sweeps); - out->print_cr(" Total number of flushed methods: %ld (thereof %ld C2 methods)", _total_nof_methods_reclaimed, + out->print_cr(" Total number of full sweeps: " INT64_FORMAT, _total_nof_code_cache_sweeps); + out->print_cr(" Total number of flushed methods: " INT64_FORMAT " (thereof " INT64_FORMAT " C2 methods)", + _total_nof_methods_reclaimed, _total_nof_c2_methods_reclaimed); out->print_cr(" Total size of flushed methods: " SIZE_FORMAT " kB", _total_flushed_size/K); } diff --git a/src/hotspot/share/runtime/sweeper.hpp b/src/hotspot/share/runtime/sweeper.hpp index 9ba2298e9efbf7c030ea6ec10655ce15bd1f386f..ecf5a353cfd1cbde22c7c3bc1988c0f8c77fccde 100644 --- a/src/hotspot/share/runtime/sweeper.hpp +++ b/src/hotspot/share/runtime/sweeper.hpp @@ -66,8 +66,8 @@ class NMethodSweeper : public AllStatic { MadeZombie, Flushed }; - static long _traversals; // Stack scan count, also sweep ID. - static long _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache + static int64_t _traversals; // Stack scan count, also sweep ID. + static int64_t _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache static CompiledMethodIterator _current; // Current compiled method static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache static size_t _sweep_threshold_bytes; // The threshold for when to invoke sweeps @@ -78,8 +78,8 @@ class NMethodSweeper : public AllStatic { // 1) alive -> not_entrant // 2) not_entrant -> zombie // Stat counters - static long _total_nof_methods_reclaimed; // Accumulated nof methods flushed - static long _total_nof_c2_methods_reclaimed; // Accumulated nof C2-compiled methods flushed + static int64_t _total_nof_methods_reclaimed; // Accumulated nof methods flushed + static int64_t _total_nof_c2_methods_reclaimed; // Accumulated nof C2-compiled methods flushed static size_t _total_flushed_size; // Total size of flushed methods static int _hotness_counter_reset_val; @@ -97,10 +97,10 @@ class NMethodSweeper : public AllStatic { static void do_stack_scanning(); static void sweep(); public: - static long traversal_count() { return _traversals; } + static int64_t traversal_count() { return _traversals; } static size_t sweep_threshold_bytes() { return _sweep_threshold_bytes; } static void set_sweep_threshold_bytes(size_t threshold) { _sweep_threshold_bytes = threshold; } - static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } + static int64_t total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } static const Tickspan total_time_sweeping() { return _total_time_sweeping; } static const Tickspan peak_sweep_time() { return _peak_sweep_time; } static const Tickspan peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp index 87f2880650846f2be13084ba51809ee65e3d1699..d4234575fc0332b4e71fe54e48dc324d7cea42ab 100644 --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp @@ -57,6 +57,40 @@ #include "utilities/events.hpp" #include "utilities/preserveException.hpp" +class CleanupObjectMonitorsHashtable: StackObj { + public: + bool do_entry(void*& key, ObjectMonitorsHashtable::PtrList*& list) { + list->clear(); // clear the LinkListNodes + delete list; // then delete the LinkedList + return true; + } +}; + +ObjectMonitorsHashtable::~ObjectMonitorsHashtable() { + CleanupObjectMonitorsHashtable cleanup; + _ptrs->unlink(&cleanup); // cleanup the LinkedLists + delete _ptrs; // then delete the hash table +} + +void ObjectMonitorsHashtable::add_entry(void* key, ObjectMonitor* om) { + ObjectMonitorsHashtable::PtrList* list = get_entry(key); + if (list == nullptr) { + // Create new list and add it to the hash table: + list = new (ResourceObj::C_HEAP, mtThread) ObjectMonitorsHashtable::PtrList(); + add_entry(key, list); + } + list->add(om); // Add the ObjectMonitor to the list. + _om_count++; +} + +bool ObjectMonitorsHashtable::has_entry(void* key, ObjectMonitor* om) { + ObjectMonitorsHashtable::PtrList* list = get_entry(key); + if (list == nullptr || list->find(om) == nullptr) { + return false; + } + return true; +} + void MonitorList::add(ObjectMonitor* m) { ObjectMonitor* head; do { @@ -417,6 +451,14 @@ void ObjectSynchronizer::handle_sync_on_value_based_class(Handle obj, JavaThread } } +static bool useHeavyMonitors() { +#if defined(X86) || defined(AARCH64) || defined(PPC64) + return UseHeavyMonitors; +#else + return false; +#endif +} + // ----------------------------------------------------------------------------- // Monitor Enter/Exit // The interpreter and compiler assembly code tries to lock using the fast path @@ -428,28 +470,33 @@ void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, JavaThread* current) handle_sync_on_value_based_class(obj, current); } - markWord mark = obj->mark(); - if (mark.is_neutral()) { - // Anticipate successful CAS -- the ST of the displaced mark must - // be visible <= the ST performed by the CAS. - lock->set_displaced_header(mark); - if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) { + if (!useHeavyMonitors()) { + markWord mark = obj->mark(); + if (mark.is_neutral()) { + // Anticipate successful CAS -- the ST of the displaced mark must + // be visible <= the ST performed by the CAS. + lock->set_displaced_header(mark); + if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) { + return; + } + // Fall through to inflate() ... + } else if (mark.has_locker() && + current->is_lock_owned((address)mark.locker())) { + assert(lock != mark.locker(), "must not re-lock the same lock"); + assert(lock != (BasicLock*)obj->mark().value(), "don't relock with same BasicLock"); + lock->set_displaced_header(markWord::from_pointer(NULL)); return; } - // Fall through to inflate() ... - } else if (mark.has_locker() && - current->is_lock_owned((address)mark.locker())) { - assert(lock != mark.locker(), "must not re-lock the same lock"); - assert(lock != (BasicLock*)obj->mark().value(), "don't relock with same BasicLock"); - lock->set_displaced_header(markWord::from_pointer(NULL)); - return; + + // The object header will never be displaced to this lock, + // so it does not matter what the value is, except that it + // must be non-zero to avoid looking like a re-entrant lock, + // and must not look locked either. + lock->set_displaced_header(markWord::unused_mark()); + } else if (VerifyHeavyMonitors) { + guarantee(!obj->mark().has_locker(), "must not be stack-locked"); } - // The object header will never be displaced to this lock, - // so it does not matter what the value is, except that it - // must be non-zero to avoid looking like a re-entrant lock, - // and must not look locked either. - lock->set_displaced_header(markWord::unused_mark()); // An async deflation can race after the inflate() call and before // enter() can make the ObjectMonitor busy. enter() returns false if // we have lost the race to async deflation and we simply try again. @@ -462,45 +509,49 @@ void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, JavaThread* current) } void ObjectSynchronizer::exit(oop object, BasicLock* lock, JavaThread* current) { - markWord mark = object->mark(); + if (!useHeavyMonitors()) { + markWord mark = object->mark(); - markWord dhw = lock->displaced_header(); - if (dhw.value() == 0) { - // If the displaced header is NULL, then this exit matches up with - // a recursive enter. No real work to do here except for diagnostics. + markWord dhw = lock->displaced_header(); + if (dhw.value() == 0) { + // If the displaced header is NULL, then this exit matches up with + // a recursive enter. No real work to do here except for diagnostics. #ifndef PRODUCT - if (mark != markWord::INFLATING()) { - // Only do diagnostics if we are not racing an inflation. Simply - // exiting a recursive enter of a Java Monitor that is being - // inflated is safe; see the has_monitor() comment below. - assert(!mark.is_neutral(), "invariant"); - assert(!mark.has_locker() || - current->is_lock_owned((address)mark.locker()), "invariant"); - if (mark.has_monitor()) { - // The BasicLock's displaced_header is marked as a recursive - // enter and we have an inflated Java Monitor (ObjectMonitor). - // This is a special case where the Java Monitor was inflated - // after this thread entered the stack-lock recursively. When a - // Java Monitor is inflated, we cannot safely walk the Java - // Monitor owner's stack and update the BasicLocks because a - // Java Monitor can be asynchronously inflated by a thread that - // does not own the Java Monitor. - ObjectMonitor* m = mark.monitor(); - assert(m->object()->mark() == mark, "invariant"); - assert(m->is_entered(current), "invariant"); + if (mark != markWord::INFLATING()) { + // Only do diagnostics if we are not racing an inflation. Simply + // exiting a recursive enter of a Java Monitor that is being + // inflated is safe; see the has_monitor() comment below. + assert(!mark.is_neutral(), "invariant"); + assert(!mark.has_locker() || + current->is_lock_owned((address)mark.locker()), "invariant"); + if (mark.has_monitor()) { + // The BasicLock's displaced_header is marked as a recursive + // enter and we have an inflated Java Monitor (ObjectMonitor). + // This is a special case where the Java Monitor was inflated + // after this thread entered the stack-lock recursively. When a + // Java Monitor is inflated, we cannot safely walk the Java + // Monitor owner's stack and update the BasicLocks because a + // Java Monitor can be asynchronously inflated by a thread that + // does not own the Java Monitor. + ObjectMonitor* m = mark.monitor(); + assert(m->object()->mark() == mark, "invariant"); + assert(m->is_entered(current), "invariant"); + } } - } #endif - return; - } - - if (mark == markWord::from_pointer(lock)) { - // If the object is stack-locked by the current thread, try to - // swing the displaced header from the BasicLock back to the mark. - assert(dhw.is_neutral(), "invariant"); - if (object->cas_set_mark(dhw, mark) == mark) { return; } + + if (mark == markWord::from_pointer(lock)) { + // If the object is stack-locked by the current thread, try to + // swing the displaced header from the BasicLock back to the mark. + assert(dhw.is_neutral(), "invariant"); + if (object->cas_set_mark(dhw, mark) == mark) { + return; + } + } + } else if (VerifyHeavyMonitors) { + guarantee(!object->mark().has_locker(), "must not be stack-locked"); } // We have to take the slow-path of possible inflation and then exit. @@ -804,7 +855,10 @@ intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) { markWord temp, test; intptr_t hash; markWord mark = read_stable_mark(obj); - + if (VerifyHeavyMonitors) { + assert(UseHeavyMonitors, "+VerifyHeavyMonitors requires +UseHeavyMonitors"); + guarantee(!mark.has_locker(), "must not be stack locked"); + } if (mark.is_neutral()) { // if this is a normal header hash = mark.hash(); if (hash != 0) { // if it has a hash, just return it @@ -972,11 +1026,18 @@ JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_ob // Visitors ... +// Iterate ObjectMonitors where the owner == thread; this does NOT include +// ObjectMonitors where owner is set to a stack lock address in thread. +// +// This version of monitors_iterate() works with the in-use monitor list. +// void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure, JavaThread* thread) { MonitorList::Iterator iter = _in_use_list.iterator(); while (iter.has_next()) { ObjectMonitor* mid = iter.next(); if (mid->owner() != thread) { + // Not owned by the target thread and intentionally skips when owner + // is set to a stack lock address in the target thread. continue; } if (!mid->is_being_async_deflated() && mid->object_peek() != NULL) { @@ -993,6 +1054,31 @@ void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure, JavaThread* t } } +// This version of monitors_iterate() works with the specified linked list. +// +void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure, + ObjectMonitorsHashtable::PtrList* list, + JavaThread* thread) { + typedef LinkedListIterator ObjectMonitorIterator; + ObjectMonitorIterator iter(list->head()); + while (!iter.is_empty()) { + ObjectMonitor* mid = *iter.next(); + // Owner set to a stack lock address in thread should never be seen here: + assert(mid->owner() == thread, "must be"); + if (!mid->is_being_async_deflated() && mid->object_peek() != NULL) { + // Only process with closure if the object is set. + + // monitors_iterate() is only called at a safepoint or when the + // target thread is suspended or when the target thread is + // operating on itself. The current closures in use today are + // only interested in an owned ObjectMonitor and ownership + // cannot be dropped under the calling contexts so the + // ObjectMonitor cannot be async deflated. + closure->do_monitor(mid); + } + } +} + static bool monitors_used_above_threshold(MonitorList* list) { if (MonitorUsedDeflationThreshold == 0) { // disabled case is easy return false; @@ -1318,8 +1404,17 @@ void ObjectSynchronizer::chk_for_block_req(JavaThread* current, const char* op_n // Walk the in-use list and deflate (at most MonitorDeflationMax) idle // ObjectMonitors. Returns the number of deflated ObjectMonitors. +// +// If table != nullptr, we gather owned ObjectMonitors indexed by the +// owner in the table. Please note that ObjectMonitors where the owner +// is set to a stack lock address are NOT associated with the JavaThread +// that holds that stack lock. All of the current consumers of +// ObjectMonitorsHashtable info only care about JNI locked monitors and +// those do not have the owner set to a stack lock address. +// size_t ObjectSynchronizer::deflate_monitor_list(Thread* current, LogStream* ls, - elapsedTimer* timer_p) { + elapsedTimer* timer_p, + ObjectMonitorsHashtable* table) { MonitorList::Iterator iter = _in_use_list.iterator(); size_t deflated_count = 0; @@ -1330,6 +1425,18 @@ size_t ObjectSynchronizer::deflate_monitor_list(Thread* current, LogStream* ls, ObjectMonitor* mid = iter.next(); if (mid->deflate_monitor()) { deflated_count++; + } else if (table != nullptr) { + // The caller is interested in the owned ObjectMonitors. This does + // not include when owner is set to a stack lock address in thread. + // This also does not capture unowned ObjectMonitors that cannot be + // deflated because of a waiter. + void* key = mid->owner(); + // Since deflate_idle_monitors() and deflate_monitor_list() can be + // called more than once, we have to make sure the entry has not + // already been added. + if (key != nullptr && !table->has_entry(key, mid)) { + table->add_entry(key, mid); + } } if (current->is_Java_thread()) { @@ -1354,8 +1461,8 @@ class HandshakeForDeflation : public HandshakeClosure { // This function is called by the MonitorDeflationThread to deflate // ObjectMonitors. It is also called via do_final_audit_and_print_stats() -// by the VMThread. -size_t ObjectSynchronizer::deflate_idle_monitors() { +// and VM_ThreadDump::doit() by the VMThread. +size_t ObjectSynchronizer::deflate_idle_monitors(ObjectMonitorsHashtable* table) { Thread* current = Thread::current(); if (current->is_Java_thread()) { // The async deflation request has been processed. @@ -1380,7 +1487,7 @@ size_t ObjectSynchronizer::deflate_idle_monitors() { } // Deflate some idle ObjectMonitors. - size_t deflated_count = deflate_monitor_list(current, ls, &timer); + size_t deflated_count = deflate_monitor_list(current, ls, &timer, table); if (deflated_count > 0 || is_final_audit()) { // There are ObjectMonitors that have been deflated or this is the // final audit and all the remaining ObjectMonitors have been @@ -1438,6 +1545,10 @@ size_t ObjectSynchronizer::deflate_idle_monitors() { } ls->print_cr("end deflating: in_use_list stats: ceiling=" SIZE_FORMAT ", count=" SIZE_FORMAT ", max=" SIZE_FORMAT, in_use_list_ceiling(), _in_use_list.count(), _in_use_list.max()); + if (table != nullptr) { + ls->print_cr("ObjectMonitorsHashtable: key_count=" SIZE_FORMAT ", om_count=" SIZE_FORMAT, + table->key_count(), table->om_count()); + } } OM_PERFDATA_OP(MonExtant, set_value(_in_use_list.count())); @@ -1540,7 +1651,7 @@ void ObjectSynchronizer::do_final_audit_and_print_stats() { // Do a deflation in order to reduce the in-use monitor population // that is reported by ObjectSynchronizer::log_in_use_monitor_details() // which is called by ObjectSynchronizer::audit_and_print_stats(). - while (ObjectSynchronizer::deflate_idle_monitors() != 0) { + while (ObjectSynchronizer::deflate_idle_monitors(/* ObjectMonitorsHashtable is not needed here */ nullptr) >= (size_t)MonitorDeflationMax) { ; // empty } // The other audit_and_print_stats() call is done at the Debug diff --git a/src/hotspot/share/runtime/synchronizer.hpp b/src/hotspot/share/runtime/synchronizer.hpp index 5a331e306eeb01fce5fa582fd88bc1d50033267c..6fc47813f9916605dc3932a6cceb91eca96712e5 100644 --- a/src/hotspot/share/runtime/synchronizer.hpp +++ b/src/hotspot/share/runtime/synchronizer.hpp @@ -30,11 +30,69 @@ #include "runtime/basicLock.hpp" #include "runtime/handles.hpp" #include "utilities/growableArray.hpp" +#include "utilities/linkedlist.hpp" +#include "utilities/resourceHash.hpp" class LogStream; class ObjectMonitor; class ThreadsList; +// Hash table of void* to a list of ObjectMonitor* owned by the JavaThread. +// The JavaThread's owner key is either a JavaThread* or a stack lock +// address in the JavaThread so we use "void*". +// +class ObjectMonitorsHashtable { + private: + static unsigned int ptr_hash(void* const& s1) { + // 2654435761 = 2^32 * Phi (golden ratio) + return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u); + } + + public: + typedef LinkedListImpl PtrList; + + // ResourceHashtable SIZE is specified at compile time so we + // use 1031 which is the first prime after 1024. + typedef ResourceHashtable PtrTable; + private: + PtrTable* _ptrs; + size_t _key_count; + size_t _om_count; + + public: + // ResourceHashtable is passed to various functions and populated in + // different places so we allocate it using C_HEAP to make it immune + // from any ResourceMarks that happen to be in the code paths. + ObjectMonitorsHashtable() : _ptrs(new (ResourceObj::C_HEAP, mtThread) PtrTable()), _key_count(0), _om_count(0) {} + + ~ObjectMonitorsHashtable(); + + void add_entry(void* key, ObjectMonitor* om); + + void add_entry(void* key, PtrList* list) { + _ptrs->put(key, list); + _key_count++; + } + + PtrList* get_entry(void* key) { + PtrList** listpp = _ptrs->get(key); + return (listpp == nullptr) ? nullptr : *listpp; + } + + bool has_entry(void* key) { + PtrList** listpp = _ptrs->get(key); + return listpp != nullptr && *listpp != nullptr; + } + + bool has_entry(void* key, ObjectMonitor* om); + + size_t key_count() { return _key_count; } + size_t om_count() { return _om_count; } +}; + class MonitorList { friend class VMStructs; @@ -133,21 +191,30 @@ class ObjectSynchronizer : AllStatic { // JNI detach support static void release_monitors_owned_by_thread(JavaThread* current); + + // Iterate ObjectMonitors where the owner == thread; this does NOT include + // ObjectMonitors where owner is set to a stack lock address in thread: + // + // This version of monitors_iterate() works with the in-use monitor list. static void monitors_iterate(MonitorClosure* m, JavaThread* thread); + // This version of monitors_iterate() works with the specified linked list. + static void monitors_iterate(MonitorClosure* closure, + ObjectMonitorsHashtable::PtrList* list, + JavaThread* thread); // Initialize the gInflationLocks static void initialize(); - // GC: we current use aggressive monitor deflation policy + // GC: we currently use aggressive monitor deflation policy // Basically we try to deflate all monitors that are not busy. - static size_t deflate_idle_monitors(); + static size_t deflate_idle_monitors(ObjectMonitorsHashtable* table); // Deflate idle monitors: static void chk_for_block_req(JavaThread* current, const char* op_name, const char* cnt_name, size_t cnt, LogStream* ls, elapsedTimer* timer_p); - static size_t deflate_monitor_list(Thread* current, LogStream* ls, - elapsedTimer* timer_p); + static size_t deflate_monitor_list(Thread* current, LogStream* ls, elapsedTimer* timer_p, + ObjectMonitorsHashtable* table); static size_t in_use_list_ceiling(); static void dec_in_use_list_ceiling(); static void inc_in_use_list_ceiling(); diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp index b4a9b0c59a81f03cebc0197f97d078efb7e334a7..0ec50849f5a5f6936e964268cb2babd4ecd63e61 100644 --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -317,7 +317,6 @@ void Thread::record_stack_base_and_size() { } } -#if INCLUDE_NMT void Thread::register_thread_stack_with_NMT() { MemTracker::record_thread_stack(stack_end(), stack_size()); } @@ -325,7 +324,6 @@ void Thread::register_thread_stack_with_NMT() { void Thread::unregister_thread_stack_with_NMT() { MemTracker::release_thread_stack(stack_end(), stack_size()); } -#endif // INCLUDE_NMT void Thread::call_run() { DEBUG_ONLY(_run_state = CALL_RUN;) @@ -1111,7 +1109,7 @@ void JavaThread::interrupt() { debug_only(check_for_dangling_thread_pointer(this);) // For Windows _interrupt_event - osthread()->set_interrupted(true); + WINDOWS_ONLY(osthread()->set_interrupted(true);) // For Thread.sleep _SleepEvent->unpark(); @@ -1156,7 +1154,7 @@ bool JavaThread::is_interrupted(bool clear_interrupted) { if (interrupted && clear_interrupted) { assert(this == Thread::current(), "only the current thread can clear"); java_lang_Thread::set_interrupted(threadObj(), false); - osthread()->set_interrupted(false); + WINDOWS_ONLY(osthread()->set_interrupted(false);) } return interrupted; @@ -1646,24 +1644,10 @@ void JavaThread::check_and_handle_async_exceptions() { // We may be at method entry which requires we save the do-not-unlock flag. UnlockFlagSaver fs(this); - switch (thread_state()) { - case _thread_in_vm: { - JavaThread* THREAD = this; - Exceptions::throw_unsafe_access_internal_error(THREAD, __FILE__, __LINE__, "a fault occurred in an unsafe memory access operation"); - // We might have blocked in a ThreadBlockInVM wrapper in the call above so make sure we process pending - // suspend requests and object reallocation operations if any since we might be going to Java after this. - SafepointMechanism::process_if_requested_with_exit_check(this, true /* check asyncs */); - return; - } - case _thread_in_Java: { - ThreadInVMfromJava tiv(this); - JavaThread* THREAD = this; - Exceptions::throw_unsafe_access_internal_error(THREAD, __FILE__, __LINE__, "a fault occurred in an unsafe memory access operation in compiled Java code"); - return; - } - default: - ShouldNotReachHere(); - } + Exceptions::throw_unsafe_access_internal_error(this, __FILE__, __LINE__, "a fault occurred in an unsafe memory access operation"); + // We might have blocked in a ThreadBlockInVM wrapper in the call above so make sure we process pending + // suspend requests and object reallocation operations if any since we might be going to Java after this. + SafepointMechanism::process_if_requested_with_exit_check(this, true /* check asyncs */); } } @@ -1770,27 +1754,19 @@ bool JavaThread::java_resume() { } // Wait for another thread to perform object reallocation and relocking on behalf of -// this thread. -// Raw thread state transition to _thread_blocked and back again to the original -// state before returning are performed. The current thread is required to -// change to _thread_blocked in order to be seen to be safepoint/handshake safe -// whilst suspended and only after becoming handshake safe, the other thread can -// complete the handshake used to synchronize with this thread and then perform -// the reallocation and relocking. We cannot use the thread state transition -// helpers because we arrive here in various states and also because the helpers -// indirectly call this method. After leaving _thread_blocked we have to check -// for safepoint/handshake, except if _thread_in_native. The thread is safe -// without blocking then. Allowed states are enumerated in -// SafepointSynchronize::block(). See also EscapeBarrier::sync_and_suspend_*() +// this thread. The current thread is required to change to _thread_blocked in order +// to be seen to be safepoint/handshake safe whilst suspended and only after becoming +// handshake safe, the other thread can complete the handshake used to synchronize +// with this thread and then perform the reallocation and relocking. +// See EscapeBarrier::sync_and_suspend_*() void JavaThread::wait_for_object_deoptimization() { assert(!has_last_Java_frame() || frame_anchor()->walkable(), "should have walkable stack"); assert(this == Thread::current(), "invariant"); - JavaThreadState state = thread_state(); bool spin_wait = os::is_MP(); do { - set_thread_state(_thread_blocked); + ThreadBlockInVM tbivm(this, true /* allow_suspend */); // Wait for object deoptimization if requested. if (spin_wait) { // A single deoptimization is typically very short. Microbenchmarks @@ -1808,14 +1784,6 @@ void JavaThread::wait_for_object_deoptimization() { ml.wait(); } } - // The current thread could have been suspended again. We have to check for - // suspend after restoring the saved state. Without this the current thread - // might return to _thread_in_Java and execute bytecode. - set_thread_state_fence(state); - - if (state != _thread_in_native) { - SafepointMechanism::process_if_requested(this); - } // A handshake for obj. deoptimization suspend could have been processed so // we must check after processing. } while (is_obj_deopt_suspend()); @@ -2734,10 +2702,8 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; -#if INCLUDE_NMT // Initialize NMT right after argument parsing to keep the pre-NMT-init window small. MemTracker::initialize(); -#endif // INCLUDE_NMT os::init_before_ergo(); diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 74916b982759d81b8c2e0ad17320696cbf356262..9ceb17f7af16be01dc8796aef6c574fc8e3366af 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -550,8 +550,8 @@ protected: void set_stack_size(size_t size) { _stack_size = size; } address stack_end() const { return stack_base() - stack_size(); } void record_stack_base_and_size(); - void register_thread_stack_with_NMT() NOT_NMT_RETURN; - void unregister_thread_stack_with_NMT() NOT_NMT_RETURN; + void register_thread_stack_with_NMT(); + void unregister_thread_stack_with_NMT(); int lgrp_id() const { return _lgrp_id; } void set_lgrp_id(int value) { _lgrp_id = value; } @@ -1312,16 +1312,21 @@ class JavaThread: public Thread { // Returns the jni environment for this thread JNIEnv* jni_environment() { return &_jni_environment; } + // Returns the current thread as indicated by the given JNIEnv. + // We don't assert it is Thread::current here as that is done at the + // external JNI entry points where the JNIEnv is passed into the VM. static JavaThread* thread_from_jni_environment(JNIEnv* env) { - JavaThread *thread_from_jni_env = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset())); - // Only return NULL if thread is off the thread list; starting to - // exit should not return NULL. - if (thread_from_jni_env->is_terminated()) { - thread_from_jni_env->block_if_vm_exited(); - return NULL; - } else { - return thread_from_jni_env; + JavaThread* current = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset())); + // We can't get here in a thread that has completed its execution and so + // "is_terminated", but a thread is also considered terminated if the VM + // has exited, so we have to check this and block in case this is a daemon + // thread returning to the VM (the JNI DirectBuffer entry points rely on + // this). + if (current->is_terminated()) { + current->block_if_vm_exited(); + ShouldNotReachHere(); } + return current; } // JNI critical regions. These can nest. diff --git a/src/hotspot/share/runtime/threadLocalStorage.hpp b/src/hotspot/share/runtime/threadLocalStorage.hpp index 93607612a4dc38751e9e0130eadfd70076e3f919..604b624757e6f5dd3ca19742c4313ba157136a02 100644 --- a/src/hotspot/share/runtime/threadLocalStorage.hpp +++ b/src/hotspot/share/runtime/threadLocalStorage.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_THREADLOCALSTORAGE_HPP #define SHARE_RUNTIME_THREADLOCALSTORAGE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // forward-decl as we can't have an include cycle class Thread; diff --git a/src/hotspot/share/runtime/vframe.cpp b/src/hotspot/share/runtime/vframe.cpp index adf3c938d8d609d7571d39029011de3b25405dfe..14f4ee3a28c8c34ef976f23416a00e93179d8e21 100644 --- a/src/hotspot/share/runtime/vframe.cpp +++ b/src/hotspot/share/runtime/vframe.cpp @@ -608,13 +608,11 @@ javaVFrame* vframeStreamCommon::asJavaVFrame() { return result; } - #ifndef PRODUCT void vframe::print() { if (WizardMode) _fr.print_value_on(tty,NULL); } - void vframe::print_value() const { ((vframe*)this)->print(); } diff --git a/src/hotspot/share/runtime/vframeArray.cpp b/src/hotspot/share/runtime/vframeArray.cpp index 0d6417037c68ba64483275b30d45ee5f2f1e918d..2106ed7ef7c75a9e20ab9be308458c0aed1318c9 100644 --- a/src/hotspot/share/runtime/vframeArray.cpp +++ b/src/hotspot/share/runtime/vframeArray.cpp @@ -324,9 +324,11 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, } } +#ifndef PRODUCT if (PrintDeoptimizationDetails) { tty->print_cr("Expressions size: %d", expressions()->size()); } +#endif // !PRODUCT // Unpack expression stack // If this is an intermediate frame (i.e. not top frame) then this @@ -343,15 +345,15 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, *addr = value->get_int(); #ifndef PRODUCT if (PrintDeoptimizationDetails) { - tty->print_cr("Reconstructed expression %d (INT): %d", i, (int)(*addr)); + tty->print_cr(" - Reconstructed expression %d (INT): %d", i, (int)(*addr)); } -#endif +#endif // !PRODUCT break; case T_OBJECT: *addr = value->get_int(T_OBJECT); #ifndef PRODUCT if (PrintDeoptimizationDetails) { - tty->print("Reconstructed expression %d (OBJECT): ", i); + tty->print(" - Reconstructed expression %d (OBJECT): ", i); oop o = cast_to_oop((address)(*addr)); if (o == NULL) { tty->print_cr("NULL"); @@ -360,7 +362,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, tty->print_raw_cr(o->klass()->name()->as_C_string()); } } -#endif +#endif // !PRODUCT break; case T_CONFLICT: // A dead stack slot. Initialize to null in case it is an oop. @@ -371,6 +373,11 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, } } +#ifndef PRODUCT + if (PrintDeoptimizationDetails) { + tty->print_cr("Locals size: %d", locals()->size()); + } +#endif // !PRODUCT // Unpack the locals for(i = 0; i < locals()->size(); i++) { @@ -382,15 +389,15 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, *addr = value->get_int(); #ifndef PRODUCT if (PrintDeoptimizationDetails) { - tty->print_cr("Reconstructed local %d (INT): %d", i, (int)(*addr)); + tty->print_cr(" - Reconstructed local %d (INT): %d", i, (int)(*addr)); } -#endif +#endif // !PRODUCT break; case T_OBJECT: *addr = value->get_int(T_OBJECT); #ifndef PRODUCT if (PrintDeoptimizationDetails) { - tty->print("Reconstructed local %d (OBJECT): ", i); + tty->print(" - Reconstructed local %d (OBJECT): ", i); oop o = cast_to_oop((address)(*addr)); if (o == NULL) { tty->print_cr("NULL"); @@ -399,7 +406,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, tty->print_raw_cr(o->klass()->name()->as_C_string()); } } -#endif +#endif // !PRODUCT break; case T_CONFLICT: // A dead location. If it is an oop then we need a NULL to prevent GC from following it @@ -443,28 +450,15 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, #ifndef PRODUCT if (PrintDeoptimizationDetails) { ttyLocker ttyl; - tty->print_cr("[%d Interpreted Frame]", ++unpack_counter); + tty->print_cr("[%d. Interpreted Frame]", ++unpack_counter); iframe()->print_on(tty); RegisterMap map(thread); vframe* f = vframe::new_vframe(iframe(), &map, thread); f->print(); - - tty->print_cr("locals size %d", locals()->size()); - tty->print_cr("expression size %d", expressions()->size()); - - method()->print_value(); + if (WizardMode && Verbose) method()->print_codes(); tty->cr(); - // method()->print_codes(); - } else if (TraceDeoptimization) { - tty->print(" "); - method()->print_value(); - Bytecodes::Code code = Bytecodes::java_code_at(method(), bcp); - int bci = method()->bci_from(bcp); - tty->print(" - %s", Bytecodes::name(code)); - tty->print(" @ bci %d ", bci); - tty->print_cr("sp = " PTR_FORMAT, p2i(iframe()->sp())); } -#endif // PRODUCT +#endif // !PRODUCT // The expression stack and locals are in the resource area don't leave // a dangling pointer in the vframeArray we leave around for debug @@ -571,6 +565,7 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller // Find the skeletal interpreter frames to unpack into JavaThread* current = JavaThread::current(); + RegisterMap map(current, false); // Get the youngest frame we will unpack (last to be unpacked) frame me = unpack_frame.sender(&map); @@ -581,6 +576,18 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller me = me.sender(&map); } + Events::log_deopt_message(current, "DEOPT UNPACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT " mode %d", + p2i(unpack_frame.pc()), p2i(unpack_frame.sp()), exec_mode); + + if (TraceDeoptimization) { + ResourceMark rm; + stringStream st; + st.print_cr("DEOPT UNPACKING thread=" INTPTR_FORMAT " vframeArray=" INTPTR_FORMAT " mode=%d", + p2i(current), p2i(this), exec_mode); + st.print_cr(" Virtual frames (outermost/oldest first):"); + tty->print_raw(st.as_string()); + } + // Do the unpacking of interpreter frames; the frame at index 0 represents the top activation, so it has no callee // Unpack the frames from the oldest (frames() -1) to the youngest (0) frame* caller_frame = &me; @@ -600,6 +607,24 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller callee_parameters = callee->size_of_parameters() + (has_member_arg ? 1 : 0); callee_locals = callee->max_locals(); } + if (TraceDeoptimization) { + ResourceMark rm; + stringStream st; + st.print(" VFrame %d (" INTPTR_FORMAT ")", index, p2i(elem)); + st.print(" - %s", elem->method()->name_and_sig_as_C_string()); + int bci = elem->raw_bci(); + const char* code_name; + if (bci == SynchronizationEntryBCI) { + code_name = "sync entry"; + } else { + Bytecodes::Code code = elem->method()->code_at(bci); + code_name = Bytecodes::name(code); + } + st.print(" - %s", code_name); + st.print(" @ bci=%d ", bci); + st.print_cr("sp=" PTR_FORMAT, p2i(elem->iframe()->sp())); + tty->print_raw(st.as_string()); + } elem->unpack_on_stack(caller_actual_parameters, callee_parameters, callee_locals, @@ -614,6 +639,9 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller caller_actual_parameters = callee_parameters; } deallocate_monitor_chunks(); + if (TraceDeoptimization) { + tty->cr(); + } } void vframeArray::deallocate_monitor_chunks() { @@ -641,7 +669,7 @@ bool vframeArray::structural_compare(JavaThread* thread, GrowableArray= (size_t)MonitorDeflationMax) { + ; /* empty */ + } + } + if (_num_threads == 0) { // Snapshot all live threads @@ -293,7 +305,7 @@ void VM_ThreadDump::doit() { if (_with_locked_synchronizers) { tcl = concurrent_locks.thread_concurrent_locks(jt); } - snapshot_thread(jt, tcl); + snapshot_thread(jt, tcl, tablep); } } else { // Snapshot threads in the given _threads array @@ -328,14 +340,15 @@ void VM_ThreadDump::doit() { if (_with_locked_synchronizers) { tcl = concurrent_locks.thread_concurrent_locks(jt); } - snapshot_thread(jt, tcl); + snapshot_thread(jt, tcl, tablep); } } } -void VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) { +void VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl, + ObjectMonitorsHashtable* table) { ThreadSnapshot* snapshot = _result->add_thread_snapshot(java_thread); - snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors); + snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors, table); snapshot->set_concurrent_locks(tcl); } diff --git a/src/hotspot/share/runtime/vmOperations.hpp b/src/hotspot/share/runtime/vmOperations.hpp index fa80d859b09fdd38c065f444e0267b83aa96ce87..262ac740c1c0fbe683c7de0a89b14c3040492fee 100644 --- a/src/hotspot/share/runtime/vmOperations.hpp +++ b/src/hotspot/share/runtime/vmOperations.hpp @@ -32,54 +32,50 @@ // A hodge podge of commonly used VM Operations -class VM_None: public VM_Operation { - const char* _reason; - public: - VM_None(const char* reason) : _reason(reason) {} - const char* name() const { return _reason; } - VMOp_Type type() const { return VMOp_None; } - void doit() {}; +class VM_EmptyOperation : public VM_Operation { +public: + virtual void doit() final {} + virtual bool skip_thread_oop_barriers() const final { + // Neither the doit function nor the the safepoint + // cleanup tasks read oops in the Java threads. + return true; + } }; -class VM_Cleanup: public VM_Operation { +class VM_Halt: public VM_EmptyOperation { public: - VMOp_Type type() const { return VMOp_Cleanup; } - void doit() {}; + VMOp_Type type() const { return VMOp_Halt; } }; -class VM_ClearICs: public VM_Operation { - private: - bool _preserve_static_stubs; +class VM_SafepointALot: public VM_EmptyOperation { public: - VM_ClearICs(bool preserve_static_stubs) { _preserve_static_stubs = preserve_static_stubs; } - void doit(); - VMOp_Type type() const { return VMOp_ClearICs; } + VMOp_Type type() const { return VMOp_SafepointALot; } }; -// empty vm op, evaluated just to force a safepoint -class VM_ForceSafepoint: public VM_Operation { +class VM_Cleanup: public VM_EmptyOperation { public: - void doit() {} - VMOp_Type type() const { return VMOp_ForceSafepoint; } + VMOp_Type type() const { return VMOp_Cleanup; } }; -// empty vm op, when forcing a safepoint to suspend a thread -class VM_ThreadSuspend: public VM_ForceSafepoint { +// empty vm op, evaluated just to force a safepoint +class VM_ForceSafepoint: public VM_EmptyOperation { public: - VMOp_Type type() const { return VMOp_ThreadSuspend; } + VMOp_Type type() const { return VMOp_ForceSafepoint; } }; -// empty vm op, when forcing a safepoint to suspend threads from jvmti -class VM_ThreadsSuspendJVMTI: public VM_ForceSafepoint { +// empty vm op, when forcing a safepoint due to inline cache buffers being full +class VM_ICBufferFull: public VM_EmptyOperation { public: - VMOp_Type type() const { return VMOp_ThreadsSuspendJVMTI; } + VMOp_Type type() const { return VMOp_ICBufferFull; } }; -// empty vm op, when forcing a safepoint due to inline cache buffers being full -class VM_ICBufferFull: public VM_ForceSafepoint { +class VM_ClearICs: public VM_Operation { + private: + bool _preserve_static_stubs; public: - VMOp_Type type() const { return VMOp_ICBufferFull; } - virtual bool skip_thread_oop_barriers() const { return true; } + VM_ClearICs(bool preserve_static_stubs) { _preserve_static_stubs = preserve_static_stubs; } + void doit(); + VMOp_Type type() const { return VMOp_ClearICs; } }; // Base class for invoking parts of a gtest in a safepoint. @@ -207,7 +203,8 @@ class VM_ThreadDump : public VM_Operation { bool _with_locked_monitors; bool _with_locked_synchronizers; - void snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl); + void snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl, + ObjectMonitorsHashtable* table); public: VM_ThreadDump(ThreadDumpResult* result, diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 89abff4a0a8d530e1d9935daa89405f5509fa641..7fc64c943857583ad0dea25b6cc599e8014b9476 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -660,7 +660,7 @@ nonstatic_field(nmethod, _verified_entry_point, address) \ nonstatic_field(nmethod, _osr_entry_point, address) \ volatile_nonstatic_field(nmethod, _lock_count, jint) \ - volatile_nonstatic_field(nmethod, _stack_traversal_mark, long) \ + volatile_nonstatic_field(nmethod, _stack_traversal_mark, int64_t) \ nonstatic_field(nmethod, _compile_id, int) \ nonstatic_field(nmethod, _comp_level, int) \ \ @@ -1199,6 +1199,7 @@ declare_integer_type(ssize_t) \ declare_integer_type(intx) \ declare_integer_type(intptr_t) \ + declare_integer_type(int64_t) \ declare_unsigned_integer_type(uintx) \ declare_unsigned_integer_type(uintptr_t) \ declare_unsigned_integer_type(uint8_t) \ @@ -1767,6 +1768,7 @@ declare_c2_type(DivVFNode, VectorNode) \ declare_c2_type(DivVDNode, VectorNode) \ declare_c2_type(PopCountVINode, VectorNode) \ + declare_c2_type(PopCountVLNode, VectorNode) \ declare_c2_type(LShiftVBNode, VectorNode) \ declare_c2_type(LShiftVSNode, VectorNode) \ declare_c2_type(LShiftVINode, VectorNode) \ diff --git a/src/hotspot/share/runtime/vmThread.cpp b/src/hotspot/share/runtime/vmThread.cpp index 2e601a11f60d2c64d0e6505f678a488d925c4248..e22c33984868d386e2ef09d17682cffe751c0c51 100644 --- a/src/hotspot/share/runtime/vmThread.cpp +++ b/src/hotspot/share/runtime/vmThread.cpp @@ -96,8 +96,8 @@ void VMOperationTimeoutTask::disarm() { //------------------------------------------------------------------------------------------------------------------ // Implementation of VMThread stuff -static VM_None safepointALot_op("SafepointALot"); -static VM_Cleanup cleanup_op; +static VM_SafepointALot safepointALot_op; +static VM_Cleanup cleanup_op; bool VMThread::_should_terminate = false; bool VMThread::_terminated = false; @@ -147,7 +147,7 @@ void VMThread::destroy() { _vm_thread = NULL; // VM thread is gone } -static VM_None halt_op("Halt"); +static VM_Halt halt_op; void VMThread::run() { assert(this == vm_thread(), "check"); diff --git a/src/hotspot/share/runtime/vmThread.hpp b/src/hotspot/share/runtime/vmThread.hpp index 23384c61257b6afbd3d8a6127a0976aab245452d..0d7d58e258799acefdd70bfa372bdc0ef26e5d27 100644 --- a/src/hotspot/share/runtime/vmThread.hpp +++ b/src/hotspot/share/runtime/vmThread.hpp @@ -53,8 +53,7 @@ public: }; // -// A single VMThread (the primordial thread) spawns all other threads -// and is itself used by other threads to offload heavy vm operations +// A single VMThread is used by other threads to offload heavy vm operations // like scavenge, garbage_collect etc. // @@ -78,7 +77,6 @@ class VMThread: public NamedThread { void inner_execute(VM_Operation* op); void wait_for_operation(); - public: // Constructor VMThread(); @@ -87,14 +85,15 @@ class VMThread: public NamedThread { guarantee(false, "VMThread deletion must fix the race with VM termination"); } + // The ever running loop for the VMThread + void loop(); + + public: bool is_running() const { return Atomic::load(&_is_running); } // Tester bool is_VM_thread() const { return true; } - // The ever running loop for the VMThread - void loop(); - // Called to stop the VM thread static void wait_for_vm_thread_exit(); static bool should_terminate() { return _should_terminate; } diff --git a/src/hotspot/share/services/attachListener.cpp b/src/hotspot/share/services/attachListener.cpp index 957b34112d590a63cae988769a36f2ef31a07af4..f916f43849ffb567eafbfe0fcdf581dd898b7216 100644 --- a/src/hotspot/share/services/attachListener.cpp +++ b/src/hotspot/share/services/attachListener.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -292,6 +292,7 @@ static jint heap_inspection(AttachOperation* op, outputStream* out) { uintx num; if (!Arguments::parse_uintx(num_str, &num, 0)) { out->print_cr("Invalid parallel thread number: [%s]", num_str); + delete fs; return JNI_ERR; } parallel_thread_num = num == 0 ? parallel_thread_num : (uint)num; diff --git a/src/hotspot/share/services/attachListener.hpp b/src/hotspot/share/services/attachListener.hpp index 25fad127d0f71f19aff92d064ab5b806c4b78c7a..5765240c16c36c95a01719f544c143b6ae269c30 100644 --- a/src/hotspot/share/services/attachListener.hpp +++ b/src/hotspot/share/services/attachListener.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_SERVICES_ATTACHLISTENER_HPP #define SHARE_SERVICES_ATTACHLISTENER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/services/diagnosticArgument.cpp b/src/hotspot/share/services/diagnosticArgument.cpp index f10fe6c4641560b0cc7f9ec8b1da0022b61b88e3..3dd75009175e86a0c2422de3b67704cdea212926 100644 --- a/src/hotspot/share/services/diagnosticArgument.cpp +++ b/src/hotspot/share/services/diagnosticArgument.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ #include "memory/resourceArea.hpp" #include "runtime/thread.hpp" #include "services/diagnosticArgument.hpp" +#include "utilities/globalDefinitions.hpp" StringArrayArgument::StringArrayArgument() { _array = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray(32, mtServiceability); @@ -114,13 +115,12 @@ template <> void DCmdArgument::parse_value(const char* str, || sscanf(str, JLONG_FORMAT "%n", &_value, &scanned) != 1 || (size_t)scanned != len) { - ResourceMark rm; - - char* buf = NEW_RESOURCE_ARRAY(char, len + 1); - strncpy(buf, str, len); - buf[len] = '\0'; + const int maxprint = 64; Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(), - "Integer parsing error in command argument '%s'. Could not parse: %s.\n", _name, buf); + "Integer parsing error in command argument '%s'. Could not parse: %.*s%s.\n", _name, + MIN2((int)len, maxprint), + (str == NULL ? "" : str), + (len > maxprint ? "..." : "")); } } diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index 1b3710cf004c2a47d8b17e9c8f171781745b1f18..06b9539a94d7dc2533d8fac8ca67ec3cefd04a1e 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -36,6 +36,7 @@ #include "memory/metaspace/metaspaceDCmd.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" +#include "oops/instanceKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayOop.inline.hpp" @@ -419,6 +420,11 @@ void HeapInfoDCmd::execute(DCmdSource source, TRAPS) { void FinalizerInfoDCmd::execute(DCmdSource source, TRAPS) { ResourceMark rm(THREAD); + if (!InstanceKlass::is_finalization_enabled()) { + output()->print_cr("Finalization is disabled"); + return; + } + Klass* k = SystemDictionary::resolve_or_fail( vmSymbols::finalizer_histogram_klass(), true, CHECK); @@ -906,8 +912,9 @@ void CompilerDirectivesClearDCmd::execute(DCmdSource source, TRAPS) { ClassHierarchyDCmd::ClassHierarchyDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), _print_interfaces("-i", "Inherited interfaces should be printed.", "BOOLEAN", false, "false"), - _print_subclasses("-s", "If a classname is specified, print its subclasses. " - "Otherwise only its superclasses are printed.", "BOOLEAN", false, "false"), + _print_subclasses("-s", "If a classname is specified, print its subclasses " + "in addition to its superclasses. Without this option only the " + "superclasses will be printed.", "BOOLEAN", false, "false"), _classname("classname", "Name of class whose hierarchy should be printed. " "If not specified, all class hierarchies are printed.", "STRING", false) { diff --git a/src/hotspot/share/services/gcNotifier.hpp b/src/hotspot/share/services/gcNotifier.hpp index a13b85e0e69b0deaad5aec15aee8cb368da7b2ec..1a4582025c42949bd2947e08dd32719ea785e015 100644 --- a/src/hotspot/share/services/gcNotifier.hpp +++ b/src/hotspot/share/services/gcNotifier.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_SERVICES_GCNOTIFIER_HPP #define SHARE_SERVICES_GCNOTIFIER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "services/memoryPool.hpp" #include "services/memoryService.hpp" #include "services/memoryManager.hpp" diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp index b14e1223943f671cc6fd8ff823df53fa391224b5..8f83e129b94e789e090ee999e44961978a3d8376 100644 --- a/src/hotspot/share/services/heapDumper.cpp +++ b/src/hotspot/share/services/heapDumper.cpp @@ -2388,7 +2388,7 @@ void VM_HeapDumper::dump_stack_traces() { HandleMark hm(current_thread); ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false); - stack_trace->dump_stack_at_safepoint(-1); + stack_trace->dump_stack_at_safepoint(-1, /* ObjectMonitorsHashtable is not needed here */ nullptr); _stack_traces[_num_threads++] = stack_trace; // write HPROF_FRAME records for this thread's stack trace diff --git a/src/hotspot/share/services/heapDumperCompression.cpp b/src/hotspot/share/services/heapDumperCompression.cpp index 0d6426017974012c0918d745672dcb3403c1c704..0c9958077d225f47cb8f26dd21cf0021ce38fd8c 100644 --- a/src/hotspot/share/services/heapDumperCompression.cpp +++ b/src/hotspot/share/services/heapDumperCompression.cpp @@ -1,4 +1,5 @@ /* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -45,7 +46,7 @@ char const* FileWriter::open_writer() { FileWriter::~FileWriter() { if (_fd >= 0) { - os::close(_fd); + ::close(_fd); _fd = -1; } } @@ -54,7 +55,7 @@ char const* FileWriter::write_buf(char* buf, ssize_t size) { assert(_fd >= 0, "Must be open"); assert(size > 0, "Must write at least one byte"); - ssize_t n = (ssize_t) os::write(_fd, buf, (uint) size); + ssize_t n = os::write(_fd, buf, (uint) size); if (n <= 0) { return os::strerror(errno); diff --git a/src/hotspot/share/services/lowMemoryDetector.hpp b/src/hotspot/share/services/lowMemoryDetector.hpp index 09bb1ce640681cbf4a5f10a4c69c4ce81d5b861f..3070eb00ab7af8db4a41dce792078dcc6b79ff89 100644 --- a/src/hotspot/share/services/lowMemoryDetector.hpp +++ b/src/hotspot/share/services/lowMemoryDetector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_SERVICES_LOWMEMORYDETECTOR_HPP #define SHARE_SERVICES_LOWMEMORYDETECTOR_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopHandle.hpp" #include "runtime/atomic.hpp" #include "services/memoryPool.hpp" diff --git a/src/hotspot/share/services/mallocSiteTable.cpp b/src/hotspot/share/services/mallocSiteTable.cpp index dae1357cef12c60b244438f2850c153bba6f45d3..2670c138daa159ebacc4d3fd63963507b48dbad6 100644 --- a/src/hotspot/share/services/mallocSiteTable.cpp +++ b/src/hotspot/share/services/mallocSiteTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,12 +33,6 @@ MallocSiteHashtableEntry* MallocSiteTable::_table[MallocSiteTable::table_size]; const NativeCallStack* MallocSiteTable::_hash_entry_allocation_stack = NULL; const MallocSiteHashtableEntry* MallocSiteTable::_hash_entry_allocation_site = NULL; -// concurrent access counter -volatile int MallocSiteTable::_access_count = 0; - -// Tracking hashtable contention -NOT_PRODUCT(int MallocSiteTable::_peak_count = 0;) - /* * Initialize malloc site table. * Hashtable entry is malloc'd, so it can cause infinite recursion. @@ -202,122 +196,81 @@ void MallocSiteTable::delete_linked_list(MallocSiteHashtableEntry* head) { } } -void MallocSiteTable::shutdown() { - AccessLock locker(&_access_count); - locker.exclusiveLock(); - reset(); -} - bool MallocSiteTable::walk_malloc_site(MallocSiteWalker* walker) { assert(walker != NULL, "NuLL walker"); - AccessLock locker(&_access_count); - if (locker.sharedLock()) { - NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);) - return walk(walker); - } - return false; -} - - -void MallocSiteTable::AccessLock::exclusiveLock() { - int target; - int val; - - assert(_lock_state != ExclusiveLock, "Can only call once"); - assert(*_lock >= 0, "Can not content exclusive lock"); - - // make counter negative to block out shared locks - do { - val = *_lock; - target = _MAGIC_ + *_lock; - } while (Atomic::cmpxchg(_lock, val, target) != val); - - // wait for all readers to exit - while (*_lock != _MAGIC_) { -#ifdef _WINDOWS - os::naked_short_sleep(1); -#else - os::naked_yield(); -#endif - } - _lock_state = ExclusiveLock; + return walk(walker); } void MallocSiteTable::print_tuning_statistics(outputStream* st) { - - AccessLock locker(&_access_count); - if (locker.sharedLock()) { - // Total number of allocation sites, include empty sites - int total_entries = 0; - // Number of allocation sites that have all memory freed - int empty_entries = 0; - // Number of captured call stack distribution - int stack_depth_distribution[NMT_TrackingStackDepth + 1] = { 0 }; - // Chain lengths - int lengths[table_size] = { 0 }; - - for (int i = 0; i < table_size; i ++) { - int this_chain_length = 0; - const MallocSiteHashtableEntry* head = _table[i]; - while (head != NULL) { - total_entries ++; - this_chain_length ++; - if (head->size() == 0) { - empty_entries ++; - } - const int callstack_depth = head->peek()->call_stack()->frames(); - assert(callstack_depth >= 0 && callstack_depth <= NMT_TrackingStackDepth, - "Sanity (%d)", callstack_depth); - stack_depth_distribution[callstack_depth] ++; - head = head->next(); - } - lengths[i] = this_chain_length; - } - - st->print_cr("Malloc allocation site table:"); - st->print_cr("\tTotal entries: %d", total_entries); - st->print_cr("\tEmpty entries: %d (%2.2f%%)", empty_entries, ((float)empty_entries * 100) / total_entries); - st->cr(); - - // We report the hash distribution (chain length distribution) of the n shortest chains - // - under the assumption that this usually contains all lengths. Reporting threshold - // is 20, and the expected avg chain length is 5..6 (see table size). - static const int chain_length_threshold = 20; - int chain_length_distribution[chain_length_threshold] = { 0 }; - int over_threshold = 0; - int longest_chain_length = 0; - for (int i = 0; i < table_size; i ++) { - if (lengths[i] >= chain_length_threshold) { - over_threshold ++; - } else { - chain_length_distribution[lengths[i]] ++; + // Total number of allocation sites, include empty sites + int total_entries = 0; + // Number of allocation sites that have all memory freed + int empty_entries = 0; + // Number of captured call stack distribution + int stack_depth_distribution[NMT_TrackingStackDepth + 1] = { 0 }; + // Chain lengths + int lengths[table_size] = { 0 }; + + for (int i = 0; i < table_size; i ++) { + int this_chain_length = 0; + const MallocSiteHashtableEntry* head = _table[i]; + while (head != NULL) { + total_entries ++; + this_chain_length ++; + if (head->size() == 0) { + empty_entries ++; } - longest_chain_length = MAX2(longest_chain_length, lengths[i]); + const int callstack_depth = head->peek()->call_stack()->frames(); + assert(callstack_depth >= 0 && callstack_depth <= NMT_TrackingStackDepth, + "Sanity (%d)", callstack_depth); + stack_depth_distribution[callstack_depth] ++; + head = head->next(); } + lengths[i] = this_chain_length; + } - st->print_cr("Hash distribution:"); - if (chain_length_distribution[0] == 0) { - st->print_cr("no empty buckets."); + st->print_cr("Malloc allocation site table:"); + st->print_cr("\tTotal entries: %d", total_entries); + st->print_cr("\tEmpty entries: %d (%2.2f%%)", empty_entries, ((float)empty_entries * 100) / total_entries); + st->cr(); + + // We report the hash distribution (chain length distribution) of the n shortest chains + // - under the assumption that this usually contains all lengths. Reporting threshold + // is 20, and the expected avg chain length is 5..6 (see table size). + static const int chain_length_threshold = 20; + int chain_length_distribution[chain_length_threshold] = { 0 }; + int over_threshold = 0; + int longest_chain_length = 0; + for (int i = 0; i < table_size; i ++) { + if (lengths[i] >= chain_length_threshold) { + over_threshold ++; } else { - st->print_cr("%d buckets are empty.", chain_length_distribution[0]); - } - for (int len = 1; len < MIN2(longest_chain_length + 1, chain_length_threshold); len ++) { - st->print_cr("%2d %s: %d.", len, (len == 1 ? " entry" : "entries"), chain_length_distribution[len]); + chain_length_distribution[lengths[i]] ++; } - if (longest_chain_length >= chain_length_threshold) { - st->print_cr(">=%2d entries: %d.", chain_length_threshold, over_threshold); - } - st->print_cr("most entries: %d.", longest_chain_length); - st->cr(); + longest_chain_length = MAX2(longest_chain_length, lengths[i]); + } - st->print_cr("Call stack depth distribution:"); - for (int i = 0; i <= NMT_TrackingStackDepth; i ++) { - st->print_cr("\t%d: %d", i, stack_depth_distribution[i]); - } - st->cr(); - } // lock -} + st->print_cr("Hash distribution:"); + if (chain_length_distribution[0] == 0) { + st->print_cr("no empty buckets."); + } else { + st->print_cr("%d buckets are empty.", chain_length_distribution[0]); + } + for (int len = 1; len < MIN2(longest_chain_length + 1, chain_length_threshold); len ++) { + st->print_cr("%2d %s: %d.", len, (len == 1 ? " entry" : "entries"), chain_length_distribution[len]); + } + if (longest_chain_length >= chain_length_threshold) { + st->print_cr(">=%2d entries: %d.", chain_length_threshold, over_threshold); + } + st->print_cr("most entries: %d.", longest_chain_length); + st->cr(); + st->print_cr("Call stack depth distribution:"); + for (int i = 0; i <= NMT_TrackingStackDepth; i ++) { + st->print_cr("\t%d: %d", i, stack_depth_distribution[i]); + } + st->cr(); +} bool MallocSiteHashtableEntry::atomic_insert(MallocSiteHashtableEntry* entry) { return Atomic::replace_if_null(&_next, entry); diff --git a/src/hotspot/share/services/mallocSiteTable.hpp b/src/hotspot/share/services/mallocSiteTable.hpp index 8aa25310326dc87aa4a0577e72fb25e074101e78..814b70c6473a5dba8fecf56892c3295b5413844e 100644 --- a/src/hotspot/share/services/mallocSiteTable.hpp +++ b/src/hotspot/share/services/mallocSiteTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,12 @@ #ifndef SHARE_SERVICES_MALLOCSITETABLE_HPP #define SHARE_SERVICES_MALLOCSITETABLE_HPP -#include "utilities/macros.hpp" - -#if INCLUDE_NMT - #include "memory/allocation.hpp" #include "runtime/atomic.hpp" #include "services/allocationSite.hpp" #include "services/mallocTracker.hpp" #include "services/nmtCommon.hpp" +#include "utilities/macros.hpp" #include "utilities/nativeCallStack.hpp" // MallocSite represents a code path that eventually calls @@ -118,54 +115,8 @@ class MallocSiteTable : AllStatic { // in the malloc header can hold. STATIC_ASSERT(table_size <= MAX_MALLOCSITE_TABLE_SIZE); - // This is a very special lock, that allows multiple shared accesses (sharedLock), but - // once exclusive access (exclusiveLock) is requested, all shared accesses are - // rejected forever. - class AccessLock : public StackObj { - enum LockState { - NoLock, - SharedLock, - ExclusiveLock - }; - - private: - // A very large negative number. The only possibility to "overflow" - // this number is when there are more than -min_jint threads in - // this process, which is not going to happen in foreseeable future. - const static int _MAGIC_ = min_jint; - - LockState _lock_state; - volatile int* _lock; - public: - AccessLock(volatile int* lock) : - _lock_state(NoLock), _lock(lock) { - } - - ~AccessLock() { - if (_lock_state == SharedLock) { - Atomic::dec(_lock); - } - } - // Acquire shared lock. - // Return true if shared access is granted. - inline bool sharedLock() { - jint res = Atomic::add(_lock, 1); - if (res < 0) { - Atomic::dec(_lock); - return false; - } - _lock_state = SharedLock; - return true; - } - // Acquire exclusive lock - void exclusiveLock(); - }; - public: static bool initialize(); - static void shutdown(); - - NOT_PRODUCT(static int access_peak_count() { return _peak_count; }) // Number of hash buckets static inline int hash_buckets() { return (int)table_size; } @@ -174,14 +125,10 @@ class MallocSiteTable : AllStatic { // acquired before access the entry. static inline bool access_stack(NativeCallStack& stack, size_t bucket_idx, size_t pos_idx) { - AccessLock locker(&_access_count); - if (locker.sharedLock()) { - NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);) - MallocSite* site = malloc_site(bucket_idx, pos_idx); - if (site != NULL) { - stack = *site->call_stack(); - return true; - } + MallocSite* site = malloc_site(bucket_idx, pos_idx); + if (site != NULL) { + stack = *site->call_stack(); + return true; } return false; } @@ -195,27 +142,18 @@ class MallocSiteTable : AllStatic { // 2. overflow hash bucket static inline bool allocation_at(const NativeCallStack& stack, size_t size, size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) { - AccessLock locker(&_access_count); - if (locker.sharedLock()) { - NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);) - MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx, flags); - if (site != NULL) site->allocate(size); - return site != NULL; - } - return false; + MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx, flags); + if (site != NULL) site->allocate(size); + return site != NULL; } // Record memory deallocation. bucket_idx and pos_idx indicate where the allocation // information was recorded. static inline bool deallocation_at(size_t size, size_t bucket_idx, size_t pos_idx) { - AccessLock locker(&_access_count); - if (locker.sharedLock()) { - NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);) - MallocSite* site = malloc_site(bucket_idx, pos_idx); - if (site != NULL) { - site->deallocate(size); - return true; - } + MallocSite* site = malloc_site(bucket_idx, pos_idx); + if (site != NULL) { + site->deallocate(size); + return true; } return false; } @@ -251,18 +189,11 @@ class MallocSiteTable : AllStatic { } private: - // Counter for counting concurrent access - static volatile int _access_count; - // The callsite hashtable. It has to be a static table, // since malloc call can come from C runtime linker. static MallocSiteHashtableEntry* _table[table_size]; static const NativeCallStack* _hash_entry_allocation_stack; static const MallocSiteHashtableEntry* _hash_entry_allocation_site; - - - NOT_PRODUCT(static int _peak_count;) }; -#endif // INCLUDE_NMT #endif // SHARE_SERVICES_MALLOCSITETABLE_HPP diff --git a/src/hotspot/share/services/mallocTracker.cpp b/src/hotspot/share/services/mallocTracker.cpp index be1d6eea33078e62660c582871660e91c15c106e..04cf12be94f115732a53059406ad82c96397dc01 100644 --- a/src/hotspot/share/services/mallocTracker.cpp +++ b/src/hotspot/share/services/mallocTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "runtime/os.hpp" +#include "runtime/safefetch.inline.hpp" #include "services/mallocSiteTable.hpp" #include "services/mallocTracker.hpp" #include "services/mallocTracker.inline.hpp" @@ -31,6 +32,8 @@ #include "utilities/debug.hpp" #include "utilities/ostream.hpp" +#include "jvm_io.h" + size_t MallocMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)]; #ifdef ASSERT @@ -113,10 +116,9 @@ void MallocHeader::mark_block_as_dead() { } void MallocHeader::release() { - // Tracking already shutdown, no housekeeping is needed anymore - if (MemTracker::tracking_level() <= NMT_minimal) return; + assert(MemTracker::enabled(), "Sanity"); - check_block_integrity(); + assert_block_integrity(); MallocMemorySummary::record_free(size(), flags()); MallocMemorySummary::record_free_malloc_header(sizeof(MallocHeader)); @@ -154,13 +156,18 @@ void MallocHeader::print_block_on_error(outputStream* st, address bad_address) c os::print_hex_dump(st, from1, to2, 1); } } +void MallocHeader::assert_block_integrity() const { + char msg[256]; + address corruption = NULL; + if (!check_block_integrity(msg, sizeof(msg), &corruption)) { + if (corruption != NULL) { + print_block_on_error(tty, (address)this); + } + fatal("NMT corruption: Block at " PTR_FORMAT ": %s", p2i(this), msg); + } +} -// Check block integrity. If block is broken, print out a report -// to tty (optionally with hex dump surrounding the broken block), -// then trigger a fatal error. -void MallocHeader::check_block_integrity() const { - -#define PREFIX "NMT corruption: " +bool MallocHeader::check_block_integrity(char* msg, size_t msglen, address* p_corruption) const { // Note: if you modify the error messages here, make sure you // adapt the associated gtests too. @@ -168,7 +175,8 @@ void MallocHeader::check_block_integrity() const { // values. Note that we should not call this for ::free(NULL), // which should be handled by os::free() above us. if (((size_t)p2i(this)) < K) { - fatal(PREFIX "Block at " PTR_FORMAT ": invalid block address", p2i(this)); + jio_snprintf(msg, msglen, "invalid block address"); + return false; } // From here on we assume the block pointer to be valid. We could @@ -187,50 +195,47 @@ void MallocHeader::check_block_integrity() const { // Should we ever start using std::max_align_t, this would be one place to // fix up. if (!is_aligned(this, sizeof(uint64_t))) { - print_block_on_error(tty, (address)this); - fatal(PREFIX "Block at " PTR_FORMAT ": block address is unaligned", p2i(this)); + *p_corruption = (address)this; + jio_snprintf(msg, msglen, "block address is unaligned"); + return false; } // Check header canary if (_canary != _header_canary_life_mark) { - print_block_on_error(tty, (address)this); - fatal(PREFIX "Block at " PTR_FORMAT ": header canary broken.", p2i(this)); + *p_corruption = (address)this; + jio_snprintf(msg, msglen, "header canary broken"); + return false; } #ifndef _LP64 // On 32-bit we have a second canary, check that one too. if (_alt_canary != _header_alt_canary_life_mark) { - print_block_on_error(tty, (address)this); - fatal(PREFIX "Block at " PTR_FORMAT ": header alternate canary broken.", p2i(this)); + *p_corruption = (address)this; + jio_snprintf(msg, msglen, "header canary broken"); + return false; } #endif // Does block size seems reasonable? if (_size >= max_reasonable_malloc_size) { - print_block_on_error(tty, (address)this); - fatal(PREFIX "Block at " PTR_FORMAT ": header looks invalid (weirdly large block size)", p2i(this)); + *p_corruption = (address)this; + jio_snprintf(msg, msglen, "header looks invalid (weirdly large block size)"); + return false; } // Check footer canary if (get_footer() != _footer_canary_life_mark) { - print_block_on_error(tty, footer_address()); - fatal(PREFIX "Block at " PTR_FORMAT ": footer canary broken at " PTR_FORMAT " (buffer overflow?)", - p2i(this), p2i(footer_address())); + *p_corruption = footer_address(); + jio_snprintf(msg, msglen, "footer canary broken at " PTR_FORMAT " (buffer overflow?)", + p2i(footer_address())); + return false; } -#undef PREFIX + return true; } bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size, size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) const { - bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx, flags); - - // Something went wrong, could be OOM or overflow malloc site table. - // We want to keep tracking data under OOM circumstance, so transition to - // summary tracking. - if (!ret) { - MemTracker::transition_to(NMT_summary); - } - return ret; + return MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx, flags); } bool MallocHeader::get_stack(NativeCallStack& stack) const { @@ -248,18 +253,6 @@ bool MallocTracker::initialize(NMT_TrackingLevel level) { return true; } -bool MallocTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel to) { - assert(from != NMT_off, "Can not transition from off state"); - assert(to != NMT_off, "Can not transition to off state"); - assert (from != NMT_minimal, "cannot transition from minimal state"); - - if (from == NMT_detail) { - assert(to == NMT_minimal || to == NMT_summary, "Just check"); - MallocSiteTable::shutdown(); - } - return true; -} - // Record a malloc memory allocation void* MallocTracker::record_malloc(void* malloc_base, size_t size, MEMFLAGS flags, const NativeCallStack& stack, NMT_TrackingLevel level) { @@ -281,7 +274,7 @@ void* MallocTracker::record_malloc(void* malloc_base, size_t size, MEMFLAGS flag assert(((size_t)memblock & (sizeof(size_t) * 2 - 1)) == 0, "Alignment check"); #ifdef ASSERT - if (level > NMT_minimal) { + if (level > NMT_off) { // Read back assert(get_size(memblock) == size, "Wrong size"); assert(get_flags(memblock) == flags, "Wrong flags"); @@ -297,3 +290,32 @@ void* MallocTracker::record_free(void* memblock) { header->release(); return (void*)header; } + +// Given a pointer, if it seems to point to the start of a valid malloced block, +// print the block. Note that since there is very low risk of memory looking +// accidentally like a valid malloc block header (canaries and all) this is not +// totally failproof. Only use this during debugging or when you can afford +// signals popping up, e.g. when writing an hs_err file. +bool MallocTracker::print_pointer_information(const void* p, outputStream* st) { + assert(MemTracker::enabled(), "NMT must be enabled"); + if (CanUseSafeFetch32() && os::is_readable_pointer(p)) { + const NMT_TrackingLevel tracking_level = MemTracker::tracking_level(); + const MallocHeader* mhdr = (const MallocHeader*)MallocTracker::get_base(const_cast(p), tracking_level); + char msg[256]; + address p_corrupted; + if (os::is_readable_pointer(mhdr) && + mhdr->check_block_integrity(msg, sizeof(msg), &p_corrupted)) { + st->print_cr(PTR_FORMAT " malloc'd " SIZE_FORMAT " bytes by %s", + p2i(p), mhdr->size(), NMTUtil::flag_to_name(mhdr->flags())); + if (tracking_level == NMT_detail) { + NativeCallStack ncs; + if (mhdr->get_stack(ncs)) { + ncs.print_on(st); + st->cr(); + } + } + return true; + } + } + return false; +} diff --git a/src/hotspot/share/services/mallocTracker.hpp b/src/hotspot/share/services/mallocTracker.hpp index 9fd3968831be20e0817b56fe4d4922908721ce5f..78e20c30f15e53d128736e004aa55b9f6654b70f 100644 --- a/src/hotspot/share/services/mallocTracker.hpp +++ b/src/hotspot/share/services/mallocTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,14 +25,14 @@ #ifndef SHARE_SERVICES_MALLOCTRACKER_HPP #define SHARE_SERVICES_MALLOCTRACKER_HPP -#if INCLUDE_NMT - #include "memory/allocation.hpp" #include "runtime/atomic.hpp" #include "runtime/threadCritical.hpp" #include "services/nmtCommon.hpp" #include "utilities/nativeCallStack.hpp" +class outputStream; + /* * This counter class counts memory allocation and deallocation, * records total memory allocation size and number of allocations. @@ -314,10 +314,9 @@ class MallocHeader { // We discount sizes larger than these static const size_t max_reasonable_malloc_size = LP64_ONLY(256 * G) NOT_LP64(3500 * M); - // Check block integrity. If block is broken, print out a report - // to tty (optionally with hex dump surrounding the broken block), - // then trigger a fatal error. - void check_block_integrity() const; + // If block is broken, print out a report to tty (optionally with + // hex dump surrounding the broken block), then trigger a fatal error + void assert_block_integrity() const; void print_block_on_error(outputStream* st, address bad_address) const; void mark_block_as_dead(); @@ -330,13 +329,8 @@ class MallocHeader { public: MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack, NMT_TrackingLevel level) { - assert(size < max_reasonable_malloc_size, "Too large allocation size?"); - if (level == NMT_minimal) { - return; - } - _flags = NMTUtil::flag_to_index(flags); set_size(size); if (level == NMT_detail) { @@ -368,6 +362,11 @@ class MallocHeader { // Cleanup tracking information and mark block as dead before the memory is released. void release(); + // If block is broken, fill in a short descriptive text in out, + // an option pointer to the corruption in p_corruption, and return false. + // Return true if block is fine. + bool check_block_integrity(char* msg, size_t msglen, address* p_corruption) const; + private: inline void set_size(size_t size) { _size = size; @@ -386,8 +385,6 @@ class MallocTracker : AllStatic { // Initialize malloc tracker for specific tracking level static bool initialize(NMT_TrackingLevel level); - static bool transition(NMT_TrackingLevel from, NMT_TrackingLevel to); - // malloc tracking header size for specific tracking level static inline size_t malloc_header_size(NMT_TrackingLevel level) { return (level == NMT_off) ? 0 : sizeof(MallocHeader); @@ -443,6 +440,14 @@ class MallocTracker : AllStatic { static inline void record_arena_size_change(ssize_t size, MEMFLAGS flags) { MallocMemorySummary::record_arena_size_change(size, flags); } + + // Given a pointer, if it seems to point to the start of a valid malloced block, + // print the block. Note that since there is very low risk of memory looking + // accidentally like a valid malloc block header (canaries and all) this is not + // totally failproof. Only use this during debugging or when you can afford + // signals popping up, e.g. when writing an hs_err file. + static bool print_pointer_information(const void* p, outputStream* st); + private: static inline MallocHeader* malloc_header(void *memblock) { assert(memblock != NULL, "NULL pointer"); @@ -451,7 +456,4 @@ class MallocTracker : AllStatic { } }; -#endif // INCLUDE_NMT - - #endif // SHARE_SERVICES_MALLOCTRACKER_HPP diff --git a/src/hotspot/share/services/memBaseline.hpp b/src/hotspot/share/services/memBaseline.hpp index c43c937abb107648d4bd1e031aba0961d4972632..ef8013734649ab6ebc6b6ea2f04e43626aa5b36a 100644 --- a/src/hotspot/share/services/memBaseline.hpp +++ b/src/hotspot/share/services/memBaseline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_MEMBASELINE_HPP #define SHARE_SERVICES_MEMBASELINE_HPP -#if INCLUDE_NMT - #include "memory/metaspaceStats.hpp" #include "runtime/mutex.hpp" #include "services/mallocSiteTable.hpp" @@ -212,6 +210,4 @@ class MemBaseline { void virtual_memory_sites_to_reservation_site_order(); }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_MEMBASELINE_HPP diff --git a/src/hotspot/share/services/memReporter.hpp b/src/hotspot/share/services/memReporter.hpp index 77fb1d70a00a84d3fc719d428cf3f45ad360f98a..2051ab88e3cd7f48493a30a9cb02782fcbe2e61b 100644 --- a/src/hotspot/share/services/memReporter.hpp +++ b/src/hotspot/share/services/memReporter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_MEMREPORTER_HPP #define SHARE_SERVICES_MEMREPORTER_HPP -#if INCLUDE_NMT - #include "memory/metaspace.hpp" #include "oops/instanceKlass.hpp" #include "services/memBaseline.hpp" @@ -239,6 +237,4 @@ class MemDetailDiffReporter : public MemSummaryDiffReporter { size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const; }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_MEMREPORTER_HPP diff --git a/src/hotspot/share/services/memTracker.cpp b/src/hotspot/share/services/memTracker.cpp index a28d3badbcf25e102eb76ad81eb2a905ed9b2761..1037ec27418b951ee17f33a3f8bd7086a979a854 100644 --- a/src/hotspot/share/services/memTracker.cpp +++ b/src/hotspot/share/services/memTracker.cpp @@ -108,41 +108,9 @@ void Tracker::record(address addr, size_t size) { } } - -// Shutdown can only be issued via JCmd, and NMT JCmd is serialized by lock -void MemTracker::shutdown() { - // We can only shutdown NMT to minimal tracking level if it is ever on. - if (tracking_level() > NMT_minimal) { - transition_to(NMT_minimal); - } -} - -bool MemTracker::transition_to(NMT_TrackingLevel level) { - NMT_TrackingLevel current_level = tracking_level(); - - assert(level != NMT_off || current_level == NMT_off, "Cannot transition NMT to off"); - - if (current_level == level) { - return true; - } else if (current_level > level) { - // Downgrade tracking level, we want to lower the tracking level first - _tracking_level = level; - // Make _tracking_level visible immediately. - OrderAccess::fence(); - VirtualMemoryTracker::transition(current_level, level); - MallocTracker::transition(current_level, level); - ThreadStackTracker::transition(current_level, level); - } else { - // Upgrading tracking level is not supported and has never been supported. - // Allocating and deallocating malloc tracking structures is not thread safe and - // leads to inconsistencies unless a lot coarser locks are added. - } - return true; -} - // Report during error reporting. void MemTracker::error_report(outputStream* output) { - if (tracking_level() >= NMT_summary) { + if (enabled()) { report(true, output, MemReporterBase::default_scale); // just print summary for error case. output->print("Preinit state:"); NMTPreInit::print_state(output); @@ -157,11 +125,8 @@ void MemTracker::final_report(outputStream* output) { // printing the final report during normal VM exit, it should not print // the final report again. In addition, it should be guarded from // recursive calls in case NMT reporting itself crashes. - if (Atomic::cmpxchg(&g_final_report_did_run, false, true) == false) { - NMT_TrackingLevel level = tracking_level(); - if (level >= NMT_summary) { - report(level == NMT_summary, output, 1); - } + if (enabled() && Atomic::cmpxchg(&g_final_report_did_run, false, true) == false) { + report(tracking_level() == NMT_summary, output, 1); } } @@ -189,7 +154,6 @@ void MemTracker::tuning_statistics(outputStream* out) { out->print_cr("State: %s", NMTUtil::tracking_level_to_string(_tracking_level)); out->print_cr("Malloc allocation site table size: %d", MallocSiteTable::hash_buckets()); out->print_cr(" Tracking stack depth: %d", NMT_TrackingStackDepth); - NOT_PRODUCT(out->print_cr("Peak concurrent access: %d", MallocSiteTable::access_peak_count());) out->cr(); MallocSiteTable::print_tuning_statistics(out); out->cr(); diff --git a/src/hotspot/share/services/memTracker.hpp b/src/hotspot/share/services/memTracker.hpp index 21d1aa82630829869e7e60b79e7260c3f26564aa..06d5c0c94a892813c95ac3c62ae0b3a12aff943e 100644 --- a/src/hotspot/share/services/memTracker.hpp +++ b/src/hotspot/share/services/memTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,67 +25,13 @@ #ifndef SHARE_SERVICES_MEMTRACKER_HPP #define SHARE_SERVICES_MEMTRACKER_HPP -#include "services/nmtCommon.hpp" -#include "utilities/nativeCallStack.hpp" - - -#if !INCLUDE_NMT - -#define CURRENT_PC NativeCallStack::empty_stack() -#define CALLER_PC NativeCallStack::empty_stack() - -class Tracker : public StackObj { - public: - enum TrackerType { - uncommit, - release - }; - Tracker(enum TrackerType type) : _type(type) { } - void record(address addr, size_t size) { } - private: - enum TrackerType _type; -}; - -class MemTracker : AllStatic { - public: - static inline NMT_TrackingLevel tracking_level() { return NMT_off; } - static inline void shutdown() { } - static inline void init() { } - static bool check_launcher_nmt_support(const char* value) { return true; } - static bool verify_nmt_option() { return true; } - - static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag, - const NativeCallStack& stack, NMT_TrackingLevel level) { return mem_base; } - static inline size_t malloc_header_size(NMT_TrackingLevel level) { return 0; } - static inline size_t malloc_header_size(void* memblock) { return 0; } - static inline size_t malloc_footer_size(NMT_TrackingLevel level) { return 0; } - static inline void* malloc_base(void* memblock) { return memblock; } - static inline void* record_free(void* memblock, NMT_TrackingLevel level) { return memblock; } - - static inline void record_new_arena(MEMFLAGS flag) { } - static inline void record_arena_free(MEMFLAGS flag) { } - static inline void record_arena_size_change(ssize_t diff, MEMFLAGS flag) { } - static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack, - MEMFLAGS flag = mtNone) { } - static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size, - const NativeCallStack& stack, MEMFLAGS flag = mtNone) { } - static inline void record_virtual_memory_split_reserved(void* addr, size_t size, size_t split) { } - static inline void record_virtual_memory_commit(void* addr, size_t size, const NativeCallStack& stack) { } - static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { } - static inline void record_thread_stack(void* addr, size_t size) { } - static inline void release_thread_stack(void* addr, size_t size) { } - - static void final_report(outputStream*) { } - static void error_report(outputStream*) { } -}; - -#else - #include "runtime/mutexLocker.hpp" #include "runtime/threadCritical.hpp" #include "services/mallocTracker.hpp" +#include "services/nmtCommon.hpp" #include "services/threadStackTracker.hpp" #include "services/virtualMemoryTracker.hpp" +#include "utilities/nativeCallStack.hpp" #define CURRENT_PC ((MemTracker::tracking_level() == NMT_detail) ? \ NativeCallStack(0) : NativeCallStack::empty_stack()) @@ -137,14 +83,9 @@ class MemTracker : AllStatic { return _tracking_level; } - // Shutdown native memory tracking. - // This transitions the tracking level: - // summary -> minimal - // detail -> minimal - static void shutdown(); - - // Transition the tracking level to specified level - static bool transition_to(NMT_TrackingLevel level); + static inline bool enabled() { + return _tracking_level > NMT_off; + } static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag, const NativeCallStack& stack, NMT_TrackingLevel level) { @@ -180,20 +121,20 @@ class MemTracker : AllStatic { // Record creation of an arena static inline void record_new_arena(MEMFLAGS flag) { - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; MallocTracker::record_new_arena(flag); } // Record destruction of an arena static inline void record_arena_free(MEMFLAGS flag) { - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; MallocTracker::record_arena_free(flag); } // Record arena size change. Arena size is the size of all arena // chuncks that backing up the arena. static inline void record_arena_size_change(ssize_t diff, MEMFLAGS flag) { - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; MallocTracker::record_arena_size_change(diff, flag); } @@ -203,11 +144,9 @@ class MemTracker : AllStatic { static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack, MEMFLAGS flag = mtNone) { assert_post_init(); - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; if (addr != NULL) { ThreadCritical tc; - // Recheck to avoid potential racing during NMT shutdown - if (tracking_level() < NMT_summary) return; VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, flag); } } @@ -215,10 +154,9 @@ class MemTracker : AllStatic { static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size, const NativeCallStack& stack, MEMFLAGS flag = mtNone) { assert_post_init(); - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; if (addr != NULL) { ThreadCritical tc; - if (tracking_level() < NMT_summary) return; VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, flag); VirtualMemoryTracker::add_committed_region((address)addr, size, stack); } @@ -227,10 +165,9 @@ class MemTracker : AllStatic { static inline void record_virtual_memory_commit(void* addr, size_t size, const NativeCallStack& stack) { assert_post_init(); - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; if (addr != NULL) { ThreadCritical tc; - if (tracking_level() < NMT_summary) return; VirtualMemoryTracker::add_committed_region((address)addr, size, stack); } } @@ -243,28 +180,25 @@ class MemTracker : AllStatic { // memory flags of the original region. static inline void record_virtual_memory_split_reserved(void* addr, size_t size, size_t split) { assert_post_init(); - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; if (addr != NULL) { ThreadCritical tc; - // Recheck to avoid potential racing during NMT shutdown - if (tracking_level() < NMT_summary) return; VirtualMemoryTracker::split_reserved_region((address)addr, size, split); } } static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { assert_post_init(); - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; if (addr != NULL) { ThreadCritical tc; - if (tracking_level() < NMT_summary) return; VirtualMemoryTracker::set_reserved_region_type((address)addr, flag); } } static void record_thread_stack(void* addr, size_t size) { assert_post_init(); - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; if (addr != NULL) { ThreadStackTracker::new_thread_stack((address)addr, size, CALLER_PC); } @@ -272,7 +206,7 @@ class MemTracker : AllStatic { static inline void release_thread_stack(void* addr, size_t size) { assert_post_init(); - if (tracking_level() < NMT_summary) return; + if (!enabled()) return; if (addr != NULL) { ThreadStackTracker::delete_thread_stack((address)addr, size); } @@ -321,6 +255,4 @@ class MemTracker : AllStatic { static Mutex* _query_lock; }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_MEMTRACKER_HPP diff --git a/src/hotspot/share/services/nmtCommon.cpp b/src/hotspot/share/services/nmtCommon.cpp index 0137a880d8c55c42b6a51dd806be58ce1d535447..2494336595bb73866736690db4f1df1e1c513fc5 100644 --- a/src/hotspot/share/services/nmtCommon.cpp +++ b/src/hotspot/share/services/nmtCommon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,11 +28,14 @@ #define MEMORY_TYPE_DECLARE_NAME(type, human_readable) \ human_readable, +STATIC_ASSERT(NMT_off > NMT_unknown); +STATIC_ASSERT(NMT_summary > NMT_off); +STATIC_ASSERT(NMT_detail > NMT_summary); + const char* NMTUtil::_memory_type_names[] = { MEMORY_TYPES_DO(MEMORY_TYPE_DECLARE_NAME) }; - const char* NMTUtil::scale_name(size_t scale) { switch(scale) { case 1: return ""; @@ -64,7 +67,6 @@ const char* NMTUtil::tracking_level_to_string(NMT_TrackingLevel lvl) { switch(lvl) { case NMT_unknown: return "unknown"; break; case NMT_off: return "off"; break; - case NMT_minimal: return "minimal"; break; case NMT_summary: return "summary"; break; case NMT_detail: return "detail"; break; default: return "invalid"; break; diff --git a/src/hotspot/share/services/nmtCommon.hpp b/src/hotspot/share/services/nmtCommon.hpp index 108769760915dc7cbfb549a6898e2fbdad695b6c..dc85338c025a0fe74efc0c406210d51b7cd8593d 100644 --- a/src/hotspot/share/services/nmtCommon.hpp +++ b/src/hotspot/share/services/nmtCommon.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_SERVICES_NMTCOMMON_HPP #define SHARE_SERVICES_NMTCOMMON_HPP -#include "memory/allocation.hpp" +#include "memory/allocation.hpp" // for MEMFLAGS only #include "utilities/align.hpp" #include "utilities/globalDefinitions.hpp" @@ -41,10 +41,6 @@ // - nothing is tracked // - no malloc headers are used // -// "minimal": after shutdown - NMT had been on at some point but has been switched off -// - nothing is tracked -// - malloc headers are allocated but not initialized not used -// // "summary": after initialization with NativeMemoryTracking=summary - NMT in summary mode // - category summaries per tag are tracked // - thread stacks are tracked @@ -59,25 +55,16 @@ // - malloc headers are used // - malloc call site table is allocated and used // -// Valid state transitions: -// -// unknown ----> off -// | -// |--> summary -- -// | | -// |--> detail --+--> minimal -// // Please keep relation of numerical values! -// unknown < off < minimal < summary < detail +// unknown < off < summary < detail // enum NMT_TrackingLevel { - NMT_unknown = 0, - NMT_off = 1, - NMT_minimal = 2, - NMT_summary = 3, - NMT_detail = 4 + NMT_unknown, + NMT_off, + NMT_summary, + NMT_detail }; // Number of stack frames to capture. This is a diff --git a/src/hotspot/share/services/nmtDCmd.hpp b/src/hotspot/share/services/nmtDCmd.hpp index 52c61d34c0c138d8fc25151454ae70e3cfa76ed0..23302b790a6bf65869207bbbb53be5dae857944f 100644 --- a/src/hotspot/share/services/nmtDCmd.hpp +++ b/src/hotspot/share/services/nmtDCmd.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_NMTDCMD_HPP #define SHARE_SERVICES_NMTDCMD_HPP -#if INCLUDE_NMT - #include "services/diagnosticArgument.hpp" #include "services/diagnosticFramework.hpp" #include "services/memBaseline.hpp" @@ -71,6 +69,4 @@ class NMTDCmd: public DCmdWithParser { bool check_detail_tracking_level(outputStream* out); }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_NMTDCMD_HPP diff --git a/src/hotspot/share/services/nmtPreInit.cpp b/src/hotspot/share/services/nmtPreInit.cpp index 1fdf4ba9d9f572d1cf5fb818debe1b8c8f397ded..67eb3eef41f6abf85e20b4057fedde326d08420b 100644 --- a/src/hotspot/share/services/nmtPreInit.cpp +++ b/src/hotspot/share/services/nmtPreInit.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022 SAP SE. All rights reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,8 +31,6 @@ #include "utilities/ostream.hpp" #include "utilities/globalDefinitions.hpp" -#if INCLUDE_NMT - // Obviously we cannot use os::malloc for any dynamic allocation during pre-NMT-init, so we must use // raw malloc; to make this very clear, wrap them. static void* raw_malloc(size_t s) { return ::malloc(s); } @@ -190,5 +188,3 @@ void NMTPreInit::print_state(outputStream* st) { st->print_cr("pre-init mallocs: %u, pre-init reallocs: %u, pre-init frees: %u", _num_mallocs_pre, _num_reallocs_pre, _num_frees_pre); } - -#endif // INCLUDE_NMT diff --git a/src/hotspot/share/services/nmtPreInit.hpp b/src/hotspot/share/services/nmtPreInit.hpp index eed2519113554db9f37ad3c53b8a4401d49fa892..d65ebaf5dc3bd22d932d690158c5ee0f6834adcd 100644 --- a/src/hotspot/share/services/nmtPreInit.hpp +++ b/src/hotspot/share/services/nmtPreInit.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022 SAP SE. All rights reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,6 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -#if INCLUDE_NMT - class outputStream; // NMTPreInit is the solution to a specific problem: @@ -353,7 +351,5 @@ public: DEBUG_ONLY(static void verify();) }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_NMT_PREINIT_HPP diff --git a/src/hotspot/share/services/threadIdTable.hpp b/src/hotspot/share/services/threadIdTable.hpp index 223b57fcecbf5597cc6893a6b398522a58e0940d..12772aed88c0b62c457ca0903bcd6d6b1ebeabdb 100644 --- a/src/hotspot/share/services/threadIdTable.hpp +++ b/src/hotspot/share/services/threadIdTable.hpp @@ -26,7 +26,7 @@ #ifndef SHARE_SERVICES_THREADIDTABLE_HPP #define SHARE_SERVICES_THREADIDTABLE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JavaThread; class ThreadsList; diff --git a/src/hotspot/share/services/threadService.cpp b/src/hotspot/share/services/threadService.cpp index c99d789021b0dabfb0c460118203765010826980..42b38000a84f1ae863fa7ea4c3ca5de88cf3c02f 100644 --- a/src/hotspot/share/services/threadService.cpp +++ b/src/hotspot/share/services/threadService.cpp @@ -659,7 +659,7 @@ ThreadStackTrace::~ThreadStackTrace() { } } -void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth) { +void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth, ObjectMonitorsHashtable* table) { assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped"); if (_thread->has_last_Java_frame()) { @@ -683,9 +683,19 @@ void ThreadStackTrace::dump_stack_at_safepoint(int maxDepth) { if (_with_locked_monitors) { // Iterate inflated monitors and find monitors locked by this thread - // not found in the stack + // that are not found in the stack, e.g. JNI locked monitors: InflatedMonitorsClosure imc(this); - ObjectSynchronizer::monitors_iterate(&imc, _thread); + if (table != nullptr) { + // Get the ObjectMonitors locked by the target thread, if any, + // and does not include any where owner is set to a stack lock + // address in the target thread: + ObjectMonitorsHashtable::PtrList* list = table->get_entry(_thread); + if (list != nullptr) { + ObjectSynchronizer::monitors_iterate(&imc, list, _thread); + } + } else { + ObjectSynchronizer::monitors_iterate(&imc, _thread); + } } } @@ -936,9 +946,10 @@ ThreadSnapshot::~ThreadSnapshot() { delete _concurrent_locks; } -void ThreadSnapshot::dump_stack_at_safepoint(int max_depth, bool with_locked_monitors) { +void ThreadSnapshot::dump_stack_at_safepoint(int max_depth, bool with_locked_monitors, + ObjectMonitorsHashtable* table) { _stack_trace = new ThreadStackTrace(_thread, with_locked_monitors); - _stack_trace->dump_stack_at_safepoint(max_depth); + _stack_trace->dump_stack_at_safepoint(max_depth, table); } diff --git a/src/hotspot/share/services/threadService.hpp b/src/hotspot/share/services/threadService.hpp index e78fbab080866e9ea68ea0ad775fcf329dfe0de5..ed411d42a90d58fbfb5a2f017917598f6ac67e39 100644 --- a/src/hotspot/share/services/threadService.hpp +++ b/src/hotspot/share/services/threadService.hpp @@ -247,7 +247,8 @@ public: ThreadStackTrace* get_stack_trace() { return _stack_trace; } ThreadConcurrentLocks* get_concurrent_locks() { return _concurrent_locks; } - void dump_stack_at_safepoint(int max_depth, bool with_locked_monitors); + void dump_stack_at_safepoint(int max_depth, bool with_locked_monitors, + ObjectMonitorsHashtable* table); void set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; } void metadata_do(void f(Metadata*)); }; @@ -270,7 +271,7 @@ class ThreadStackTrace : public CHeapObj { int get_stack_depth() { return _depth; } void add_stack_frame(javaVFrame* jvf); - void dump_stack_at_safepoint(int max_depth); + void dump_stack_at_safepoint(int max_depth, ObjectMonitorsHashtable* table); Handle allocate_fill_stack_trace_element_array(TRAPS); void metadata_do(void f(Metadata*)); GrowableArray* jni_locked_monitors() { return _jni_locked_monitors; } diff --git a/src/hotspot/share/services/threadStackTracker.cpp b/src/hotspot/share/services/threadStackTracker.cpp index b426e81613bf1a41361a0453a9202fa073e6c98a..5caad66bb89f5558b1d157e96af8da7d33ba50ea 100644 --- a/src/hotspot/share/services/threadStackTracker.cpp +++ b/src/hotspot/share/services/threadStackTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,19 +42,6 @@ bool ThreadStackTracker::initialize(NMT_TrackingLevel level) { return true; } -bool ThreadStackTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel to) { - assert (from != NMT_minimal, "cannot convert from the lowest tracking level to anything"); - if (to == NMT_minimal) { - assert(from == NMT_summary || from == NMT_detail, "Just check"); - ThreadCritical tc; - if (_simple_thread_stacks != NULL) { - delete _simple_thread_stacks; - _simple_thread_stacks = NULL; - } - } - return true; -} - int ThreadStackTracker::compare_thread_stack_base(const SimpleThreadStackSite& s1, const SimpleThreadStackSite& s2) { return s1.base() - s2.base(); } diff --git a/src/hotspot/share/services/threadStackTracker.hpp b/src/hotspot/share/services/threadStackTracker.hpp index 3eee93cd71c4e06b4b6753a1f51aa14b203f6a1c..db7fc0e8569f4e84960b958ff51e496a5e48c3ff 100644 --- a/src/hotspot/share/services/threadStackTracker.hpp +++ b/src/hotspot/share/services/threadStackTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_THREADSTACKTRACKER_HPP #define SHARE_SERVICES_THREADSTACKTRACKER_HPP -#if INCLUDE_NMT - #include "services/allocationSite.hpp" #include "services/mallocSiteTable.hpp" #include "services/nmtCommon.hpp" @@ -72,7 +70,6 @@ private: static SortedLinkedList* _simple_thread_stacks; public: static bool initialize(NMT_TrackingLevel level); - static bool transition(NMT_TrackingLevel from, NMT_TrackingLevel to); static void new_thread_stack(void* base, size_t size, const NativeCallStack& stack); static void delete_thread_stack(void* base, size_t size); @@ -85,5 +82,5 @@ public: static bool walk_simple_thread_stack_site(MallocSiteWalker* walker); }; -#endif // INCLUDE_NMT #endif // SHARE_SERVICES_THREADSTACKTRACKER_HPP + diff --git a/src/hotspot/share/services/virtualMemoryTracker.cpp b/src/hotspot/share/services/virtualMemoryTracker.cpp index f9909f9e5691443077a4c066d6f952771d4a4264..d259966e6117d1ed7632fc7a9366e0051d8ad797 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.cpp +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -672,19 +672,32 @@ bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) { return true; } -// Transition virtual memory tracking level. -bool VirtualMemoryTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel to) { - assert (from != NMT_minimal, "cannot convert from the lowest tracking level to anything"); - if (to == NMT_minimal) { - assert(from == NMT_summary || from == NMT_detail, "Just check"); - // Clean up virtual memory tracking data structures. - ThreadCritical tc; - // Check for potential race with other thread calling transition - if (_reserved_regions != NULL) { - delete _reserved_regions; - _reserved_regions = NULL; +class PrintRegionWalker : public VirtualMemoryWalker { +private: + const address _p; + outputStream* _st; +public: + PrintRegionWalker(const void* p, outputStream* st) : + _p((address)p), _st(st) { } + + bool do_allocation_site(const ReservedMemoryRegion* rgn) { + if (rgn->contain_address(_p)) { + _st->print_cr(PTR_FORMAT " in mmap'd memory region [" PTR_FORMAT " - " PTR_FORMAT "] by %s", + p2i(_p), p2i(rgn->base()), p2i(rgn->base() + rgn->size()), rgn->flag_name()); + if (MemTracker::tracking_level() == NMT_detail) { + rgn->call_stack()->print_on(_st); + _st->cr(); + } + return false; } + return true; } +}; + +// If p is contained within a known memory region, print information about it to the +// given stream and return true; false otherwise. +bool VirtualMemoryTracker::print_containing_region(const void* p, outputStream* st) { + PrintRegionWalker walker(p, st); + return !walk_virtual_memory(&walker); - return true; } diff --git a/src/hotspot/share/services/virtualMemoryTracker.hpp b/src/hotspot/share/services/virtualMemoryTracker.hpp index a7948f67447ead9d4d1f6933c1ea4740cc054bc7..9ae61a605fb1eab83873cdf822c338cd3ddf08a7 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.hpp +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_VIRTUALMEMORYTRACKER_HPP #define SHARE_SERVICES_VIRTUALMEMORYTRACKER_HPP -#if INCLUDE_NMT - #include "memory/allocation.hpp" #include "memory/metaspace.hpp" // For MetadataType #include "memory/metaspaceStats.hpp" @@ -341,7 +339,7 @@ class ReservedMemoryRegion : public VirtualMemoryRegion { return *this; } - const char* flag_name() { return NMTUtil::flag_to_name(_flag); } + const char* flag_name() const { return NMTUtil::flag_to_name(_flag); } private: // The committed region contains the uncommitted region, subtract the uncommitted @@ -387,7 +385,9 @@ class VirtualMemoryTracker : AllStatic { // Walk virtual memory data structure for creating baseline, etc. static bool walk_virtual_memory(VirtualMemoryWalker* walker); - static bool transition(NMT_TrackingLevel from, NMT_TrackingLevel to); + // If p is contained within a known memory region, print information about it to the + // given stream and return true; false otherwise. + static bool print_containing_region(const void* p, outputStream* st); // Snapshot current thread stacks static void snapshot_thread_stacks(); @@ -396,6 +396,5 @@ class VirtualMemoryTracker : AllStatic { static SortedLinkedList* _reserved_regions; }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_VIRTUALMEMORYTRACKER_HPP + diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index 83d1b6579062d80587cd1af030a9587f22ae91c1..71c9c286f8fc690f44e6a2796841cc680cf29962 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -70,11 +70,12 @@ enum { JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class JVM_ACC_IS_BEING_REDEFINED = 0x00100000, // True if the klass is being redefined. + JVM_ACC_HAS_RESOLVED_METHODS = 0x00200000, // True if the klass has resolved methods // Klass* and Method* flags - JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00200000, + JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00400000, - JVM_ACC_PROMOTED_FLAGS = 0x00200000, // flags promoted from methods to the holding klass + JVM_ACC_PROMOTED_FLAGS = 0x00400000, // flags promoted from methods to the holding klass // field flags // Note: these flags must be defined in the low order 16 bits because @@ -164,6 +165,9 @@ class AccessFlags { void set_is_being_redefined() { atomic_set_bits(JVM_ACC_IS_BEING_REDEFINED); } void clear_is_being_redefined() { atomic_clear_bits(JVM_ACC_IS_BEING_REDEFINED); } + bool has_resolved_methods() const { return (_flags & JVM_ACC_HAS_RESOLVED_METHODS) != 0; } + void set_has_resolved_methods() { atomic_set_bits(JVM_ACC_HAS_RESOLVED_METHODS); } + // field flags bool is_field_access_watched() const { return (_flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; } bool is_field_modification_watched() const diff --git a/src/hotspot/share/utilities/copy.hpp b/src/hotspot/share/utilities/copy.hpp index bd502d5313d27b7cd712c097d9eea082df13075a..12f59ad1311b3c9d481e761a08b92e5eb5b6ee5f 100644 --- a/src/hotspot/share/utilities/copy.hpp +++ b/src/hotspot/share/utilities/copy.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,15 +37,6 @@ extern "C" { void _Copy_conjoint_words(const HeapWord* from, HeapWord* to, size_t count); void _Copy_disjoint_words(const HeapWord* from, HeapWord* to, size_t count); - void _Copy_conjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count); - void _Copy_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count); - - void _Copy_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count); - void _Copy_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count); - - void _Copy_conjoint_bytes(const void* from, void* to, size_t count); - - void _Copy_conjoint_bytes_atomic (const void* from, void* to, size_t count); void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count); void _Copy_conjoint_jints_atomic (const jint* from, jint* to, size_t count); void _Copy_conjoint_jlongs_atomic (const jlong* from, jlong* to, size_t count); @@ -55,7 +46,6 @@ extern "C" { void _Copy_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count); void _Copy_arrayof_conjoint_jints (const HeapWord* from, HeapWord* to, size_t count); void _Copy_arrayof_conjoint_jlongs (const HeapWord* from, HeapWord* to, size_t count); - void _Copy_arrayof_conjoint_oops (const HeapWord* from, HeapWord* to, size_t count); } class Copy : AllStatic { diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp index 1a0c3a84647fe1b9c5136304d91da76ad29a74a5..e8d95ebec1c4c7b57985ea62963b9d306d7dd062 100644 --- a/src/hotspot/share/utilities/debug.cpp +++ b/src/hotspot/share/utilities/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,9 @@ #include "runtime/vframe.hpp" #include "runtime/vm_version.hpp" #include "services/heapDumper.hpp" +#include "services/mallocTracker.hpp" #include "services/memTracker.hpp" +#include "services/virtualMemoryTracker.hpp" #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" #include "utilities/formatBuffer.hpp" @@ -480,7 +482,23 @@ extern "C" JNIEXPORT void pp(void* p) { oop obj = cast_to_oop(p); obj->print(); } else { - tty->print(PTR_FORMAT, p2i(p)); + // Ask NMT about this pointer. + // GDB note: We will be using SafeFetch to access the supposed malloc header. If the address is + // not readable, this will generate a signal. That signal will trip up the debugger: gdb will + // catch the signal and disable the pp() command for further use. + // In order to avoid that, switch off SIGSEGV handling with "handle SIGSEGV nostop" before + // invoking pp() + if (MemTracker::enabled()) { + // Does it point into a known mmaped region? + if (VirtualMemoryTracker::print_containing_region(p, tty)) { + return; + } + // Does it look like the start of a malloced block? + if (MallocTracker::print_pointer_information(p, tty)) { + return; + } + } + tty->print_cr(PTR_FORMAT, p2i(p)); } } diff --git a/src/hotspot/share/utilities/decoder.hpp b/src/hotspot/share/utilities/decoder.hpp index ccf3ac4ba3cfb8a2428cdd3874463a5ac8761d95..b0a368fd058ebca5c01aa127e0b7d0e0b4e79938 100644 --- a/src/hotspot/share/utilities/decoder.hpp +++ b/src/hotspot/share/utilities/decoder.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #ifndef SHARE_UTILITIES_DECODER_HPP #define SHARE_UTILITIES_DECODER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/mutex.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/share/utilities/elfFile.cpp b/src/hotspot/share/utilities/elfFile.cpp index 1e2a6a5279f868585da3c70fbd0b5bafbcfdcf76..2198d2943c17e32ef10534910bd3df8d2abc1187 100644 --- a/src/hotspot/share/utilities/elfFile.cpp +++ b/src/hotspot/share/utilities/elfFile.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -168,7 +168,7 @@ void ElfFile::cleanup_tables() { NullDecoder::decoder_status ElfFile::parse_elf(const char* filepath) { assert(filepath, "null file path"); - _file = fopen(filepath, "r"); + _file = os::fopen(filepath, "r"); if (_file != NULL) { return load_tables(); } else { diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index e71c48c6c423ffb1b29dbc982d768d25d4230b80..4ddc8e18ae6620bab8d8a8108f04a2585a3e14c5 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -461,9 +461,9 @@ volatile int Exceptions::_out_of_memory_error_metaspace_errors = 0; volatile int Exceptions::_out_of_memory_error_class_metaspace_errors = 0; void Exceptions::count_out_of_memory_exceptions(Handle exception) { - if (exception() == Universe::out_of_memory_error_metaspace()) { + if (Universe::is_out_of_memory_error_metaspace(exception())) { Atomic::inc(&_out_of_memory_error_metaspace_errors, memory_order_relaxed); - } else if (exception() == Universe::out_of_memory_error_class_metaspace()) { + } else if (Universe::is_out_of_memory_error_class_metaspace(exception())) { Atomic::inc(&_out_of_memory_error_class_metaspace_errors, memory_order_relaxed); } else { // everything else reported as java heap OOM diff --git a/src/hotspot/share/utilities/globalCounter.hpp b/src/hotspot/share/utilities/globalCounter.hpp index beba72a954a1a0115d8ae4acf05d59c69d9d659f..5f5eba263b98012992538de5027fa1c741b79ce0 100644 --- a/src/hotspot/share/utilities/globalCounter.hpp +++ b/src/hotspot/share/utilities/globalCounter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_UTILITIES_GLOBALCOUNTER_HPP #define SHARE_UTILITIES_GLOBALCOUNTER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/padded.hpp" class Thread; diff --git a/src/hotspot/share/utilities/globalDefinitions.cpp b/src/hotspot/share/utilities/globalDefinitions.cpp index a1d3cd9ccf386123e35650da261e003fff464a6b..349d99f3311f8eda545d60f1a1f03dd35c57ef86 100644 --- a/src/hotspot/share/utilities/globalDefinitions.cpp +++ b/src/hotspot/share/utilities/globalDefinitions.cpp @@ -39,6 +39,14 @@ int LogBitsPerHeapOop = 0; int BytesPerHeapOop = 0; int BitsPerHeapOop = 0; +// Old CDS options +bool DumpSharedSpaces; +bool DynamicDumpSharedSpaces; +bool RequireSharedSpaces; +extern "C" { +JNIEXPORT jboolean UseSharedSpaces = true; +} + // Object alignment, in units of HeapWords. // Defaults are -1 so things will break badly if incorrectly initialized. int MinObjAlignment = -1; diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index 78a8ffa11bfa9623950c57a257e52509a26d3f2a..1b0b90e70fc00397e455b70644b54dd22141e7f4 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -508,6 +508,16 @@ const jfloat max_jfloat = jfloat_cast(max_jintFloat); const int max_method_code_size = 64*K - 1; // JVM spec, 2nd ed. section 4.8.1 (p.134) +//---------------------------------------------------------------------------------------------------- +// old CDS options +extern bool DumpSharedSpaces; +extern bool DynamicDumpSharedSpaces; +extern bool RequireSharedSpaces; +extern "C" { +// Make sure UseSharedSpaces is accessible to the serviceability agent. +extern JNIEXPORT jboolean UseSharedSpaces; +} + //---------------------------------------------------------------------------------------------------- // Object alignment, in units of HeapWords. // diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp index 9b362b88c11911a2c89360d0c7e08cc5d4678523..9207e8a1739c8b2a8e75ee9b71a3711a993c398a 100644 --- a/src/hotspot/share/utilities/macros.hpp +++ b/src/hotspot/share/utilities/macros.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -241,22 +241,6 @@ #define NOT_ZGC_RETURN_(code) { return code; } #endif // INCLUDE_ZGC -#ifndef INCLUDE_NMT -#define INCLUDE_NMT 1 -#endif // INCLUDE_NMT - -#if INCLUDE_NMT -#define NOT_NMT_RETURN /* next token must be ; */ -#define NOT_NMT_RETURN_(code) /* next token must be ; */ -#define NMT_ONLY(x) x -#define NOT_NMT(x) -#else -#define NOT_NMT_RETURN {} -#define NOT_NMT_RETURN_(code) { return code; } -#define NMT_ONLY(x) -#define NOT_NMT(x) x -#endif // INCLUDE_NMT - #ifndef INCLUDE_JFR #define INCLUDE_JFR 1 #endif diff --git a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp index 355b21209021c703585478c9c3732b8842fb9194..2fbd26f2dca91e47f5e17d998beba8981b1b1852 100644 --- a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp +++ b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp @@ -135,28 +135,46 @@ bool NonblockingQueue::try_pop(T** node_ptr) { } T* next_node = Atomic::load_acquire(next_ptr(*result)); - if (next_node == NULL) { - // A concurrent try_pop already claimed what was the last entry. That - // operation may not have cleared queue head yet, but we should still - // treat the queue as empty until a push/append operation changes head - // to an entry with a non-NULL next value. - *node_ptr = NULL; - return true; - - } else if (!is_end(next_node)) { - // The next_node is not at the end of the queue's list. Use the "usual" - // lock-free pop from the head of a singly linked list to try to take it. - if (result == Atomic::cmpxchg(&_head, result, next_node)) { - // Former head successfully taken. + if (!is_end(next_node)) { + // [Clause 1] + // There are several cases for next_node. + // (1) next_node is the extension of the queue's list. + // (2) next_node is NULL, because a competing try_pop took result. + // (3) next_node is the extension of some unrelated list, because a + // competing try_pop took result and put it in some other list. + // + // Attempt to advance the list, replacing result with next_node in + // _head. The success or failure of that attempt, along with the value + // of next_node, are used to partially determine which case we're in and + // how to proceed. In particular, advancement will fail for case (3). + if (result != Atomic::cmpxchg(&_head, result, next_node)) { + // [Clause 1a] + // The cmpxchg to advance the list failed; a concurrent try_pop won + // the race and claimed result. This can happen for any of the + // next_node cases. + return false; + } else if (next_node == NULL) { + // [Clause 1b] + // The cmpxchg to advance the list succeeded, but a concurrent try_pop + // has already claimed result (see [Clause 2] - result was the last + // entry in the list) by nulling result's next field. The advance set + // _head to NULL, "helping" the competing try_pop. _head will remain + // NULL until a subsequent push/append. This is a lost race, and we + // report it as such for consistency, though we could report the queue + // was empty. + return false; + } else { + // [Clause 1c] + // Successfully advanced the list and claimed result. next_node was + // in the extension of the queue's list. Return result after + // unlinking it from next_node. set_next(*result, NULL); *node_ptr = result; return true; - } else { - // Lost race to take result from the head of the list. - return false; } - } else if (is_end(Atomic::cmpxchg(next_ptr(*result), end_marker(), (T*)NULL))) { + } else if (is_end(Atomic::cmpxchg(next_ptr(*result), next_node, (T*)NULL))) { + // [Clause 2] // Result was the last entry and we've claimed it by setting its next // value to NULL. However, this leaves the queue in disarray. Fix up // the queue, possibly in conjunction with other concurrent operations. @@ -170,7 +188,8 @@ bool NonblockingQueue::try_pop(T** node_ptr) { Atomic::cmpxchg(&_tail, result, (T*)NULL); // Attempt to change the queue head from result to NULL. Failure of the - // cmpxchg indicates a concurrent push/append updated the head first. + // cmpxchg indicates a concurrent operation updated _head first. That + // could be either a push/extend or a try_pop in [Clause 1b]. Atomic::cmpxchg(&_head, result, (T*)NULL); // The queue has been restored to order, and we can return the result. @@ -178,9 +197,10 @@ bool NonblockingQueue::try_pop(T** node_ptr) { return true; } else { - // Result was the last entry in the list, but either a concurrent pop - // claimed it first or a concurrent push/append extended the list from - // it. Either way, we lost the race. + // [Clause 3] + // Result was the last entry in the list, but either a concurrent + // try_pop claimed it first or a concurrent push/append extended the + // list from it. Either way, we lost the race to claim it. return false; } } diff --git a/src/hotspot/share/utilities/ostream.cpp b/src/hotspot/share/utilities/ostream.cpp index 04995064fe3a98489bebb3605ceadc9d02b38f95..efb6a4ac7e6b77a51a03eb58f79428b9aa199ed1 100644 --- a/src/hotspot/share/utilities/ostream.cpp +++ b/src/hotspot/share/utilities/ostream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -545,7 +545,7 @@ const char* make_log_name(const char* log_name, const char* force_directory) { } fileStream::fileStream(const char* file_name) { - _file = fopen(file_name, "w"); + _file = os::fopen(file_name, "w"); if (_file != NULL) { _need_close = true; } else { @@ -555,7 +555,7 @@ fileStream::fileStream(const char* file_name) { } fileStream::fileStream(const char* file_name, const char* opentype) { - _file = fopen(file_name, opentype); + _file = os::fopen(file_name, opentype); if (_file != NULL) { _need_close = true; } else { @@ -614,7 +614,7 @@ void fileStream::flush() { void fdStream::write(const char* s, size_t len) { if (_fd != -1) { // Make an unused local variable to avoid warning from gcc compiler. - size_t count = ::write(_fd, s, (int)len); + ssize_t count = ::write(_fd, s, (int)len); update_position(s, len); } } @@ -1079,7 +1079,7 @@ networkStream::networkStream() : bufferedStream(1024*10, 1024*10) { _socket = -1; - int result = os::socket(AF_INET, SOCK_STREAM, 0); + int result = ::socket(AF_INET, SOCK_STREAM, 0); if (result <= 0) { assert(false, "Socket could not be created!"); } else { diff --git a/src/hotspot/share/utilities/quickSort.hpp b/src/hotspot/share/utilities/quickSort.hpp index 000f1bf4f4283bb65361d4358d6ca30ff3a751c0..a94a7cd8b6ce14d601f1a60236b2731c6dbd683a 100644 --- a/src/hotspot/share/utilities/quickSort.hpp +++ b/src/hotspot/share/utilities/quickSort.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_UTILITIES_QUICKSORT_HPP #define SHARE_UTILITIES_QUICKSORT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/globals.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/utilities/stringUtils.cpp b/src/hotspot/share/utilities/stringUtils.cpp index 21fb7a6e8d32e7428679ce915cb1189ba9c2e683..0ee73de809a9ecba6840809064a53ccdc6909484 100644 --- a/src/hotspot/share/utilities/stringUtils.cpp +++ b/src/hotspot/share/utilities/stringUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ #include "utilities/debug.hpp" #include "utilities/stringUtils.hpp" +#include + int StringUtils::replace_no_expand(char* string, const char* from, const char* to) { int replace_count = 0; size_t from_len = strlen(from); diff --git a/src/hotspot/share/utilities/stringUtils.hpp b/src/hotspot/share/utilities/stringUtils.hpp index 372222d7c70ff8b00a93b67330c9f172140722e5..54d6847a4c4dfa267ff8f3a6fd442a453022735e 100644 --- a/src/hotspot/share/utilities/stringUtils.hpp +++ b/src/hotspot/share/utilities/stringUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_UTILITIES_STRINGUTILS_HPP #define SHARE_UTILITIES_STRINGUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class StringUtils : AllStatic { public: diff --git a/src/hotspot/share/utilities/utf8.cpp b/src/hotspot/share/utilities/utf8.cpp index 6ebeb9a6c9b21d4f688f60a1b0f02d162ef805a3..81ad02a9ba608efa17a6047998a71ec74b2f108d 100644 --- a/src/hotspot/share/utilities/utf8.cpp +++ b/src/hotspot/share/utilities/utf8.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,12 @@ */ #include "precompiled.hpp" +#include "memory/allocation.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/utf8.hpp" + // Assume the utf8 string is in legal form and has been // checked in the class file parser/format checker. template char* UTF8::next(const char* str, T* value) { diff --git a/src/hotspot/share/utilities/utf8.hpp b/src/hotspot/share/utilities/utf8.hpp index 0ebd65b0658aa60a329a2a29cb35e259c250480d..e7b2905e04614adeed4b6535095207cda2039871 100644 --- a/src/hotspot/share/utilities/utf8.hpp +++ b/src/hotspot/share/utilities/utf8.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,9 @@ #ifndef SHARE_UTILITIES_UTF8_HPP #define SHARE_UTILITIES_UTF8_HPP -#include "memory/allocation.hpp" +#include "jni.h" +#include "memory/allStatic.hpp" +#include "utilities/debug.hpp" // Low-level interface for UTF8 strings diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index 4ae43cedf5215da88c240c1fa05569b0e58940cc..1d72092f8ae6f52592715565f13b9f5a6a18fe5f 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1654,7 +1654,7 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt _current_step_info = ""; if (fd_log > 3) { - close(fd_log); + ::close(fd_log); fd_log = -1; } @@ -1676,7 +1676,7 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt const bool overwrite = false; // We do not overwrite an existing replay file. int fd = prepare_log_file(ReplayDataFile, "replay_pid%p.log", overwrite, buffer, sizeof(buffer)); if (fd != -1) { - FILE* replay_data_file = os::open(fd, "w"); + FILE* replay_data_file = os::fdopen(fd, "w"); if (replay_data_file != NULL) { fileStream replay_data_stream(replay_data_file, /*need_close=*/true); env->dump_replay_data_unsafe(&replay_data_stream); diff --git a/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java b/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java index 1b6fce47fc718bcd282549d492c5dcc32012cceb..6ff8fe4bbf8012d765ebb606bdd803c4bcf15a8c 100644 --- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java +++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,7 @@ class LinuxFileStore int[] majorMinorMicro = new int[3]; int length = Math.min(matches.length, majorMinorMicro.length); for (int i = 0; i < length; i++) { - majorMinorMicro[i] = Integer.valueOf(matches[i]); + majorMinorMicro[i] = Integer.parseInt(matches[i]); } return majorMinorMicro; } diff --git a/src/java.base/macosx/classes/apple/security/KeychainStore.java b/src/java.base/macosx/classes/apple/security/KeychainStore.java index cf97d4e04c0e90a96604197ee3164db16d0b87c1..688d280f83812cde0d5aea750664a2d156b623a0 100644 --- a/src/java.base/macosx/classes/apple/security/KeychainStore.java +++ b/src/java.base/macosx/classes/apple/security/KeychainStore.java @@ -945,7 +945,6 @@ public final class KeychainStore extends KeyStoreSpi { byte[] safeContentsData; ContentInfo safeContents; DerInputStream sci; - byte[] eAlgId = null; sci = new DerInputStream(safeContentsArray[i].toByteArray()); safeContents = new ContentInfo(sci); @@ -984,7 +983,6 @@ public final class KeychainStore extends KeyStoreSpi { ObjectIdentifier bagId; DerInputStream sbi; DerValue bagValue; - Object bagItem = null; sbi = safeBags[i].toDerInputStream(); bagId = sbi.getOID(); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java b/src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java index 20af0c78309c70f0d45084b8b292820845865bd4..738b34d3aeb41b0d46526f32a6ecce12ec3f0045 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,7 +108,7 @@ final class BlockCipherParamsCore { T getParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (IvParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(IvParameterSpec.class)) { return paramSpec.cast(new IvParameterSpec(this.iv)); } else { throw new InvalidParameterSpecException diff --git a/src/java.base/share/classes/com/sun/crypto/provider/BlowfishCrypt.java b/src/java.base/share/classes/com/sun/crypto/provider/BlowfishCrypt.java index f5483f7deff51dfc93b8d808aa6708ff7c7e37de..5fde830e519fa337945343e42ba1883fdc668258 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/BlowfishCrypt.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/BlowfishCrypt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ final class BlowfishCrypt extends SymmetricCipher throw new InvalidKeyException("Key too long (> 448 bits)"); } // Step 1: Init P and then S arrays from pi bytes - int i, j, count; + int i, j; System.arraycopy(pi, 0, p, 0, 18); System.arraycopy(pi, 18, s0, 0, 256); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Poly1305Parameters.java b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Poly1305Parameters.java index ad31fb6f6914fd74e4dbf96b9fb84e55b808953f..762827d0152ff705411f67be7affd0123c01fd6e 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Poly1305Parameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Poly1305Parameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -147,7 +147,7 @@ public final class ChaCha20Poly1305Parameters extends AlgorithmParametersSpi { T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (IvParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(IvParameterSpec.class)) { return paramSpec.cast(new IvParameterSpec(nonce)); } else { throw new InvalidParameterSpecException diff --git a/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java b/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java index 93eede032f1a586c73f500d6c616f7bee389c1d5..64ce01c53ab5bd6a11d370ab7e749bf558bb681a 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -812,10 +812,13 @@ final class CipherCore { if (outputCapacity < estOutSize) { cipher.save(); } - // create temporary output buffer if the estimated size is larger - // than the user-provided buffer. - internalOutput = new byte[estOutSize]; - offset = 0; + if (outputCapacity < estOutSize || padding != null) { + // create temporary output buffer if the estimated size is larger + // than the user-provided buffer or a padding needs to be removed + // before copying the unpadded result to the output buffer + internalOutput = new byte[estOutSize]; + offset = 0; + } } byte[] outBuffer = (internalOutput != null) ? internalOutput : output; diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DHParameters.java b/src/java.base/share/classes/com/sun/crypto/provider/DHParameters.java index da3129805b635d36597f1828cf8aa3ec6fa4270c..859c64dc4054266f76328f6ba38a64f452ab27e0 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DHParameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DHParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,7 +98,7 @@ public final class DHParameters extends AlgorithmParametersSpi { T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (DHParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(DHParameterSpec.class)) { return paramSpec.cast(new DHParameterSpec(this.p, this.g, this.l)); } else { throw new InvalidParameterSpecException diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GCMParameters.java b/src/java.base/share/classes/com/sun/crypto/provider/GCMParameters.java index 911ccc558241bc9b9a2de463bf7d807523e88fb2..8060ca9b7de4d59b9f2b2f448a1cac2bd98f90e4 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/GCMParameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/GCMParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,7 +107,7 @@ public final class GCMParameters extends AlgorithmParametersSpi { T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (GCMParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(GCMParameterSpec.class)) { return paramSpec.cast(new GCMParameterSpec(tLen * 8, iv)); } else { throw new InvalidParameterSpecException diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java index 728d463068e198bf4b39079e4ac8f17579bb5bc5..635061d613126bf83732f331ed811ee015277cb2 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java @@ -1304,7 +1304,7 @@ abstract class GaloisCounterMode extends CipherSpi { // 'len' includes ibuffer data checkDataLength(len, tagLenBytes); if (dst.remaining() < len + tagLenBytes) { - throw new ShortBufferException("Output buffer too small, must" + + throw new ShortBufferException("Output buffer too small, must " + "be at least " + (len + tagLenBytes) + " bytes long"); } @@ -1472,7 +1472,7 @@ abstract class GaloisCounterMode extends CipherSpi { } if (len - tagLenBytes > out.length - outOfs) { - throw new ShortBufferException("Output buffer too small, must" + + throw new ShortBufferException("Output buffer too small, must " + "be at least " + (len - tagLenBytes) + " bytes long"); } diff --git a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java index b13a1a905d7ccf1091b26ceb0863ab2530c66cb3..570aca63e09b241d407dcdf63dde12055e173822 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java @@ -177,6 +177,10 @@ final class KeyProtector { byte[] encodedParams = encrInfo.getAlgorithm().getEncodedParams(); + if (encodedParams == null) { + throw new IOException("Missing PBE parameters"); + } + // parse the PBE parameters into the corresponding spec AlgorithmParameters pbeParams = AlgorithmParameters.getInstance("PBE"); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java b/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java index bdb1da97b63c7f52315fa5340671463f15ba9d9a..d8bf4386455ead620155807c1c266154f1852ab4 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,8 +107,12 @@ public final class OAEPParameters extends AlgorithmParametersSpi { if (!val.getOID().equals(OID_MGF1)) { throw new IOException("Only MGF1 mgf is supported"); } + byte[] encodedParams = val.getEncodedParams(); + if (encodedParams == null) { + throw new IOException("Missing MGF1 parameters"); + } AlgorithmId params = AlgorithmId.parse( - new DerValue(val.getEncodedParams())); + new DerValue(encodedParams)); mgfSpec = switch (params.getName()) { case "SHA-1" -> MGF1ParameterSpec.SHA1; case "SHA-224" -> MGF1ParameterSpec.SHA224; @@ -129,7 +133,12 @@ public final class OAEPParameters extends AlgorithmParametersSpi { if (!val.getOID().equals(OID_PSpecified)) { throw new IOException("Wrong OID for pSpecified"); } - p = DerValue.wrap(val.getEncodedParams()).getOctetString(); + byte[] encodedParams = val.getEncodedParams(); + if (encodedParams == null) { + throw new IOException("Missing pSpecified label"); + } + + p = DerValue.wrap(encodedParams).getOctetString(); } else { p = new byte[0]; } @@ -148,7 +157,7 @@ public final class OAEPParameters extends AlgorithmParametersSpi { protected T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (OAEPParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(OAEPParameterSpec.class)) { return paramSpec.cast( new OAEPParameterSpec(mdName, "MGF1", mgfSpec, new PSource.PSpecified(p))); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java b/src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java index ea2dfbf31aed646f6d1ef3781b31345f2548bf37..ed09fe94118bcd50a3682eec9218d1110e864e4b 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java @@ -243,7 +243,7 @@ abstract class PBEKeyFactory extends SecretKeyFactorySpi { // Check if requested key spec is amongst the valid ones if ((keySpecCl != null) - && PBEKeySpec.class.isAssignableFrom(keySpecCl)) { + && keySpecCl.isAssignableFrom(PBEKeySpec.class)) { byte[] passwdBytes = key.getEncoded(); char[] passwdChars = new char[passwdBytes.length]; for (int i=0; i paramSpec) throws InvalidParameterSpecException { - if (PBEParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(PBEParameterSpec.class)) { return paramSpec.cast( new PBEParameterSpec(this.salt, this.iCount, this.cipherParam)); } else { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java b/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java index a26c95b16d3703960700b709fd830cd11932e391..4e3c7e44a3837beb2ec5e27e5098e9db82404f73 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -334,7 +334,7 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi { T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (PBEParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(PBEParameterSpec.class)) { return paramSpec.cast( new PBEParameterSpec(this.salt, this.iCount, this.cipherParam)); } else { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2Core.java b/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2Core.java index 87207c778ecb43e3684219296d0ffdcac46a7c92..c9e754685828e51c2cecd8b1c4699da019723616 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2Core.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2Core.java @@ -92,7 +92,7 @@ abstract class PBKDF2Core extends SecretKeyFactorySpi { if (key instanceof javax.crypto.interfaces.PBEKey) { // Check if requested key spec is amongst the valid ones if ((keySpecCl != null) - && PBEKeySpec.class.isAssignableFrom(keySpecCl)) { + && keySpecCl.isAssignableFrom(PBEKeySpec.class)) { javax.crypto.interfaces.PBEKey pKey = (javax.crypto.interfaces.PBEKey) key; char[] passwd = pKey.getPassword(); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2HmacSHA1Factory.java b/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2HmacSHA1Factory.java deleted file mode 100644 index d8070e968b66e18625173781a95221a0c4c55a42..0000000000000000000000000000000000000000 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2HmacSHA1Factory.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.crypto.provider; - -import java.security.InvalidKeyException; -import java.security.spec.KeySpec; -import java.security.spec.InvalidKeySpecException; -import java.util.Arrays; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactorySpi; -import javax.crypto.spec.PBEKeySpec; - -/** - * This class implements a key factory for PBE keys derived using - * PBKDF2 with HmacSHA1 psuedo random function(PRF) as defined in - * PKCS#5 v2.0. - * - * @author Valerie Peng - * - */ -public final class PBKDF2HmacSHA1Factory extends SecretKeyFactorySpi { - - /** - * Empty constructor - */ - public PBKDF2HmacSHA1Factory() { - } - - /** - * Generates a SecretKey object from the provided key - * specification (key material). - * - * @param keySpec the specification (key material) of the secret key - * - * @return the secret key - * - * @exception InvalidKeySpecException if the given key specification - * is inappropriate for this key factory to produce a public key. - */ - protected SecretKey engineGenerateSecret(KeySpec keySpec) - throws InvalidKeySpecException - { - if (!(keySpec instanceof PBEKeySpec)) { - throw new InvalidKeySpecException("Invalid key spec"); - } - PBEKeySpec ks = (PBEKeySpec) keySpec; - return new PBKDF2KeyImpl(ks, "HmacSHA1"); - } - - /** - * Returns a specification (key material) of the given key - * in the requested format. - * - * @param key the key - * - * @param keySpecCl the requested format in which the key material shall be - * returned - * - * @return the underlying key specification (key material) in the - * requested format - * - * @exception InvalidKeySpecException if the requested key - * specification is inappropriate for the given key, or the - * given key cannot be processed (e.g., the given key has an - * unrecognized algorithm or format). - */ - protected KeySpec engineGetKeySpec(SecretKey key, Class keySpecCl) - throws InvalidKeySpecException { - if (key instanceof javax.crypto.interfaces.PBEKey) { - // Check if requested key spec is amongst the valid ones - if ((keySpecCl != null) - && PBEKeySpec.class.isAssignableFrom(keySpecCl)) { - javax.crypto.interfaces.PBEKey pKey = - (javax.crypto.interfaces.PBEKey) key; - char[] passwd = pKey.getPassword(); - byte[] encoded = pKey.getEncoded(); - try { - return new PBEKeySpec(passwd, pKey.getSalt(), - pKey.getIterationCount(), encoded.length * 8); - } finally { - if (passwd != null) { - Arrays.fill(passwd, (char) 0); - } - Arrays.fill(encoded, (byte)0); - } - } else { - throw new InvalidKeySpecException("Invalid key spec"); - } - } else { - throw new InvalidKeySpecException("Invalid key " + - "format/algorithm"); - } - } - - /** - * Translates a SecretKey object, whose provider may be - * unknown or potentially untrusted, into a corresponding - * SecretKey object of this key factory. - * - * @param key the key whose provider is unknown or untrusted - * - * @return the translated key - * - * @exception InvalidKeyException if the given key cannot be processed by - * this key factory. - */ - protected SecretKey engineTranslateKey(SecretKey key) - throws InvalidKeyException { - if ((key != null) && - (key.getAlgorithm().equalsIgnoreCase("PBKDF2WithHmacSHA1")) && - (key.getFormat().equalsIgnoreCase("RAW"))) { - - // Check if key originates from this factory - if (key instanceof com.sun.crypto.provider.PBKDF2KeyImpl) { - return key; - } - // Check if key implements the PBEKey - if (key instanceof javax.crypto.interfaces.PBEKey) { - javax.crypto.interfaces.PBEKey pKey = - (javax.crypto.interfaces.PBEKey) key; - char[] password = pKey.getPassword(); - byte[] encoding = pKey.getEncoded(); - PBEKeySpec spec = - new PBEKeySpec(password, - pKey.getSalt(), - pKey.getIterationCount(), - encoding.length*8); - try { - return new PBKDF2KeyImpl(spec, "HmacSHA1"); - } catch (InvalidKeySpecException re) { - throw new InvalidKeyException - ("Invalid key component(s)", re); - } finally { - if (password != null) { - Arrays.fill(password, (char) 0); - spec.clearPassword(); - } - Arrays.fill(encoding, (byte)0); - } - } - } - throw new InvalidKeyException("Invalid key format/algorithm"); - } -} diff --git a/src/java.base/share/classes/com/sun/crypto/provider/RC2Parameters.java b/src/java.base/share/classes/com/sun/crypto/provider/RC2Parameters.java index e33ab101d707844eaae6fb19c3d0ff60ba64ea4f..919e1e7b2e93aef78b7400228ae23c4d434c7762 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/RC2Parameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/RC2Parameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,7 +180,7 @@ public final class RC2Parameters extends AlgorithmParametersSpi { T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (RC2ParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(RC2ParameterSpec.class)) { return paramSpec.cast((iv == null ? new RC2ParameterSpec(effectiveKeySize) : new RC2ParameterSpec(effectiveKeySize, iv))); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java index be1535d9a2b9ba5e508f787ece49367fb443e369..56e4dd976632aae8d3be0646cd2a3dd9530e6688 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java @@ -213,7 +213,7 @@ public final class TlsKeyMaterialGenerator extends KeyGeneratorSpi { if (protocolVersion >= 0x0302) { // TLS 1.1+ throw new RuntimeException( - "Internal Error: TLS 1.1+ should not be negotiating" + + "Internal Error: TLS 1.1+ should not be negotiating " + "exportable ciphersuites"); } else if (protocolVersion == 0x0301) { // TLS 1.0 diff --git a/src/java.base/share/classes/java/io/ClassCache.java b/src/java.base/share/classes/java/io/ClassCache.java new file mode 100644 index 0000000000000000000000000000000000000000..48e7a36c05ab60bbeed37a9ab40adfa111e4d192 --- /dev/null +++ b/src/java.base/share/classes/java/io/ClassCache.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.util.Objects; + +// Maps Class instances to values of type T. Under memory pressure, the +// mapping is released (under soft references GC policy) and would be +// recomputed the next time it is queried. The mapping is bound to the +// lifetime of the class: when the class is unloaded, the mapping is +// removed too. +abstract class ClassCache { + + private static class CacheRef extends SoftReference { + private final Class type; + private T strongReferent; + + CacheRef(T referent, ReferenceQueue queue, Class type) { + super(referent, queue); + this.type = type; + this.strongReferent = referent; + } + + Class getType() { + return type; + } + + T getStrong() { + return strongReferent; + } + + void clearStrong() { + strongReferent = null; + } + } + + private final ReferenceQueue queue; + private final ClassValue> map; + + protected abstract T computeValue(Class cl); + + protected ClassCache() { + queue = new ReferenceQueue<>(); + map = new ClassValue<>() { + @Override + protected CacheRef computeValue(Class type) { + T v = ClassCache.this.computeValue(type); + Objects.requireNonNull(v); + return new CacheRef<>(v, queue, type); + } + }; + } + + T get(Class cl) { + while (true) { + processQueue(); + + CacheRef ref = map.get(cl); + + // Case 1: A recently created CacheRef. + // We might still have strong referent, and can return it. + // This guarantees progress for at least one thread on every CacheRef. + // Clear the strong referent before returning to make the cache soft. + T strongVal = ref.getStrong(); + if (strongVal != null) { + ref.clearStrong(); + return strongVal; + } + + // Case 2: Older or recently cleared CacheRef. + // Check if its soft referent is still available, and return it. + T val = ref.get(); + if (val != null) { + return val; + } + + // Case 3: The reference was cleared. + // Clear the mapping and retry. + map.remove(cl); + } + } + + private void processQueue() { + Reference ref; + while((ref = queue.poll()) != null) { + CacheRef cacheRef = (CacheRef)ref; + map.remove(cacheRef.getType()); + } + } +} diff --git a/src/java.base/share/classes/java/io/DataInput.java b/src/java.base/share/classes/java/io/DataInput.java index b8088ff78da2a6ee43839a670b49543327ebf00e..9fdc6bbaf52f68234dda4c96d93b5725ddf2fcdb 100644 --- a/src/java.base/share/classes/java/io/DataInput.java +++ b/src/java.base/share/classes/java/io/DataInput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -493,7 +493,7 @@ public interface DataInput { * is encountered, it is discarded and reading * ceases. If the character {@code '\r'} * is encountered, it is discarded and, if - * the following byte converts to the + * the following byte converts to the * character {@code '\n'}, then that is * discarded also; reading then ceases. If * end of file is encountered before either diff --git a/src/java.base/share/classes/java/io/FilenameFilter.java b/src/java.base/share/classes/java/io/FilenameFilter.java index fcd81479ee12eaa4ad2e1a4a1d8caa1138039daa..43e041d546d0d1b3bd2ea5f305163f7bac4e478e 100644 --- a/src/java.base/share/classes/java/io/FilenameFilter.java +++ b/src/java.base/share/classes/java/io/FilenameFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,11 +34,12 @@ package java.io; * * @author Arthur van Hoff * @author Jonathan Payne - * @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter) + * @see java.desktop/java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter) * @see java.io.File * @see java.io.File#list(java.io.FilenameFilter) * @since 1.0 */ +@SuppressWarnings("doclint:reference") // cross-module links @FunctionalInterface public interface FilenameFilter { /** diff --git a/src/java.base/share/classes/java/io/ObjectInputFilter.java b/src/java.base/share/classes/java/io/ObjectInputFilter.java index d5cae8043b1b9eacf0b4aeeb8020ad1f95bd96ab..3ec164f5aea891b5d48efc493a546aa9e2ab7741 100644 --- a/src/java.base/share/classes/java/io/ObjectInputFilter.java +++ b/src/java.base/share/classes/java/io/ObjectInputFilter.java @@ -27,7 +27,6 @@ package java.io; import jdk.internal.access.SharedSecrets; import jdk.internal.util.StaticProperty; -import sun.security.action.GetBooleanAction; import java.lang.reflect.InvocationTargetException; import java.security.AccessController; @@ -523,10 +522,15 @@ public interface ObjectInputFilter { * {@systemProperty jdk.serialFilter}, its value is used to configure the filter. * If the system property is not defined, and the {@link java.security.Security} property * {@code jdk.serialFilter} is defined then it is used to configure the filter. - * The filter is created as if {@link #createFilter(String) createFilter} is called; - * if the filter string is invalid, an {@link ExceptionInInitializerError} is thrown. - * Otherwise, the filter is not configured during initialization and - * can be set with {@link #setSerialFilter(ObjectInputFilter) Config.setSerialFilter}. + * The filter is created as if {@link #createFilter(String) createFilter} is called, + * if the filter string is invalid the initialization fails and subsequent attempts to + * {@linkplain Config#getSerialFilter() get the filter}, {@linkplain Config#setSerialFilter set a filter}, + * or create an {@linkplain ObjectInputStream#ObjectInputStream(InputStream) ObjectInputStream} + * throw {@link IllegalStateException}. Deserialization is not possible with an + * invalid serial filter. + * If the system property {@code jdk.serialFilter} or the {@link java.security.Security} + * property {@code jdk.serialFilter} is not set the filter can be set with + * {@link #setSerialFilter(ObjectInputFilter) Config.setSerialFilter}. * Setting the {@code jdk.serialFilter} with {@link System#setProperty(String, String) * System.setProperty} does not set the filter. * The syntax for the property value is the same as for the @@ -545,9 +549,12 @@ public interface ObjectInputFilter { *

The class must be public, must have a public zero-argument constructor, implement the * {@link BinaryOperator {@literal BinaryOperator}} interface, provide its implementation and * be accessible via the {@linkplain ClassLoader#getSystemClassLoader() application class loader}. - * If the filter factory constructor is not invoked successfully, an {@link ExceptionInInitializerError} - * is thrown and subsequent use of the filter factory for deserialization fails with - * {@link IllegalStateException}. + * If the filter factory constructor is not invoked successfully subsequent attempts to + * {@linkplain Config#getSerialFilterFactory() get the factory}, + * {@linkplain Config#setSerialFilterFactory(BinaryOperator) set the factory}, or create an + * {@link ObjectInputStream#ObjectInputStream(InputStream) ObjectInputStream} + * throw {@link IllegalStateException}. Deserialization is not possible with an + * invalid serial filter factory. * The filter factory configured using the system or security property during initialization * can NOT be replaced with {@link #setSerialFilterFactory(BinaryOperator) Config.setSerialFilterFactory}. * This ensures that a filter factory set on the command line is not overridden accidentally @@ -582,12 +589,22 @@ public interface ObjectInputFilter { */ private static volatile ObjectInputFilter serialFilter; + /** + * Saved message if the jdk.serialFilter property is invalid. + */ + private static final String invalidFilterMessage; + /** * Current serial filter factory. * @see Config#setSerialFilterFactory(BinaryOperator) */ private static volatile BinaryOperator serialFilterFactory; + /** + * Saved message if the jdk.serialFilterFactory property is invalid. + */ + private static final String invalidFactoryMessage; + /** * Boolean to indicate that the filter factory can not be set or replaced. * - an ObjectInputStream has already been created using the current filter factory @@ -630,23 +647,24 @@ public interface ObjectInputFilter { Security.getProperty(SERIAL_FILTER_PROPNAME)); // Initialize the static filter if the jdk.serialFilter is present - ObjectInputFilter filter = null; + String filterMessage = null; if (filterString != null) { configLog.log(DEBUG, "Creating deserialization filter from {0}", filterString); try { - filter = createFilter(filterString); + serialFilter = createFilter(filterString); } catch (RuntimeException re) { configLog.log(ERROR, "Error configuring filter: {0}", (Object) re); - // Do not continue if configuration not initialized - throw re; + // serialFilter remains null + filterMessage = "Invalid jdk.serialFilter: " + re.getMessage(); } } - serialFilter = filter; + invalidFilterMessage = filterMessage; // Initialize the filter factory if the jdk.serialFilterFactory is defined // otherwise use the builtin filter factory. + String factoryMessage = null; if (factoryClassName == null) { serialFilterFactory = new BuiltinFilterFactory(); } else { @@ -671,10 +689,13 @@ public interface ObjectInputFilter { Throwable th = (ex instanceof InvocationTargetException ite) ? ite.getCause() : ex; configLog.log(ERROR, "Error configuring filter factory: {0}", (Object)th); - // Do not continue if configuration not initialized - throw new ExceptionInInitializerError(th); + // Configuration not initialized + // serialFilterFactory remains null and filterFactoryNoReplace == true; + factoryMessage = "invalid jdk.serialFilterFactory: " + + factoryClassName + ": " + th.getClass().getName() + ": " + th.getMessage(); } } + invalidFactoryMessage = factoryMessage; // Setup shared secrets for RegistryImpl to use. SharedSecrets.setJavaObjectInputFilterAccess(Config::createFilter2); } @@ -696,8 +717,14 @@ public interface ObjectInputFilter { * Returns the static JVM-wide deserialization filter or {@code null} if not configured. * * @return the static JVM-wide deserialization filter or {@code null} if not configured + * @throws IllegalStateException if the initialization of the filter from the + * system property {@code jdk.serialFilter} or + * the security property {@code jdk.serialFilter} fails. */ public static ObjectInputFilter getSerialFilter() { + if (invalidFilterMessage != null) { + throw new IllegalStateException(invalidFilterMessage); + } return serialFilter; } @@ -707,7 +734,9 @@ public interface ObjectInputFilter { * @param filter the deserialization filter to set as the JVM-wide filter; not null * @throws SecurityException if there is security manager and the * {@code SerializablePermission("serialFilter")} is not granted - * @throws IllegalStateException if the filter has already been set + * @throws IllegalStateException if the filter has already been set or the initialization + * of the filter from the system property {@code jdk.serialFilter} or + * the security property {@code jdk.serialFilter} fails. */ public static void setSerialFilter(ObjectInputFilter filter) { Objects.requireNonNull(filter, "filter"); @@ -716,6 +745,9 @@ public interface ObjectInputFilter { if (sm != null) { sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION); } + if (invalidFilterMessage != null) { + throw new IllegalStateException(invalidFilterMessage); + } synchronized (serialFilterLock) { if (serialFilter != null) { throw new IllegalStateException("Serial filter can only be set once"); @@ -749,8 +781,10 @@ public interface ObjectInputFilter { * @since 17 */ public static BinaryOperator getSerialFilterFactory() { - if (serialFilterFactory == null) - throw new IllegalStateException("Serial filter factory initialization incomplete"); + if (serialFilterFactory == null) { + // If initializing the factory failed or not yet complete, throw with the message + throw new IllegalStateException(invalidFilterFactoryMessage()); + } return serialFilterFactory; } @@ -812,15 +846,26 @@ public interface ObjectInputFilter { } if (filterFactoryNoReplace.getAndSet(true)) { final String msg = serialFilterFactory != null - ? serialFilterFactory.getClass().getName() - : "initialization incomplete"; - throw new IllegalStateException("Cannot replace filter factory: " + msg); + ? "Cannot replace filter factory: " + serialFilterFactory.getClass().getName() + : invalidFilterFactoryMessage(); + throw new IllegalStateException(msg); } configLog.log(DEBUG, "Setting deserialization filter factory to {0}", filterFactory.getClass().getName()); serialFilterFactory = filterFactory; } + /* + * Return message for an invalid filter factory configuration saved from the static init. + * It can be called before the static initializer is complete and has set the message/null. + */ + private static String invalidFilterFactoryMessage() { + assert serialFilterFactory == null; // undefined if a filter factory has been set + return (invalidFactoryMessage != null) + ? invalidFactoryMessage + : "Serial filter factory initialization incomplete"; + } + /** * Returns an ObjectInputFilter from a string of patterns. *

diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java index 5a0978ab382757a8c570c488d9da54020e676335..714785cd117bf67ce0d057dfabdebbdb04152a00 100644 --- a/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,9 @@ package java.io; import java.io.ObjectInputFilter.Config; -import java.io.ObjectStreamClass.WeakClassKey; import java.io.ObjectStreamClass.RecordSupport; import java.lang.System.Logger; import java.lang.invoke.MethodHandle; -import java.lang.ref.ReferenceQueue; import java.lang.reflect.Array; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Modifier; @@ -43,10 +41,6 @@ import java.security.PrivilegedExceptionAction; import java.util.Arrays; import java.util.Map; import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import static java.io.ObjectStreamClass.processQueue; import jdk.internal.access.SharedSecrets; import jdk.internal.event.DeserializationEvent; @@ -282,12 +276,13 @@ public class ObjectInputStream private static class Caches { /** cache of subclass security audit results */ - static final ConcurrentMap subclassAudits = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to audited subclasses */ - static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue<>(); + static final ClassValue subclassAudits = + new ClassValue<>() { + @Override + protected Boolean computeValue(Class type) { + return auditSubclass(type); + } + }; /** * Property to permit setting a filter after objects @@ -382,8 +377,13 @@ public class ObjectInputStream * has written and flushed the header. * *

The constructor initializes the deserialization filter to the filter returned - * by invoking the {@link Config#getSerialFilterFactory()} with {@code null} for the current filter + * by invoking the serial filter factory returned from {@link Config#getSerialFilterFactory()} + * with {@code null} for the current filter * and the {@linkplain Config#getSerialFilter() static JVM-wide filter} for the requested filter. + * If the serial filter or serial filter factory properties are invalid + * an {@link IllegalStateException} is thrown. + * When the filter factory {@code apply} method is invoked it may throw a runtime exception + * preventing the {@code ObjectInputStream} from being constructed. * *

If a security manager is installed, this constructor will check for * the "enableSubclassImplementation" SerializablePermission when invoked @@ -396,6 +396,8 @@ public class ObjectInputStream * @throws IOException if an I/O error occurs while reading stream header * @throws SecurityException if untrusted subclass illegally overrides * security-sensitive methods + * @throws IllegalStateException if the initialization of {@link ObjectInputFilter.Config} + * fails due to invalid serial filter or serial filter factory properties. * @throws NullPointerException if {@code in} is {@code null} * @see ObjectInputStream#ObjectInputStream() * @see ObjectInputStream#readFields() @@ -419,8 +421,13 @@ public class ObjectInputStream * implementation of ObjectInputStream. * *

The constructor initializes the deserialization filter to the filter returned - * by invoking the {@link Config#getSerialFilterFactory()} with {@code null} for the current filter + * by invoking the serial filter factory returned from {@link Config#getSerialFilterFactory()} + * with {@code null} for the current filter * and the {@linkplain Config#getSerialFilter() static JVM-wide filter} for the requested filter. + * If the serial filter or serial filter factory properties are invalid + * an {@link IllegalStateException} is thrown. + * When the filter factory {@code apply} method is invoked it may throw a runtime exception + * preventing the {@code ObjectInputStream} from being constructed. * *

If there is a security manager installed, this method first calls the * security manager's {@code checkPermission} method with the @@ -431,6 +438,8 @@ public class ObjectInputStream * {@code checkPermission} method denies enabling * subclassing. * @throws IOException if an I/O error occurs while creating this stream + * @throws IllegalStateException if the initialization of {@link ObjectInputFilter.Config} + * fails due to invalid serial filter or serial filter factory properties. * @see SecurityManager#checkPermission * @see java.io.SerializablePermission */ @@ -729,7 +738,7 @@ public class ObjectInputStream * restored a final set of validations can be performed. * * @param obj the object to receive the validation callback. - * @param prio controls the order of callbacks;zero is a good default. + * @param prio controls the order of callbacks; zero is a good default. * Use higher numbers to be called back earlier, lower numbers for * later callbacks. Within a priority, callbacks are processed in * no particular order. @@ -1204,7 +1213,7 @@ public class ObjectInputStream * @throws IOException If other I/O error has occurred. */ public void readFully(byte[] buf, int off, int len) throws IOException { - Objects.checkFromToIndex(off, len, buf.length); + Objects.checkFromIndexSize(off, len, buf.length); bin.readFully(buf, off, len, false); } @@ -1306,6 +1315,8 @@ public class ObjectInputStream *

  • each object reference previously deserialized from the stream * (class is {@code null}, arrayLength is -1), *
  • each regular class (class is not {@code null}, arrayLength is -1), + *
  • each interface class explicitly referenced in the stream + * (it is not called for interfaces implemented by classes in the stream), *
  • each interface of a dynamic proxy and the dynamic proxy class itself * (class is not {@code null}, arrayLength is -1), *
  • each array is filtered using the array type and length of the array @@ -1624,13 +1635,7 @@ public class ObjectInputStream if (sm == null) { return; } - processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); - WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); - Boolean result = Caches.subclassAudits.get(key); - if (result == null) { - result = auditSubclass(cl); - Caches.subclassAudits.putIfAbsent(key, result); - } + boolean result = Caches.subclassAudits.get(cl); if (!result) { sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } @@ -1990,6 +1995,10 @@ public class ObjectInputStream } } catch (ClassNotFoundException ex) { resolveEx = ex; + } catch (IllegalAccessError aie) { + IOException ice = new InvalidClassException(aie.getMessage()); + ice.initCause(aie); + throw ice; } catch (OutOfMemoryError memerr) { IOException ex = new InvalidObjectException("Proxy interface limit exceeded: " + Arrays.toString(ifaces)); @@ -2068,6 +2077,30 @@ public class ObjectInputStream totalObjectRefs++; depth++; desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); + + if (cl != null) { + // Check that serial filtering has been done on the local class descriptor's superclass, + // in case it does not appear in the stream. + + // Find the next super descriptor that has a local class descriptor. + // Descriptors for which there is no local class are ignored. + ObjectStreamClass superLocal = null; + for (ObjectStreamClass sDesc = desc.getSuperDesc(); sDesc != null; sDesc = sDesc.getSuperDesc()) { + if ((superLocal = sDesc.getLocalDesc()) != null) { + break; + } + } + + // Scan local descriptor superclasses for a match with the local descriptor of the super found above. + // For each super descriptor before the match, invoke the serial filter on the class. + // The filter is invoked for each class that has not already been filtered + // but would be filtered if the instance had been serialized by this Java runtime. + for (ObjectStreamClass lDesc = desc.getLocalDesc().getSuperDesc(); + lDesc != null && lDesc != superLocal; + lDesc = lDesc.getSuperDesc()) { + filterCheck(lDesc.forClass(), -1); + } + } } finally { depth--; } @@ -2526,6 +2559,13 @@ public class ObjectInputStream throw new InternalError(); } clear(); + // Check that an object follows the TC_EXCEPTION typecode + byte tc = bin.peekByte(); + if (tc != TC_OBJECT && + tc != TC_REFERENCE) { + throw new StreamCorruptedException( + String.format("invalid type code: %02X", tc)); + } return (IOException) readObject0(Object.class, false); } diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java index 2a4d455c3a042539fa322f984e49c40fb0ff0b79..1ac6f60614f1b8113c937cee2bc4210a76db3458 100644 --- a/src/java.base/share/classes/java/io/ObjectOutputStream.java +++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package java.io; -import java.io.ObjectStreamClass.WeakClassKey; -import java.lang.ref.ReferenceQueue; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -34,9 +32,6 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.StringJoiner; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import static java.io.ObjectStreamClass.processQueue; import sun.reflect.misc.ReflectUtil; /** @@ -177,12 +172,13 @@ public class ObjectOutputStream private static class Caches { /** cache of subclass security audit results */ - static final ConcurrentMap subclassAudits = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to audited subclasses */ - static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue<>(); + static final ClassValue subclassAudits = + new ClassValue<>() { + @Override + protected Boolean computeValue(Class type) { + return auditSubclass(type); + } + }; } /** filter stream for handling block data conversion */ @@ -660,10 +656,11 @@ public class ObjectOutputStream * stream. Subclasses of ObjectOutputStream may override this method to * customize the way in which class descriptors are written to the * serialization stream. The corresponding method in ObjectInputStream, - * {@code readClassDescriptor}, should then be overridden to + * {@link ObjectInputStream#readClassDescriptor readClassDescriptor}, should then be overridden to * reconstitute the class descriptor from its custom stream representation. * By default, this method writes class descriptors according to the format - * defined in the Object Serialization specification. + * defined in the + * Java Object Serialization Specification. * *

    Note that this method will only be called if the ObjectOutputStream * is not using the old serialization stream format (set by calling @@ -1065,13 +1062,7 @@ public class ObjectOutputStream if (sm == null) { return; } - processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); - WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); - Boolean result = Caches.subclassAudits.get(key); - if (result == null) { - result = auditSubclass(cl); - Caches.subclassAudits.putIfAbsent(key, result); - } + boolean result = Caches.subclassAudits.get(cl); if (!result) { sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } diff --git a/src/java.base/share/classes/java/io/ObjectStreamClass.java b/src/java.base/share/classes/java/io/ObjectStreamClass.java index ff8a934a887da31dadb46a7dd62aa7711127c3b1..86ed2b839d13727791114e7cc6f816147243bc97 100644 --- a/src/java.base/share/classes/java/io/ObjectStreamClass.java +++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java @@ -28,10 +28,6 @@ package java.io; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -59,7 +55,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import jdk.internal.misc.Unsafe; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; @@ -108,19 +103,22 @@ public class ObjectStreamClass implements Serializable { private static class Caches { /** cache mapping local classes -> descriptors */ - static final ConcurrentMap> localDescs = - new ConcurrentHashMap<>(); + static final ClassCache localDescs = + new ClassCache<>() { + @Override + protected ObjectStreamClass computeValue(Class type) { + return new ObjectStreamClass(type); + } + }; /** cache mapping field group/local desc pairs -> field reflectors */ - static final ConcurrentMap> reflectors = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to local classes */ - private static final ReferenceQueue> localDescsQueue = - new ReferenceQueue<>(); - /** queue for WeakReferences to field reflectors keys */ - private static final ReferenceQueue> reflectorsQueue = - new ReferenceQueue<>(); + static final ClassCache> reflectors = + new ClassCache<>() { + @Override + protected Map computeValue(Class type) { + return new ConcurrentHashMap<>(); + } + }; } /** class associated with this descriptor (if any) */ @@ -362,136 +360,7 @@ public class ObjectStreamClass implements Serializable { if (!(all || Serializable.class.isAssignableFrom(cl))) { return null; } - processQueue(Caches.localDescsQueue, Caches.localDescs); - WeakClassKey key = new WeakClassKey(cl, Caches.localDescsQueue); - Reference ref = Caches.localDescs.get(key); - Object entry = null; - if (ref != null) { - entry = ref.get(); - } - EntryFuture future = null; - if (entry == null) { - EntryFuture newEntry = new EntryFuture(); - Reference newRef = new SoftReference<>(newEntry); - do { - if (ref != null) { - Caches.localDescs.remove(key, ref); - } - ref = Caches.localDescs.putIfAbsent(key, newRef); - if (ref != null) { - entry = ref.get(); - } - } while (ref != null && entry == null); - if (entry == null) { - future = newEntry; - } - } - - if (entry instanceof ObjectStreamClass) { // check common case first - return (ObjectStreamClass) entry; - } - if (entry instanceof EntryFuture) { - future = (EntryFuture) entry; - if (future.getOwner() == Thread.currentThread()) { - /* - * Handle nested call situation described by 4803747: waiting - * for future value to be set by a lookup() call further up the - * stack will result in deadlock, so calculate and set the - * future value here instead. - */ - entry = null; - } else { - entry = future.get(); - } - } - if (entry == null) { - try { - entry = new ObjectStreamClass(cl); - } catch (Throwable th) { - entry = th; - } - if (future.set(entry)) { - Caches.localDescs.put(key, new SoftReference<>(entry)); - } else { - // nested lookup call already set future - entry = future.get(); - } - } - - if (entry instanceof ObjectStreamClass) { - return (ObjectStreamClass) entry; - } else if (entry instanceof RuntimeException) { - throw (RuntimeException) entry; - } else if (entry instanceof Error) { - throw (Error) entry; - } else { - throw new InternalError("unexpected entry: " + entry); - } - } - - /** - * Placeholder used in class descriptor and field reflector lookup tables - * for an entry in the process of being initialized. (Internal) callers - * which receive an EntryFuture belonging to another thread as the result - * of a lookup should call the get() method of the EntryFuture; this will - * return the actual entry once it is ready for use and has been set(). To - * conserve objects, EntryFutures synchronize on themselves. - */ - private static class EntryFuture { - - private static final Object unset = new Object(); - private final Thread owner = Thread.currentThread(); - private Object entry = unset; - - /** - * Attempts to set the value contained by this EntryFuture. If the - * EntryFuture's value has not been set already, then the value is - * saved, any callers blocked in the get() method are notified, and - * true is returned. If the value has already been set, then no saving - * or notification occurs, and false is returned. - */ - synchronized boolean set(Object entry) { - if (this.entry != unset) { - return false; - } - this.entry = entry; - notifyAll(); - return true; - } - - /** - * Returns the value contained by this EntryFuture, blocking if - * necessary until a value is set. - */ - @SuppressWarnings("removal") - synchronized Object get() { - boolean interrupted = false; - while (entry == unset) { - try { - wait(); - } catch (InterruptedException ex) { - interrupted = true; - } - } - if (interrupted) { - AccessController.doPrivileged( - new PrivilegedAction<>() { - public Void run() { - Thread.currentThread().interrupt(); - return null; - } - } - ); - } - return entry; - } - - /** - * Returns the thread that created this EntryFuture. - */ - Thread getOwner() { - return owner; - } + return Caches.localDescs.get(cl); } /** @@ -2248,82 +2117,39 @@ public class ObjectStreamClass implements Serializable { { // class irrelevant if no fields Class cl = (localDesc != null && fields.length > 0) ? - localDesc.cl : null; - processQueue(Caches.reflectorsQueue, Caches.reflectors); - FieldReflectorKey key = new FieldReflectorKey(cl, fields, - Caches.reflectorsQueue); - Reference ref = Caches.reflectors.get(key); - Object entry = null; - if (ref != null) { - entry = ref.get(); - } - EntryFuture future = null; - if (entry == null) { - EntryFuture newEntry = new EntryFuture(); - Reference newRef = new SoftReference<>(newEntry); - do { - if (ref != null) { - Caches.reflectors.remove(key, ref); - } - ref = Caches.reflectors.putIfAbsent(key, newRef); - if (ref != null) { - entry = ref.get(); - } - } while (ref != null && entry == null); - if (entry == null) { - future = newEntry; - } - } + localDesc.cl : Void.class; - if (entry instanceof FieldReflector) { // check common case first - return (FieldReflector) entry; - } else if (entry instanceof EntryFuture) { - entry = ((EntryFuture) entry).get(); - } else if (entry == null) { - try { - entry = new FieldReflector(matchFields(fields, localDesc)); - } catch (Throwable th) { - entry = th; - } - future.set(entry); - Caches.reflectors.put(key, new SoftReference<>(entry)); - } - - if (entry instanceof FieldReflector) { - return (FieldReflector) entry; - } else if (entry instanceof InvalidClassException) { - throw (InvalidClassException) entry; - } else if (entry instanceof RuntimeException) { - throw (RuntimeException) entry; - } else if (entry instanceof Error) { - throw (Error) entry; - } else { - throw new InternalError("unexpected entry: " + entry); + var clReflectors = Caches.reflectors.get(cl); + var key = new FieldReflectorKey(fields); + var reflector = clReflectors.get(key); + if (reflector == null) { + reflector = new FieldReflector(matchFields(fields, localDesc)); + var oldReflector = clReflectors.putIfAbsent(key, reflector); + if (oldReflector != null) { + reflector = oldReflector; + } } + return reflector; } /** * FieldReflector cache lookup key. Keys are considered equal if they - * refer to the same class and equivalent field formats. + * refer to equivalent field formats. */ - private static class FieldReflectorKey extends WeakReference> { + private static class FieldReflectorKey { private final String[] sigs; private final int hash; - private final boolean nullClass; - FieldReflectorKey(Class cl, ObjectStreamField[] fields, - ReferenceQueue> queue) + FieldReflectorKey(ObjectStreamField[] fields) { - super(cl, queue); - nullClass = (cl == null); sigs = new String[2 * fields.length]; for (int i = 0, j = 0; i < fields.length; i++) { ObjectStreamField f = fields[i]; sigs[j++] = f.getName(); sigs[j++] = f.getSignature(); } - hash = System.identityHashCode(cl) + Arrays.hashCode(sigs); + hash = Arrays.hashCode(sigs); } public int hashCode() { @@ -2331,19 +2157,9 @@ public class ObjectStreamClass implements Serializable { } public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (obj instanceof FieldReflectorKey other) { - Class referent; - return (nullClass ? other.nullClass - : ((referent = get()) != null) && - (other.refersTo(referent))) && - Arrays.equals(sigs, other.sigs); - } else { - return false; - } + return obj == this || + obj instanceof FieldReflectorKey other && + Arrays.equals(sigs, other.sigs); } } @@ -2407,68 +2223,6 @@ public class ObjectStreamClass implements Serializable { return matches; } - /** - * Removes from the specified map any keys that have been enqueued - * on the specified reference queue. - */ - static void processQueue(ReferenceQueue> queue, - ConcurrentMap>, ?> map) - { - Reference> ref; - while((ref = queue.poll()) != null) { - map.remove(ref); - } - } - - /** - * Weak key for Class objects. - * - **/ - static class WeakClassKey extends WeakReference> { - /** - * saved value of the referent's identity hash code, to maintain - * a consistent hash code after the referent has been cleared - */ - private final int hash; - - /** - * Create a new WeakClassKey to the given object, registered - * with a queue. - */ - WeakClassKey(Class cl, ReferenceQueue> refQueue) { - super(cl, refQueue); - hash = System.identityHashCode(cl); - } - - /** - * Returns the identity hash code of the original referent. - */ - public int hashCode() { - return hash; - } - - /** - * Returns true if the given object is this identical - * WeakClassKey instance, or, if this object's referent has not - * been cleared, if the given object is another WeakClassKey - * instance with the identical non-null referent as this one. - */ - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (obj instanceof WeakClassKey) { - Class referent = get(); - return (referent != null) && - (((WeakClassKey) obj).refersTo(referent)); - } else { - return false; - } - } - } - /** * A LRA cache of record deserialization constructors. */ diff --git a/src/java.base/share/classes/java/io/PipedInputStream.java b/src/java.base/share/classes/java/io/PipedInputStream.java index c6034e193cf0fd0abf674e6d4cfc37effcbc20cb..0d733fa4c748a0a939107f26374db5ffba31f82f 100644 --- a/src/java.base/share/classes/java/io/PipedInputStream.java +++ b/src/java.base/share/classes/java/io/PipedInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -222,7 +222,7 @@ public class PipedInputStream extends InputStream { * @param len the maximum number of bytes received * @throws IOException If the pipe is broken, * {@link #connect(java.io.PipedOutputStream) unconnected}, - * closed,or if an I/O error occurs. + * closed, or if an I/O error occurs. */ synchronized void receive(byte[] b, int off, int len) throws IOException { checkStateForReceive(); diff --git a/src/java.base/share/classes/java/io/Serial.java b/src/java.base/share/classes/java/io/Serial.java index 60ba804d3a299bb639b126140a6ae2725a983159..d648f0461593ee18a9531dd08f89ff18559e65d1 100644 --- a/src/java.base/share/classes/java/io/Serial.java +++ b/src/java.base/share/classes/java/io/Serial.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,8 @@ import java.lang.annotation.*; /** * Indicates that an annotated field or method is part of the {@linkplain * Serializable serialization mechanism} defined by the - * Java Object Serialization Specification. This + * + * Java Object Serialization Specification. This * annotation type is intended to allow compile-time checking of * serialization-related declarations, analogous to the checking * enabled by the {@link java.lang.Override} annotation type to diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java index 4a5d9afb5856e415f2cd1bd31a4b10403155057a..92e9b5b43f5688cf3bb9efa575a5de47f8f74fd7 100644 --- a/src/java.base/share/classes/java/lang/Character.java +++ b/src/java.base/share/classes/java/lang/Character.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME; * from the Unicode Consortium at * http://www.unicode.org. *

    - * Character information is based on the Unicode Standard, version 13.0. + * Character information is based on the Unicode Standard, version 14.0. *

    * The Java platform has supported different versions of the Unicode * Standard over time. Upgrades to newer versions of the Unicode Standard @@ -75,6 +75,8 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME; * Unicode version * * + * Java SE 19 + * Unicode 14.0 * Java SE 15 * Unicode 13.0 * Java SE 13 @@ -735,10 +737,10 @@ class Character implements java.io.Serializable, Comparable, Constabl */ public static final class UnicodeBlock extends Subset { /** - * 684 - the expected number of entities + * 696 - the expected number of entities * 0.75 - the default load factor of HashMap */ - private static final int NUM_ENTITIES = 684; + private static final int NUM_ENTITIES = 696; private static Map map = new HashMap<>((int)(NUM_ENTITIES / 0.75f + 1.0f)); @@ -3424,6 +3426,120 @@ class Character implements java.io.Serializable, Comparable, Constabl "CJK UNIFIED IDEOGRAPHS EXTENSION G", "CJKUNIFIEDIDEOGRAPHSEXTENSIONG"); + /** + * Constant for the "Arabic Extended-B" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock ARABIC_EXTENDED_B = + new UnicodeBlock("ARABIC_EXTENDED_B", + "ARABIC EXTENDED-B", + "ARABICEXTENDED-B"); + + /** + * Constant for the "Vithkuqi" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock VITHKUQI = + new UnicodeBlock("VITHKUQI"); + + /** + * Constant for the "Latin Extended-F" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock LATIN_EXTENDED_F = + new UnicodeBlock("LATIN_EXTENDED_F", + "LATIN EXTENDED-F", + "LATINEXTENDED-F"); + + /** + * Constant for the "Old Uyghur" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock OLD_UYGHUR = + new UnicodeBlock("OLD_UYGHUR", + "OLD UYGHUR", + "OLDUYGHUR"); + + /** + * Constant for the "Unified Canadian Aboriginal Syllabics Extended-A" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_A = + new UnicodeBlock("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_A", + "UNIFIED CANADIAN ABORIGINAL SYLLABICS EXTENDED-A", + "UNIFIEDCANADIANABORIGINALSYLLABICSEXTENDED-A"); + + /** + * Constant for the "Cypro-Minoan" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock CYPRO_MINOAN = + new UnicodeBlock("CYPRO_MINOAN", + "CYPRO-MINOAN", + "CYPRO-MINOAN"); + + /** + * Constant for the "Tangsa" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock TANGSA = + new UnicodeBlock("TANGSA"); + + /** + * Constant for the "Kana Extended-B" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock KANA_EXTENDED_B = + new UnicodeBlock("KANA_EXTENDED_B", + "KANA EXTENDED-B", + "KANAEXTENDED-B"); + + /** + * Constant for the "Znamenny Musical Notation" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock ZNAMENNY_MUSICAL_NOTATION = + new UnicodeBlock("ZNAMENNY_MUSICAL_NOTATION", + "ZNAMENNY MUSICAL NOTATION", + "ZNAMENNYMUSICALNOTATION"); + + /** + * Constant for the "Latin Extended-G" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock LATIN_EXTENDED_G = + new UnicodeBlock("LATIN_EXTENDED_G", + "LATIN EXTENDED-G", + "LATINEXTENDED-G"); + + /** + * Constant for the "Toto" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock TOTO = + new UnicodeBlock("TOTO"); + + /** + * Constant for the "Ethiopic Extended-B" Unicode + * character block. + * @since 19 + */ + public static final UnicodeBlock ETHIOPIC_EXTENDED_B = + new UnicodeBlock("ETHIOPIC_EXTENDED_B", + "ETHIOPIC EXTENDED-B", + "ETHIOPICEXTENDED-B"); + private static final int[] blockStarts = { 0x0000, // 0000..007F; Basic Latin 0x0080, // 0080..00FF; Latin-1 Supplement @@ -3445,7 +3561,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x0800, // 0800..083F; Samaritan 0x0840, // 0840..085F; Mandaic 0x0860, // 0860..086F; Syriac Supplement - 0x0870, // unassigned + 0x0870, // 0870..089F; Arabic Extended-B 0x08A0, // 08A0..08FF; Arabic Extended-A 0x0900, // 0900..097F; Devanagari 0x0980, // 0980..09FF; Bengali @@ -3612,9 +3728,11 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x104B0, // 104B0..104FF; Osage 0x10500, // 10500..1052F; Elbasan 0x10530, // 10530..1056F; Caucasian Albanian - 0x10570, // unassigned + 0x10570, // 10570..105BF; Vithkuqi + 0x105C0, // unassigned 0x10600, // 10600..1077F; Linear A - 0x10780, // unassigned + 0x10780, // 10780..107BF; Latin Extended-F + 0x107C0, // unassigned 0x10800, // 10800..1083F; Cypriot Syllabary 0x10840, // 10840..1085F; Imperial Aramaic 0x10860, // 10860..1087F; Palmyrene @@ -3646,7 +3764,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x10EC0, // unassigned 0x10F00, // 10F00..10F2F; Old Sogdian 0x10F30, // 10F30..10F6F; Sogdian - 0x10F70, // unassigned + 0x10F70, // 10F70..10FAF; Old Uyghur 0x10FB0, // 10FB0..10FDF; Chorasmian 0x10FE0, // 10FE0..10FFF; Elymaic 0x11000, // 11000..1107F; Brahmi @@ -3670,8 +3788,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x11660, // 11660..1167F; Mongolian Supplement 0x11680, // 11680..116CF; Takri 0x116D0, // unassigned - 0x11700, // 11700..1173F; Ahom - 0x11740, // unassigned + 0x11700, // 11700..1174F; Ahom + 0x11750, // unassigned 0x11800, // 11800..1184F; Dogra 0x11850, // unassigned 0x118A0, // 118A0..118FF; Warang Citi @@ -3680,7 +3798,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x119A0, // 119A0..119FF; Nandinagari 0x11A00, // 11A00..11A4F; Zanabazar Square 0x11A50, // 11A50..11AAF; Soyombo - 0x11AB0, // unassigned + 0x11AB0, // 11AB0..11ABF; Unified Canadian Aboriginal Syllabics Extended-A 0x11AC0, // 11AC0..11AFF; Pau Cin Hau 0x11B00, // unassigned 0x11C00, // 11C00..11C6F; Bhaiksuki @@ -3697,6 +3815,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x12400, // 12400..1247F; Cuneiform Numbers and Punctuation 0x12480, // 12480..1254F; Early Dynastic Cuneiform 0x12550, // unassigned + 0x12F90, // 12F90..12FFF; Cypro-Minoan 0x13000, // 13000..1342F; Egyptian Hieroglyphs 0x13430, // 13430..1343F; Egyptian Hieroglyph Format Controls 0x13440, // unassigned @@ -3704,7 +3823,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x14680, // unassigned 0x16800, // 16800..16A3F; Bamum Supplement 0x16A40, // 16A40..16A6F; Mro - 0x16A70, // unassigned + 0x16A70, // 16A70..16ACF; Tangsa 0x16AD0, // 16AD0..16AFF; Bassa Vah 0x16B00, // 16B00..16B8F; Pahawh Hmong 0x16B90, // unassigned @@ -3716,8 +3835,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x17000, // 17000..187FF; Tangut 0x18800, // 18800..18AFF; Tangut Components 0x18B00, // 18B00..18CFF; Khitan Small Script - 0x18D00, // 18D00..18D8F; Tangut Supplement - 0x18D90, // unassigned + 0x18D00, // 18D00..18D7F; Tangut Supplement + 0x18D80, // unassigned + 0x1AFF0, // 1AFF0..1AFFF; Kana Extended-B 0x1B000, // 1B000..1B0FF; Kana Supplement 0x1B100, // 1B100..1B12F; Kana Extended-A 0x1B130, // 1B130..1B16F; Small Kana Extension @@ -3726,6 +3846,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1BC00, // 1BC00..1BC9F; Duployan 0x1BCA0, // 1BCA0..1BCAF; Shorthand Format Controls 0x1BCB0, // unassigned + 0x1CF00, // 1CF00..1CFCF; Znamenny Musical Notation + 0x1CFD0, // unassigned 0x1D000, // 1D000..1D0FF; Byzantine Musical Symbols 0x1D100, // 1D100..1D1FF; Musical Symbols 0x1D200, // 1D200..1D24F; Ancient Greek Musical Notation @@ -3737,12 +3859,15 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1D400, // 1D400..1D7FF; Mathematical Alphanumeric Symbols 0x1D800, // 1D800..1DAAF; Sutton SignWriting 0x1DAB0, // unassigned + 0x1DF00, // 1DF00..1DFFF; Latin Extended-G 0x1E000, // 1E000..1E02F; Glagolitic Supplement 0x1E030, // unassigned 0x1E100, // 1E100..1E14F; Nyiakeng Puachue Hmong 0x1E150, // unassigned + 0x1E290, // 1E290..1E2BF; Toto 0x1E2C0, // 1E2C0..1E2FF; Wancho 0x1E300, // unassigned + 0x1E7E0, // 1E7E0..1E7FF; Ethiopic Extended-B 0x1E800, // 1E800..1E8DF; Mende Kikakui 0x1E8E0, // unassigned 0x1E900, // 1E900..1E95F; Adlam @@ -3810,7 +3935,7 @@ class Character implements java.io.Serializable, Comparable, Constabl SAMARITAN, MANDAIC, SYRIAC_SUPPLEMENT, - null, + ARABIC_EXTENDED_B, ARABIC_EXTENDED_A, DEVANAGARI, BENGALI, @@ -3977,8 +4102,10 @@ class Character implements java.io.Serializable, Comparable, Constabl OSAGE, ELBASAN, CAUCASIAN_ALBANIAN, + VITHKUQI, null, LINEAR_A, + LATIN_EXTENDED_F, null, CYPRIOT_SYLLABARY, IMPERIAL_ARAMAIC, @@ -4011,7 +4138,7 @@ class Character implements java.io.Serializable, Comparable, Constabl null, OLD_SOGDIAN, SOGDIAN, - null, + OLD_UYGHUR, CHORASMIAN, ELYMAIC, BRAHMI, @@ -4045,7 +4172,7 @@ class Character implements java.io.Serializable, Comparable, Constabl NANDINAGARI, ZANABAZAR_SQUARE, SOYOMBO, - null, + UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_A, PAU_CIN_HAU, null, BHAIKSUKI, @@ -4062,6 +4189,7 @@ class Character implements java.io.Serializable, Comparable, Constabl CUNEIFORM_NUMBERS_AND_PUNCTUATION, EARLY_DYNASTIC_CUNEIFORM, null, + CYPRO_MINOAN, EGYPTIAN_HIEROGLYPHS, EGYPTIAN_HIEROGLYPH_FORMAT_CONTROLS, null, @@ -4069,7 +4197,7 @@ class Character implements java.io.Serializable, Comparable, Constabl null, BAMUM_SUPPLEMENT, MRO, - null, + TANGSA, BASSA_VAH, PAHAWH_HMONG, null, @@ -4083,6 +4211,7 @@ class Character implements java.io.Serializable, Comparable, Constabl KHITAN_SMALL_SCRIPT, TANGUT_SUPPLEMENT, null, + KANA_EXTENDED_B, KANA_SUPPLEMENT, KANA_EXTENDED_A, SMALL_KANA_EXTENSION, @@ -4091,6 +4220,8 @@ class Character implements java.io.Serializable, Comparable, Constabl DUPLOYAN, SHORTHAND_FORMAT_CONTROLS, null, + ZNAMENNY_MUSICAL_NOTATION, + null, BYZANTINE_MUSICAL_SYMBOLS, MUSICAL_SYMBOLS, ANCIENT_GREEK_MUSICAL_NOTATION, @@ -4102,12 +4233,15 @@ class Character implements java.io.Serializable, Comparable, Constabl MATHEMATICAL_ALPHANUMERIC_SYMBOLS, SUTTON_SIGNWRITING, null, + LATIN_EXTENDED_G, GLAGOLITIC_SUPPLEMENT, null, NYIAKENG_PUACHUE_HMONG, null, + TOTO, WANCHO, null, + ETHIOPIC_EXTENDED_B, MENDE_KIKAKUI, null, ADLAM, @@ -4217,7 +4351,7 @@ class Character implements java.io.Serializable, Comparable, Constabl /** * Returns the UnicodeBlock with the given name. Block * names are determined by The Unicode Standard. The file - * {@code Blocks-.txt} defines blocks for a particular + * {@code Blocks.txt} defines blocks for a particular * version of the standard. The {@link Character} class specifies * the version of the standard that it supports. *

    @@ -5116,6 +5250,36 @@ class Character implements java.io.Serializable, Comparable, Constabl */ KHITAN_SMALL_SCRIPT, + /** + * Unicode script "Vithkuqi". + * @since 19 + */ + VITHKUQI, + + /** + * Unicode script "Old Uyghur". + * @since 19 + */ + OLD_UYGHUR, + + /** + * Unicode script "Cypro Minoan". + * @since 19 + */ + CYPRO_MINOAN, + + /** + * Unicode script "Tangsa". + * @since 19 + */ + TANGSA, + + /** + * Unicode script "Toto". + * @since 19 + */ + TOTO, + /** * Unicode script "Unknown". */ @@ -5185,9 +5349,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x060C, // 060C ; COMMON 0x060D, // 060D..061A; ARABIC 0x061B, // 061B ; COMMON - 0x061C, // 061C ; ARABIC - 0x061D, // 061D ; UNKNOWN - 0x061E, // 061E ; ARABIC + 0x061C, // 061C..061E; ARABIC 0x061F, // 061F ; COMMON 0x0620, // 0620..063F; ARABIC 0x0640, // 0640 ; COMMON @@ -5218,12 +5380,12 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x085E, // 085E ; MANDAIC 0x085F, // 085F ; UNKNOWN 0x0860, // 0860..086A; SYRIAC - 0x086B, // 086B..089F; UNKNOWN - 0x08A0, // 08A0..08B4; ARABIC - 0x08B5, // 08B5 ; UNKNOWN - 0x08B6, // 08B6..08C7; ARABIC - 0x08C8, // 08C8..08D2; UNKNOWN - 0x08D3, // 08D3..08E1; ARABIC + 0x086B, // 086B..086F; UNKNOWN + 0x0870, // 0870..088E; ARABIC + 0x088F, // 088F ; UNKNOWN + 0x0890, // 0890..0891; ARABIC + 0x0892, // 0892..0897; UNKNOWN + 0x0898, // 0898..08E1; ARABIC 0x08E2, // 08E2 ; COMMON 0x08E3, // 08E3..08FF; ARABIC 0x0900, // 0900..0950; DEVANAGARI @@ -5386,8 +5548,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x0C12, // 0C12..0C28; TELUGU 0x0C29, // 0C29 ; UNKNOWN 0x0C2A, // 0C2A..0C39; TELUGU - 0x0C3A, // 0C3A..0C3C; UNKNOWN - 0x0C3D, // 0C3D..0C44; TELUGU + 0x0C3A, // 0C3A..0C3B; UNKNOWN + 0x0C3C, // 0C3C..0C44; TELUGU 0x0C45, // 0C45 ; UNKNOWN 0x0C46, // 0C46..0C48; TELUGU 0x0C49, // 0C49 ; UNKNOWN @@ -5396,7 +5558,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x0C55, // 0C55..0C56; TELUGU 0x0C57, // 0C57 ; UNKNOWN 0x0C58, // 0C58..0C5A; TELUGU - 0x0C5B, // 0C5B..0C5F; UNKNOWN + 0x0C5B, // 0C5B..0C5C; UNKNOWN + 0x0C5D, // 0C5D ; TELUGU + 0x0C5E, // 0C5E..0C5F; UNKNOWN 0x0C60, // 0C60..0C63; TELUGU 0x0C64, // 0C64..0C65; UNKNOWN 0x0C66, // 0C66..0C6F; TELUGU @@ -5419,8 +5583,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x0CCA, // 0CCA..0CCD; KANNADA 0x0CCE, // 0CCE..0CD4; UNKNOWN 0x0CD5, // 0CD5..0CD6; KANNADA - 0x0CD7, // 0CD7..0CDD; UNKNOWN - 0x0CDE, // 0CDE ; KANNADA + 0x0CD7, // 0CD7..0CDC; UNKNOWN + 0x0CDD, // 0CDD..0CDE; KANNADA 0x0CDF, // 0CDF ; UNKNOWN 0x0CE0, // 0CE0..0CE3; KANNADA 0x0CE4, // 0CE4..0CE5; UNKNOWN @@ -5565,10 +5729,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x16EB, // 16EB..16ED; COMMON 0x16EE, // 16EE..16F8; RUNIC 0x16F9, // 16F9..16FF; UNKNOWN - 0x1700, // 1700..170C; TAGALOG - 0x170D, // 170D ; UNKNOWN - 0x170E, // 170E..1714; TAGALOG - 0x1715, // 1715..171F; UNKNOWN + 0x1700, // 1700..1715; TAGALOG + 0x1716, // 1716..171E; UNKNOWN + 0x171F, // 171F ; TAGALOG 0x1720, // 1720..1734; HANUNOO 0x1735, // 1735..1736; COMMON 0x1737, // 1737..173F; UNKNOWN @@ -5590,9 +5753,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1802, // 1802..1803; COMMON 0x1804, // 1804 ; MONGOLIAN 0x1805, // 1805 ; COMMON - 0x1806, // 1806..180E; MONGOLIAN - 0x180F, // 180F ; UNKNOWN - 0x1810, // 1810..1819; MONGOLIAN + 0x1806, // 1806..1819; MONGOLIAN 0x181A, // 181A..181F; UNKNOWN 0x1820, // 1820..1878; MONGOLIAN 0x1879, // 1879..187F; UNKNOWN @@ -5634,12 +5795,12 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1A9A, // 1A9A..1A9F; UNKNOWN 0x1AA0, // 1AA0..1AAD; TAI_THAM 0x1AAE, // 1AAE..1AAF; UNKNOWN - 0x1AB0, // 1AB0..1AC0; INHERITED - 0x1AC1, // 1AC1..1AFF; UNKNOWN - 0x1B00, // 1B00..1B4B; BALINESE - 0x1B4C, // 1B4C..1B4F; UNKNOWN - 0x1B50, // 1B50..1B7C; BALINESE - 0x1B7D, // 1B7D..1B7F; UNKNOWN + 0x1AB0, // 1AB0..1ACE; INHERITED + 0x1ACF, // 1ACF..1AFF; UNKNOWN + 0x1B00, // 1B00..1B4C; BALINESE + 0x1B4D, // 1B4D..1B4F; UNKNOWN + 0x1B50, // 1B50..1B7E; BALINESE + 0x1B7F, // 1B7F ; UNKNOWN 0x1B80, // 1B80..1BBF; SUNDANESE 0x1BC0, // 1BC0..1BF3; BATAK 0x1BF4, // 1BF4..1BFB; UNKNOWN @@ -5681,9 +5842,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1D78, // 1D78 ; CYRILLIC 0x1D79, // 1D79..1DBE; LATIN 0x1DBF, // 1DBF ; GREEK - 0x1DC0, // 1DC0..1DF9; INHERITED - 0x1DFA, // 1DFA ; UNKNOWN - 0x1DFB, // 1DFB..1DFF; INHERITED + 0x1DC0, // 1DC0..1DFF; INHERITED 0x1E00, // 1E00..1EFF; LATIN 0x1F00, // 1F00..1F15; GREEK 0x1F16, // 1F16..1F17; UNKNOWN @@ -5730,8 +5889,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x208F, // 208F ; UNKNOWN 0x2090, // 2090..209C; LATIN 0x209D, // 209D..209F; UNKNOWN - 0x20A0, // 20A0..20BF; COMMON - 0x20C0, // 20C0..20CF; UNKNOWN + 0x20A0, // 20A0..20C0; COMMON + 0x20C1, // 20C1..20CF; UNKNOWN 0x20D0, // 20D0..20F0; INHERITED 0x20F1, // 20F1..20FF; UNKNOWN 0x2100, // 2100..2125; COMMON @@ -5757,10 +5916,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x2B76, // 2B76..2B95; COMMON 0x2B96, // 2B96 ; UNKNOWN 0x2B97, // 2B97..2BFF; COMMON - 0x2C00, // 2C00..2C2E; GLAGOLITIC - 0x2C2F, // 2C2F ; UNKNOWN - 0x2C30, // 2C30..2C5E; GLAGOLITIC - 0x2C5F, // 2C5F ; UNKNOWN + 0x2C00, // 2C00..2C5F; GLAGOLITIC 0x2C60, // 2C60..2C7F; LATIN 0x2C80, // 2C80..2CF3; COPTIC 0x2CF4, // 2CF4..2CF8; UNKNOWN @@ -5795,8 +5951,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x2DD8, // 2DD8..2DDE; ETHIOPIC 0x2DDF, // 2DDF ; UNKNOWN 0x2DE0, // 2DE0..2DFF; CYRILLIC - 0x2E00, // 2E00..2E52; COMMON - 0x2E53, // 2E53..2E7F; UNKNOWN + 0x2E00, // 2E00..2E5D; COMMON + 0x2E5E, // 2E5E..2E7F; UNKNOWN 0x2E80, // 2E80..2E99; HAN 0x2E9A, // 2E9A ; UNKNOWN 0x2E9B, // 2E9B..2EF3; HAN @@ -5847,8 +6003,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x3358, // 3358..33FF; COMMON 0x3400, // 3400..4DBF; HAN 0x4DC0, // 4DC0..4DFF; COMMON - 0x4E00, // 4E00..9FFC; HAN - 0x9FFD, // 9FFD..9FFF; UNKNOWN + 0x4E00, // 4E00..9FFF; HAN 0xA000, // A000..A48C; YI 0xA48D, // A48D..A48F; UNKNOWN 0xA490, // A490..A4C6; YI @@ -5862,11 +6017,15 @@ class Character implements java.io.Serializable, Comparable, Constabl 0xA700, // A700..A721; COMMON 0xA722, // A722..A787; LATIN 0xA788, // A788..A78A; COMMON - 0xA78B, // A78B..A7BF; LATIN - 0xA7C0, // A7C0..A7C1; UNKNOWN - 0xA7C2, // A7C2..A7CA; LATIN - 0xA7CB, // A7CB..A7F4; UNKNOWN - 0xA7F5, // A7F5..A7FF; LATIN + 0xA78B, // A78B..A7CA; LATIN + 0xA7CB, // A7CB..A7CF; UNKNOWN + 0xA7D0, // A7D0..A7D1; LATIN + 0xA7D2, // A7D2 ; UNKNOWN + 0xA7D3, // A7D3 ; LATIN + 0xA7D4, // A7D4 ; UNKNOWN + 0xA7D5, // A7D5..A7D9; LATIN + 0xA7DA, // A7DA..A7F1; UNKNOWN + 0xA7F2, // A7F2..A7FF; LATIN 0xA800, // A800..A82C; SYLOTI_NAGRI 0xA82D, // A82D..A82F; UNKNOWN 0xA830, // A830..A839; COMMON @@ -5954,17 +6113,17 @@ class Character implements java.io.Serializable, Comparable, Constabl 0xFB43, // FB43..FB44; HEBREW 0xFB45, // FB45 ; UNKNOWN 0xFB46, // FB46..FB4F; HEBREW - 0xFB50, // FB50..FBC1; ARABIC - 0xFBC2, // FBC2..FBD2; UNKNOWN + 0xFB50, // FB50..FBC2; ARABIC + 0xFBC3, // FBC3..FBD2; UNKNOWN 0xFBD3, // FBD3..FD3D; ARABIC 0xFD3E, // FD3E..FD3F; COMMON - 0xFD40, // FD40..FD4F; UNKNOWN - 0xFD50, // FD50..FD8F; ARABIC + 0xFD40, // FD40..FD8F; ARABIC 0xFD90, // FD90..FD91; UNKNOWN 0xFD92, // FD92..FDC7; ARABIC - 0xFDC8, // FDC8..FDEF; UNKNOWN - 0xFDF0, // FDF0..FDFD; ARABIC - 0xFDFE, // FDFE..FDFF; UNKNOWN + 0xFDC8, // FDC8..FDCE; UNKNOWN + 0xFDCF, // FDCF ; ARABIC + 0xFDD0, // FDD0..FDEF; UNKNOWN + 0xFDF0, // FDF0..FDFF; ARABIC 0xFE00, // FE00..FE0F; INHERITED 0xFE10, // FE10..FE19; COMMON 0xFE1A, // FE1A..FE1F; UNKNOWN @@ -6071,13 +6230,34 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x10530, // 10530..10563; CAUCASIAN_ALBANIAN 0x10564, // 10564..1056E; UNKNOWN 0x1056F, // 1056F ; CAUCASIAN_ALBANIAN - 0x10570, // 10570..105FF; UNKNOWN + 0x10570, // 10570..1057A; VITHKUQI + 0x1057B, // 1057B ; UNKNOWN + 0x1057C, // 1057C..1058A; VITHKUQI + 0x1058B, // 1058B ; UNKNOWN + 0x1058C, // 1058C..10592; VITHKUQI + 0x10593, // 10593 ; UNKNOWN + 0x10594, // 10594..10595; VITHKUQI + 0x10596, // 10596 ; UNKNOWN + 0x10597, // 10597..105A1; VITHKUQI + 0x105A2, // 105A2 ; UNKNOWN + 0x105A3, // 105A3..105B1; VITHKUQI + 0x105B2, // 105B2 ; UNKNOWN + 0x105B3, // 105B3..105B9; VITHKUQI + 0x105BA, // 105BA ; UNKNOWN + 0x105BB, // 105BB..105BC; VITHKUQI + 0x105BD, // 105BD..105FF; UNKNOWN 0x10600, // 10600..10736; LINEAR_A 0x10737, // 10737..1073F; UNKNOWN 0x10740, // 10740..10755; LINEAR_A 0x10756, // 10756..1075F; UNKNOWN 0x10760, // 10760..10767; LINEAR_A - 0x10768, // 10768..107FF; UNKNOWN + 0x10768, // 10768..1077F; UNKNOWN + 0x10780, // 10780..10785; LATIN + 0x10786, // 10786 ; UNKNOWN + 0x10787, // 10787..107B0; LATIN + 0x107B1, // 107B1 ; UNKNOWN + 0x107B2, // 107B2..107BA; LATIN + 0x107BB, // 107BB..107FF; UNKNOWN 0x10800, // 10800..10805; CYPRIOT 0x10806, // 10806..10807; UNKNOWN 0x10808, // 10808 ; CYPRIOT @@ -6175,18 +6355,20 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x10F00, // 10F00..10F27; OLD_SOGDIAN 0x10F28, // 10F28..10F2F; UNKNOWN 0x10F30, // 10F30..10F59; SOGDIAN - 0x10F5A, // 10F5A..10FAF; UNKNOWN + 0x10F5A, // 10F5A..10F6F; UNKNOWN + 0x10F70, // 10F70..10F89; OLD_UYGHUR + 0x10F8A, // 10F8A..10FAF; UNKNOWN 0x10FB0, // 10FB0..10FCB; CHORASMIAN 0x10FCC, // 10FCC..10FDF; UNKNOWN 0x10FE0, // 10FE0..10FF6; ELYMAIC 0x10FF7, // 10FF7..10FFF; UNKNOWN 0x11000, // 11000..1104D; BRAHMI 0x1104E, // 1104E..11051; UNKNOWN - 0x11052, // 11052..1106F; BRAHMI - 0x11070, // 11070..1107E; UNKNOWN + 0x11052, // 11052..11075; BRAHMI + 0x11076, // 11076..1107E; UNKNOWN 0x1107F, // 1107F ; BRAHMI - 0x11080, // 11080..110C1; KAITHI - 0x110C2, // 110C2..110CC; UNKNOWN + 0x11080, // 11080..110C2; KAITHI + 0x110C3, // 110C3..110CC; UNKNOWN 0x110CD, // 110CD ; KAITHI 0x110CE, // 110CE..110CF; UNKNOWN 0x110D0, // 110D0..110E8; SORA_SOMPENG @@ -6270,16 +6452,16 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1165A, // 1165A..1165F; UNKNOWN 0x11660, // 11660..1166C; MONGOLIAN 0x1166D, // 1166D..1167F; UNKNOWN - 0x11680, // 11680..116B8; TAKRI - 0x116B9, // 116B9..116BF; UNKNOWN + 0x11680, // 11680..116B9; TAKRI + 0x116BA, // 116BA..116BF; UNKNOWN 0x116C0, // 116C0..116C9; TAKRI 0x116CA, // 116CA..116FF; UNKNOWN 0x11700, // 11700..1171A; AHOM 0x1171B, // 1171B..1171C; UNKNOWN 0x1171D, // 1171D..1172B; AHOM 0x1172C, // 1172C..1172F; UNKNOWN - 0x11730, // 11730..1173F; AHOM - 0x11740, // 11740..117FF; UNKNOWN + 0x11730, // 11730..11746; AHOM + 0x11747, // 11747..117FF; UNKNOWN 0x11800, // 11800..1183B; DOGRA 0x1183C, // 1183C..1189F; UNKNOWN 0x118A0, // 118A0..118F2; WARANG_CITI @@ -6310,7 +6492,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x11A00, // 11A00..11A47; ZANABAZAR_SQUARE 0x11A48, // 11A48..11A4F; UNKNOWN 0x11A50, // 11A50..11AA2; SOYOMBO - 0x11AA3, // 11AA3..11ABF; UNKNOWN + 0x11AA3, // 11AA3..11AAF; UNKNOWN + 0x11AB0, // 11AB0..11ABF; CANADIAN_ABORIGINAL 0x11AC0, // 11AC0..11AF8; PAU_CIN_HAU 0x11AF9, // 11AF9..11BFF; UNKNOWN 0x11C00, // 11C00..11C08; BHAIKSUKI @@ -6367,7 +6550,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x12470, // 12470..12474; CUNEIFORM 0x12475, // 12475..1247F; UNKNOWN 0x12480, // 12480..12543; CUNEIFORM - 0x12544, // 12544..12FFF; UNKNOWN + 0x12544, // 12544..12F8F; UNKNOWN + 0x12F90, // 12F90..12FF2; CYPRO_MINOAN + 0x12FF3, // 12FF3..12FFF; UNKNOWN 0x13000, // 13000..1342E; EGYPTIAN_HIEROGLYPHS 0x1342F, // 1342F ; UNKNOWN 0x13430, // 13430..13438; EGYPTIAN_HIEROGLYPHS @@ -6381,7 +6566,10 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x16A60, // 16A60..16A69; MRO 0x16A6A, // 16A6A..16A6D; UNKNOWN 0x16A6E, // 16A6E..16A6F; MRO - 0x16A70, // 16A70..16ACF; UNKNOWN + 0x16A70, // 16A70..16ABE; TANGSA + 0x16ABF, // 16ABF ; UNKNOWN + 0x16AC0, // 16AC0..16AC9; TANGSA + 0x16ACA, // 16ACA..16ACF; UNKNOWN 0x16AD0, // 16AD0..16AED; BASSA_VAH 0x16AEE, // 16AEE..16AEF; UNKNOWN 0x16AF0, // 16AF0..16AF5; BASSA_VAH @@ -6406,7 +6594,7 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x16FA0, // 16FA0..16FDF; UNKNOWN 0x16FE0, // 16FE0 ; TANGUT 0x16FE1, // 16FE1 ; NUSHU - 0x16FE2, // 16FE2..16FE3; COMMON + 0x16FE2, // 16FE2..16FE3; HAN 0x16FE4, // 16FE4 ; KHITAN_SMALL_SCRIPT 0x16FE5, // 16FE5..16FEF; UNKNOWN 0x16FF0, // 16FF0..16FF1; HAN @@ -6417,10 +6605,17 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x18B00, // 18B00..18CD5; KHITAN_SMALL_SCRIPT 0x18CD6, // 18CD6..18CFF; UNKNOWN 0x18D00, // 18D00..18D08; TANGUT - 0x18D09, // 18D09..1AFFF; UNKNOWN + 0x18D09, // 18D09..1AFEF; UNKNOWN + 0x1AFF0, // 1AFF0..1AFF3; KATAKANA + 0x1AFF4, // 1AFF4 ; UNKNOWN + 0x1AFF5, // 1AFF5..1AFFB; KATAKANA + 0x1AFFC, // 1AFFC ; UNKNOWN + 0x1AFFD, // 1AFFD..1AFFE; KATAKANA + 0x1AFFF, // 1AFFF ; UNKNOWN 0x1B000, // 1B000 ; KATAKANA - 0x1B001, // 1B001..1B11E; HIRAGANA - 0x1B11F, // 1B11F..1B14F; UNKNOWN + 0x1B001, // 1B001..1B11F; HIRAGANA + 0x1B120, // 1B120..1B122; KATAKANA + 0x1B123, // 1B123..1B14F; UNKNOWN 0x1B150, // 1B150..1B152; HIRAGANA 0x1B153, // 1B153..1B163; UNKNOWN 0x1B164, // 1B164..1B167; KATAKANA @@ -6437,7 +6632,13 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1BC9A, // 1BC9A..1BC9B; UNKNOWN 0x1BC9C, // 1BC9C..1BC9F; DUPLOYAN 0x1BCA0, // 1BCA0..1BCA3; COMMON - 0x1BCA4, // 1BCA4..1CFFF; UNKNOWN + 0x1BCA4, // 1BCA4..1CEFF; UNKNOWN + 0x1CF00, // 1CF00..1CF2D; INHERITED + 0x1CF2E, // 1CF2E..1CF2F; UNKNOWN + 0x1CF30, // 1CF30..1CF46; INHERITED + 0x1CF47, // 1CF47..1CF4F; UNKNOWN + 0x1CF50, // 1CF50..1CFC3; COMMON + 0x1CFC4, // 1CFC4..1CFFF; UNKNOWN 0x1D000, // 1D000..1D0F5; COMMON 0x1D0F6, // 1D0F6..1D0FF; UNKNOWN 0x1D100, // 1D100..1D126; COMMON @@ -6450,8 +6651,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1D185, // 1D185..1D18B; INHERITED 0x1D18C, // 1D18C..1D1A9; COMMON 0x1D1AA, // 1D1AA..1D1AD; INHERITED - 0x1D1AE, // 1D1AE..1D1E8; COMMON - 0x1D1E9, // 1D1E9..1D1FF; UNKNOWN + 0x1D1AE, // 1D1AE..1D1EA; COMMON + 0x1D1EB, // 1D1EB..1D1FF; UNKNOWN 0x1D200, // 1D200..1D245; GREEK 0x1D246, // 1D246..1D2DF; UNKNOWN 0x1D2E0, // 1D2E0..1D2F3; COMMON @@ -6506,7 +6707,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1DA9B, // 1DA9B..1DA9F; SIGNWRITING 0x1DAA0, // 1DAA0 ; UNKNOWN 0x1DAA1, // 1DAA1..1DAAF; SIGNWRITING - 0x1DAB0, // 1DAB0..1DFFF; UNKNOWN + 0x1DAB0, // 1DAB0..1DEFF; UNKNOWN + 0x1DF00, // 1DF00..1DF1E; LATIN + 0x1DF1F, // 1DF1F..1DFFF; UNKNOWN 0x1E000, // 1E000..1E006; GLAGOLITIC 0x1E007, // 1E007 ; UNKNOWN 0x1E008, // 1E008..1E018; GLAGOLITIC @@ -6524,11 +6727,21 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1E140, // 1E140..1E149; NYIAKENG_PUACHUE_HMONG 0x1E14A, // 1E14A..1E14D; UNKNOWN 0x1E14E, // 1E14E..1E14F; NYIAKENG_PUACHUE_HMONG - 0x1E150, // 1E150..1E2BF; UNKNOWN + 0x1E150, // 1E150..1E28F; UNKNOWN + 0x1E290, // 1E290..1E2AE; TOTO + 0x1E2AF, // 1E2AF..1E2BF; UNKNOWN 0x1E2C0, // 1E2C0..1E2F9; WANCHO 0x1E2FA, // 1E2FA..1E2FE; UNKNOWN 0x1E2FF, // 1E2FF ; WANCHO - 0x1E300, // 1E300..1E7FF; UNKNOWN + 0x1E300, // 1E300..1E7DF; UNKNOWN + 0x1E7E0, // 1E7E0..1E7E6; ETHIOPIC + 0x1E7E7, // 1E7E7 ; UNKNOWN + 0x1E7E8, // 1E7E8..1E7EB; ETHIOPIC + 0x1E7EC, // 1E7EC ; UNKNOWN + 0x1E7ED, // 1E7ED..1E7EE; ETHIOPIC + 0x1E7EF, // 1E7EF ; UNKNOWN + 0x1E7F0, // 1E7F0..1E7FE; ETHIOPIC + 0x1E7FF, // 1E7FF ; UNKNOWN 0x1E800, // 1E800..1E8C4; MENDE_KIKAKUI 0x1E8C5, // 1E8C5..1E8C6; UNKNOWN 0x1E8C7, // 1E8C7..1E8D6; MENDE_KIKAKUI @@ -6638,8 +6851,8 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1F260, // 1F260..1F265; COMMON 0x1F266, // 1F266..1F2FF; UNKNOWN 0x1F300, // 1F300..1F6D7; COMMON - 0x1F6D8, // 1F6D8..1F6DF; UNKNOWN - 0x1F6E0, // 1F6E0..1F6EC; COMMON + 0x1F6D8, // 1F6D8..1F6DC; UNKNOWN + 0x1F6DD, // 1F6DD..1F6EC; COMMON 0x1F6ED, // 1F6ED..1F6EF; UNKNOWN 0x1F6F0, // 1F6F0..1F6FC; COMMON 0x1F6FD, // 1F6FD..1F6FF; UNKNOWN @@ -6648,7 +6861,9 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1F780, // 1F780..1F7D8; COMMON 0x1F7D9, // 1F7D9..1F7DF; UNKNOWN 0x1F7E0, // 1F7E0..1F7EB; COMMON - 0x1F7EC, // 1F7EC..1F7FF; UNKNOWN + 0x1F7EC, // 1F7EC..1F7EF; UNKNOWN + 0x1F7F0, // 1F7F0 ; COMMON + 0x1F7F1, // 1F7F1..1F7FF; UNKNOWN 0x1F800, // 1F800..1F80B; COMMON 0x1F80C, // 1F80C..1F80F; UNKNOWN 0x1F810, // 1F810..1F847; COMMON @@ -6661,38 +6876,38 @@ class Character implements java.io.Serializable, Comparable, Constabl 0x1F8AE, // 1F8AE..1F8AF; UNKNOWN 0x1F8B0, // 1F8B0..1F8B1; COMMON 0x1F8B2, // 1F8B2..1F8FF; UNKNOWN - 0x1F900, // 1F900..1F978; COMMON - 0x1F979, // 1F979 ; UNKNOWN - 0x1F97A, // 1F97A..1F9CB; COMMON - 0x1F9CC, // 1F9CC ; UNKNOWN - 0x1F9CD, // 1F9CD..1FA53; COMMON + 0x1F900, // 1F900..1FA53; COMMON 0x1FA54, // 1FA54..1FA5F; UNKNOWN 0x1FA60, // 1FA60..1FA6D; COMMON 0x1FA6E, // 1FA6E..1FA6F; UNKNOWN 0x1FA70, // 1FA70..1FA74; COMMON 0x1FA75, // 1FA75..1FA77; UNKNOWN - 0x1FA78, // 1FA78..1FA7A; COMMON - 0x1FA7B, // 1FA7B..1FA7F; UNKNOWN + 0x1FA78, // 1FA78..1FA7C; COMMON + 0x1FA7D, // 1FA7D..1FA7F; UNKNOWN 0x1FA80, // 1FA80..1FA86; COMMON 0x1FA87, // 1FA87..1FA8F; UNKNOWN - 0x1FA90, // 1FA90..1FAA8; COMMON - 0x1FAA9, // 1FAA9..1FAAF; UNKNOWN - 0x1FAB0, // 1FAB0..1FAB6; COMMON - 0x1FAB7, // 1FAB7..1FABF; UNKNOWN - 0x1FAC0, // 1FAC0..1FAC2; COMMON - 0x1FAC3, // 1FAC3..1FACF; UNKNOWN - 0x1FAD0, // 1FAD0..1FAD6; COMMON - 0x1FAD7, // 1FAD7..1FAFF; UNKNOWN + 0x1FA90, // 1FA90..1FAAC; COMMON + 0x1FAAD, // 1FAAD..1FAAF; UNKNOWN + 0x1FAB0, // 1FAB0..1FABA; COMMON + 0x1FABB, // 1FABB..1FABF; UNKNOWN + 0x1FAC0, // 1FAC0..1FAC5; COMMON + 0x1FAC6, // 1FAC6..1FACF; UNKNOWN + 0x1FAD0, // 1FAD0..1FAD9; COMMON + 0x1FADA, // 1FADA..1FADF; UNKNOWN + 0x1FAE0, // 1FAE0..1FAE7; COMMON + 0x1FAE8, // 1FAE8..1FAEF; UNKNOWN + 0x1FAF0, // 1FAF0..1FAF6; COMMON + 0x1FAF7, // 1FAF7..1FAFF; UNKNOWN 0x1FB00, // 1FB00..1FB92; COMMON 0x1FB93, // 1FB93 ; UNKNOWN 0x1FB94, // 1FB94..1FBCA; COMMON 0x1FBCB, // 1FBCB..1FBEF; UNKNOWN 0x1FBF0, // 1FBF0..1FBF9; COMMON 0x1FBFA, // 1FBFA..1FFFF; UNKNOWN - 0x20000, // 20000..2A6DD; HAN - 0x2A6DE, // 2A6DE..2A6FF; UNKNOWN - 0x2A700, // 2A700..2B734; HAN - 0x2B735, // 2B735..2B73F; UNKNOWN + 0x20000, // 20000..2A6DF; HAN + 0x2A6E0, // 2A6E0..2A6FF; UNKNOWN + 0x2A700, // 2A700..2B738; HAN + 0x2B739, // 2B739..2B73F; UNKNOWN 0x2B740, // 2B740..2B81D; HAN 0x2B81E, // 2B81E..2B81F; UNKNOWN 0x2B820, // 2B820..2CEA1; HAN @@ -6775,9 +6990,7 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 060C ARABIC, // 060D..061A COMMON, // 061B - ARABIC, // 061C - UNKNOWN, // 061D - ARABIC, // 061E + ARABIC, // 061C..061E COMMON, // 061F ARABIC, // 0620..063F COMMON, // 0640 @@ -6808,12 +7021,12 @@ class Character implements java.io.Serializable, Comparable, Constabl MANDAIC, // 085E UNKNOWN, // 085F SYRIAC, // 0860..086A - UNKNOWN, // 086B..089F - ARABIC, // 08A0..08B4 - UNKNOWN, // 08B5 - ARABIC, // 08B6..08C7 - UNKNOWN, // 08C8..08D2 - ARABIC, // 08D3..08E1 + UNKNOWN, // 086B..086F + ARABIC, // 0870..088E + UNKNOWN, // 088F + ARABIC, // 0890..0891 + UNKNOWN, // 0892..0897 + ARABIC, // 0898..08E1 COMMON, // 08E2 ARABIC, // 08E3..08FF DEVANAGARI, // 0900..0950 @@ -6976,8 +7189,8 @@ class Character implements java.io.Serializable, Comparable, Constabl TELUGU, // 0C12..0C28 UNKNOWN, // 0C29 TELUGU, // 0C2A..0C39 - UNKNOWN, // 0C3A..0C3C - TELUGU, // 0C3D..0C44 + UNKNOWN, // 0C3A..0C3B + TELUGU, // 0C3C..0C44 UNKNOWN, // 0C45 TELUGU, // 0C46..0C48 UNKNOWN, // 0C49 @@ -6986,7 +7199,9 @@ class Character implements java.io.Serializable, Comparable, Constabl TELUGU, // 0C55..0C56 UNKNOWN, // 0C57 TELUGU, // 0C58..0C5A - UNKNOWN, // 0C5B..0C5F + UNKNOWN, // 0C5B..0C5C + TELUGU, // 0C5D + UNKNOWN, // 0C5E..0C5F TELUGU, // 0C60..0C63 UNKNOWN, // 0C64..0C65 TELUGU, // 0C66..0C6F @@ -7009,8 +7224,8 @@ class Character implements java.io.Serializable, Comparable, Constabl KANNADA, // 0CCA..0CCD UNKNOWN, // 0CCE..0CD4 KANNADA, // 0CD5..0CD6 - UNKNOWN, // 0CD7..0CDD - KANNADA, // 0CDE + UNKNOWN, // 0CD7..0CDC + KANNADA, // 0CDD..0CDE UNKNOWN, // 0CDF KANNADA, // 0CE0..0CE3 UNKNOWN, // 0CE4..0CE5 @@ -7155,10 +7370,9 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 16EB..16ED RUNIC, // 16EE..16F8 UNKNOWN, // 16F9..16FF - TAGALOG, // 1700..170C - UNKNOWN, // 170D - TAGALOG, // 170E..1714 - UNKNOWN, // 1715..171F + TAGALOG, // 1700..1715 + UNKNOWN, // 1716..171E + TAGALOG, // 171F HANUNOO, // 1720..1734 COMMON, // 1735..1736 UNKNOWN, // 1737..173F @@ -7180,9 +7394,7 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 1802..1803 MONGOLIAN, // 1804 COMMON, // 1805 - MONGOLIAN, // 1806..180E - UNKNOWN, // 180F - MONGOLIAN, // 1810..1819 + MONGOLIAN, // 1806..1819 UNKNOWN, // 181A..181F MONGOLIAN, // 1820..1878 UNKNOWN, // 1879..187F @@ -7224,12 +7436,12 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 1A9A..1A9F TAI_THAM, // 1AA0..1AAD UNKNOWN, // 1AAE..1AAF - INHERITED, // 1AB0..1AC0 - UNKNOWN, // 1AC1..1AFF - BALINESE, // 1B00..1B4B - UNKNOWN, // 1B4C..1B4F - BALINESE, // 1B50..1B7C - UNKNOWN, // 1B7D..1B7F + INHERITED, // 1AB0..1ACE + UNKNOWN, // 1ACF..1AFF + BALINESE, // 1B00..1B4C + UNKNOWN, // 1B4D..1B4F + BALINESE, // 1B50..1B7E + UNKNOWN, // 1B7F SUNDANESE, // 1B80..1BBF BATAK, // 1BC0..1BF3 UNKNOWN, // 1BF4..1BFB @@ -7271,9 +7483,7 @@ class Character implements java.io.Serializable, Comparable, Constabl CYRILLIC, // 1D78 LATIN, // 1D79..1DBE GREEK, // 1DBF - INHERITED, // 1DC0..1DF9 - UNKNOWN, // 1DFA - INHERITED, // 1DFB..1DFF + INHERITED, // 1DC0..1DFF LATIN, // 1E00..1EFF GREEK, // 1F00..1F15 UNKNOWN, // 1F16..1F17 @@ -7320,8 +7530,8 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 208F LATIN, // 2090..209C UNKNOWN, // 209D..209F - COMMON, // 20A0..20BF - UNKNOWN, // 20C0..20CF + COMMON, // 20A0..20C0 + UNKNOWN, // 20C1..20CF INHERITED, // 20D0..20F0 UNKNOWN, // 20F1..20FF COMMON, // 2100..2125 @@ -7347,10 +7557,7 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 2B76..2B95 UNKNOWN, // 2B96 COMMON, // 2B97..2BFF - GLAGOLITIC, // 2C00..2C2E - UNKNOWN, // 2C2F - GLAGOLITIC, // 2C30..2C5E - UNKNOWN, // 2C5F + GLAGOLITIC, // 2C00..2C5F LATIN, // 2C60..2C7F COPTIC, // 2C80..2CF3 UNKNOWN, // 2CF4..2CF8 @@ -7385,8 +7592,8 @@ class Character implements java.io.Serializable, Comparable, Constabl ETHIOPIC, // 2DD8..2DDE UNKNOWN, // 2DDF CYRILLIC, // 2DE0..2DFF - COMMON, // 2E00..2E52 - UNKNOWN, // 2E53..2E7F + COMMON, // 2E00..2E5D + UNKNOWN, // 2E5E..2E7F HAN, // 2E80..2E99 UNKNOWN, // 2E9A HAN, // 2E9B..2EF3 @@ -7437,8 +7644,7 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 3358..33FF HAN, // 3400..4DBF COMMON, // 4DC0..4DFF - HAN, // 4E00..9FFC - UNKNOWN, // 9FFD..9FFF + HAN, // 4E00..9FFF YI, // A000..A48C UNKNOWN, // A48D..A48F YI, // A490..A4C6 @@ -7452,11 +7658,15 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // A700..A721 LATIN, // A722..A787 COMMON, // A788..A78A - LATIN, // A78B..A7BF - UNKNOWN, // A7C0..A7C1 - LATIN, // A7C2..A7CA - UNKNOWN, // A7CB..A7F4 - LATIN, // A7F5..A7FF + LATIN, // A78B..A7CA + UNKNOWN, // A7CB..A7CF + LATIN, // A7D0..A7D1 + UNKNOWN, // A7D2 + LATIN, // A7D3 + UNKNOWN, // A7D4 + LATIN, // A7D5..A7D9 + UNKNOWN, // A7DA..A7F1 + LATIN, // A7F2..A7FF SYLOTI_NAGRI, // A800..A82C UNKNOWN, // A82D..A82F COMMON, // A830..A839 @@ -7544,17 +7754,17 @@ class Character implements java.io.Serializable, Comparable, Constabl HEBREW, // FB43..FB44 UNKNOWN, // FB45 HEBREW, // FB46..FB4F - ARABIC, // FB50..FBC1 - UNKNOWN, // FBC2..FBD2 + ARABIC, // FB50..FBC2 + UNKNOWN, // FBC3..FBD2 ARABIC, // FBD3..FD3D COMMON, // FD3E..FD3F - UNKNOWN, // FD40..FD4F - ARABIC, // FD50..FD8F + ARABIC, // FD40..FD8F UNKNOWN, // FD90..FD91 ARABIC, // FD92..FDC7 - UNKNOWN, // FDC8..FDEF - ARABIC, // FDF0..FDFD - UNKNOWN, // FDFE..FDFF + UNKNOWN, // FDC8..FDCE + ARABIC, // FDCF + UNKNOWN, // FDD0..FDEF + ARABIC, // FDF0..FDFF INHERITED, // FE00..FE0F COMMON, // FE10..FE19 UNKNOWN, // FE1A..FE1F @@ -7661,13 +7871,34 @@ class Character implements java.io.Serializable, Comparable, Constabl CAUCASIAN_ALBANIAN, // 10530..10563 UNKNOWN, // 10564..1056E CAUCASIAN_ALBANIAN, // 1056F - UNKNOWN, // 10570..105FF + VITHKUQI, // 10570..1057A + UNKNOWN, // 1057B + VITHKUQI, // 1057C..1058A + UNKNOWN, // 1058B + VITHKUQI, // 1058C..10592 + UNKNOWN, // 10593 + VITHKUQI, // 10594..10595 + UNKNOWN, // 10596 + VITHKUQI, // 10597..105A1 + UNKNOWN, // 105A2 + VITHKUQI, // 105A3..105B1 + UNKNOWN, // 105B2 + VITHKUQI, // 105B3..105B9 + UNKNOWN, // 105BA + VITHKUQI, // 105BB..105BC + UNKNOWN, // 105BD..105FF LINEAR_A, // 10600..10736 UNKNOWN, // 10737..1073F LINEAR_A, // 10740..10755 UNKNOWN, // 10756..1075F LINEAR_A, // 10760..10767 - UNKNOWN, // 10768..107FF + UNKNOWN, // 10768..1077F + LATIN, // 10780..10785 + UNKNOWN, // 10786 + LATIN, // 10787..107B0 + UNKNOWN, // 107B1 + LATIN, // 107B2..107BA + UNKNOWN, // 107BB..107FF CYPRIOT, // 10800..10805 UNKNOWN, // 10806..10807 CYPRIOT, // 10808 @@ -7765,18 +7996,20 @@ class Character implements java.io.Serializable, Comparable, Constabl OLD_SOGDIAN, // 10F00..10F27 UNKNOWN, // 10F28..10F2F SOGDIAN, // 10F30..10F59 - UNKNOWN, // 10F5A..10FAF + UNKNOWN, // 10F5A..10F6F + OLD_UYGHUR, // 10F70..10F89 + UNKNOWN, // 10F8A..10FAF CHORASMIAN, // 10FB0..10FCB UNKNOWN, // 10FCC..10FDF ELYMAIC, // 10FE0..10FF6 UNKNOWN, // 10FF7..10FFF BRAHMI, // 11000..1104D UNKNOWN, // 1104E..11051 - BRAHMI, // 11052..1106F - UNKNOWN, // 11070..1107E + BRAHMI, // 11052..11075 + UNKNOWN, // 11076..1107E BRAHMI, // 1107F - KAITHI, // 11080..110C1 - UNKNOWN, // 110C2..110CC + KAITHI, // 11080..110C2 + UNKNOWN, // 110C3..110CC KAITHI, // 110CD UNKNOWN, // 110CE..110CF SORA_SOMPENG, // 110D0..110E8 @@ -7860,16 +8093,16 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 1165A..1165F MONGOLIAN, // 11660..1166C UNKNOWN, // 1166D..1167F - TAKRI, // 11680..116B8 - UNKNOWN, // 116B9..116BF + TAKRI, // 11680..116B9 + UNKNOWN, // 116BA..116BF TAKRI, // 116C0..116C9 UNKNOWN, // 116CA..116FF AHOM, // 11700..1171A UNKNOWN, // 1171B..1171C AHOM, // 1171D..1172B UNKNOWN, // 1172C..1172F - AHOM, // 11730..1173F - UNKNOWN, // 11740..117FF + AHOM, // 11730..11746 + UNKNOWN, // 11747..117FF DOGRA, // 11800..1183B UNKNOWN, // 1183C..1189F WARANG_CITI, // 118A0..118F2 @@ -7900,7 +8133,8 @@ class Character implements java.io.Serializable, Comparable, Constabl ZANABAZAR_SQUARE, // 11A00..11A47 UNKNOWN, // 11A48..11A4F SOYOMBO, // 11A50..11AA2 - UNKNOWN, // 11AA3..11ABF + UNKNOWN, // 11AA3..11AAF + CANADIAN_ABORIGINAL, // 11AB0..11ABF PAU_CIN_HAU, // 11AC0..11AF8 UNKNOWN, // 11AF9..11BFF BHAIKSUKI, // 11C00..11C08 @@ -7957,7 +8191,9 @@ class Character implements java.io.Serializable, Comparable, Constabl CUNEIFORM, // 12470..12474 UNKNOWN, // 12475..1247F CUNEIFORM, // 12480..12543 - UNKNOWN, // 12544..12FFF + UNKNOWN, // 12544..12F8F + CYPRO_MINOAN, // 12F90..12FF2 + UNKNOWN, // 12FF3..12FFF EGYPTIAN_HIEROGLYPHS, // 13000..1342E UNKNOWN, // 1342F EGYPTIAN_HIEROGLYPHS, // 13430..13438 @@ -7971,7 +8207,10 @@ class Character implements java.io.Serializable, Comparable, Constabl MRO, // 16A60..16A69 UNKNOWN, // 16A6A..16A6D MRO, // 16A6E..16A6F - UNKNOWN, // 16A70..16ACF + TANGSA, // 16A70..16ABE + UNKNOWN, // 16ABF + TANGSA, // 16AC0..16AC9 + UNKNOWN, // 16ACA..16ACF BASSA_VAH, // 16AD0..16AED UNKNOWN, // 16AEE..16AEF BASSA_VAH, // 16AF0..16AF5 @@ -7996,7 +8235,7 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 16FA0..16FDF TANGUT, // 16FE0 NUSHU, // 16FE1 - COMMON, // 16FE2..16FE3 + HAN, // 16FE2..16FE3 KHITAN_SMALL_SCRIPT, // 16FE4 UNKNOWN, // 16FE5..16FEF HAN, // 16FF0..16FF1 @@ -8007,10 +8246,17 @@ class Character implements java.io.Serializable, Comparable, Constabl KHITAN_SMALL_SCRIPT, // 18B00..18CD5 UNKNOWN, // 18CD6..18CFF TANGUT, // 18D00..18D08 - UNKNOWN, // 18D09..1AFFF + UNKNOWN, // 18D09..1AFEF + KATAKANA, // 1AFF0..1AFF3 + UNKNOWN, // 1AFF4 + KATAKANA, // 1AFF5..1AFFB + UNKNOWN, // 1AFFC + KATAKANA, // 1AFFD..1AFFE + UNKNOWN, // 1AFFF KATAKANA, // 1B000 - HIRAGANA, // 1B001..1B11E - UNKNOWN, // 1B11F..1B14F + HIRAGANA, // 1B001..1B11F + KATAKANA, // 1B120..1B122 + UNKNOWN, // 1B123..1B14F HIRAGANA, // 1B150..1B152 UNKNOWN, // 1B153..1B163 KATAKANA, // 1B164..1B167 @@ -8027,7 +8273,13 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 1BC9A..1BC9B DUPLOYAN, // 1BC9C..1BC9F COMMON, // 1BCA0..1BCA3 - UNKNOWN, // 1BCA4..1CFFF + UNKNOWN, // 1BCA4..1CEFF + INHERITED, // 1CF00..1CF2D + UNKNOWN, // 1CF2E..1CF2F + INHERITED, // 1CF30..1CF46 + UNKNOWN, // 1CF47..1CF4F + COMMON, // 1CF50..1CFC3 + UNKNOWN, // 1CFC4..1CFFF COMMON, // 1D000..1D0F5 UNKNOWN, // 1D0F6..1D0FF COMMON, // 1D100..1D126 @@ -8040,8 +8292,8 @@ class Character implements java.io.Serializable, Comparable, Constabl INHERITED, // 1D185..1D18B COMMON, // 1D18C..1D1A9 INHERITED, // 1D1AA..1D1AD - COMMON, // 1D1AE..1D1E8 - UNKNOWN, // 1D1E9..1D1FF + COMMON, // 1D1AE..1D1EA + UNKNOWN, // 1D1EB..1D1FF GREEK, // 1D200..1D245 UNKNOWN, // 1D246..1D2DF COMMON, // 1D2E0..1D2F3 @@ -8096,7 +8348,9 @@ class Character implements java.io.Serializable, Comparable, Constabl SIGNWRITING, // 1DA9B..1DA9F UNKNOWN, // 1DAA0 SIGNWRITING, // 1DAA1..1DAAF - UNKNOWN, // 1DAB0..1DFFF + UNKNOWN, // 1DAB0..1DEFF + LATIN, // 1DF00..1DF1E + UNKNOWN, // 1DF1F..1DFFF GLAGOLITIC, // 1E000..1E006 UNKNOWN, // 1E007 GLAGOLITIC, // 1E008..1E018 @@ -8114,11 +8368,21 @@ class Character implements java.io.Serializable, Comparable, Constabl NYIAKENG_PUACHUE_HMONG, // 1E140..1E149 UNKNOWN, // 1E14A..1E14D NYIAKENG_PUACHUE_HMONG, // 1E14E..1E14F - UNKNOWN, // 1E150..1E2BF + UNKNOWN, // 1E150..1E28F + TOTO, // 1E290..1E2AE + UNKNOWN, // 1E2AF..1E2BF WANCHO, // 1E2C0..1E2F9 UNKNOWN, // 1E2FA..1E2FE WANCHO, // 1E2FF - UNKNOWN, // 1E300..1E7FF + UNKNOWN, // 1E300..1E7DF + ETHIOPIC, // 1E7E0..1E7E6 + UNKNOWN, // 1E7E7 + ETHIOPIC, // 1E7E8..1E7EB + UNKNOWN, // 1E7EC + ETHIOPIC, // 1E7ED..1E7EE + UNKNOWN, // 1E7EF + ETHIOPIC, // 1E7F0..1E7FE + UNKNOWN, // 1E7FF MENDE_KIKAKUI, // 1E800..1E8C4 UNKNOWN, // 1E8C5..1E8C6 MENDE_KIKAKUI, // 1E8C7..1E8D6 @@ -8228,8 +8492,8 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 1F260..1F265 UNKNOWN, // 1F266..1F2FF COMMON, // 1F300..1F6D7 - UNKNOWN, // 1F6D8..1F6DF - COMMON, // 1F6E0..1F6EC + UNKNOWN, // 1F6D8..1F6DC + COMMON, // 1F6DD..1F6EC UNKNOWN, // 1F6ED..1F6EF COMMON, // 1F6F0..1F6FC UNKNOWN, // 1F6FD..1F6FF @@ -8238,7 +8502,9 @@ class Character implements java.io.Serializable, Comparable, Constabl COMMON, // 1F780..1F7D8 UNKNOWN, // 1F7D9..1F7DF COMMON, // 1F7E0..1F7EB - UNKNOWN, // 1F7EC..1F7FF + UNKNOWN, // 1F7EC..1F7EF + COMMON, // 1F7F0 + UNKNOWN, // 1F7F1..1F7FF COMMON, // 1F800..1F80B UNKNOWN, // 1F80C..1F80F COMMON, // 1F810..1F847 @@ -8251,38 +8517,38 @@ class Character implements java.io.Serializable, Comparable, Constabl UNKNOWN, // 1F8AE..1F8AF COMMON, // 1F8B0..1F8B1 UNKNOWN, // 1F8B2..1F8FF - COMMON, // 1F900..1F978 - UNKNOWN, // 1F979 - COMMON, // 1F97A..1F9CB - UNKNOWN, // 1F9CC - COMMON, // 1F9CD..1FA53 + COMMON, // 1F900..1FA53 UNKNOWN, // 1FA54..1FA5F COMMON, // 1FA60..1FA6D UNKNOWN, // 1FA6E..1FA6F COMMON, // 1FA70..1FA74 UNKNOWN, // 1FA75..1FA77 - COMMON, // 1FA78..1FA7A - UNKNOWN, // 1FA7B..1FA7F + COMMON, // 1FA78..1FA7C + UNKNOWN, // 1FA7D..1FA7F COMMON, // 1FA80..1FA86 UNKNOWN, // 1FA87..1FA8F - COMMON, // 1FA90..1FAA8 - UNKNOWN, // 1FAA9..1FAAF - COMMON, // 1FAB0..1FAB6 - UNKNOWN, // 1FAB7..1FABF - COMMON, // 1FAC0..1FAC2 - UNKNOWN, // 1FAC3..1FACF - COMMON, // 1FAD0..1FAD6 - UNKNOWN, // 1FAD7..1FAFF + COMMON, // 1FA90..1FAAC + UNKNOWN, // 1FAAD..1FAAF + COMMON, // 1FAB0..1FABA + UNKNOWN, // 1FABB..1FABF + COMMON, // 1FAC0..1FAC5 + UNKNOWN, // 1FAC6..1FACF + COMMON, // 1FAD0..1FAD9 + UNKNOWN, // 1FADA..1FADF + COMMON, // 1FAE0..1FAE7 + UNKNOWN, // 1FAE8..1FAEF + COMMON, // 1FAF0..1FAF6 + UNKNOWN, // 1FAF7..1FAFF COMMON, // 1FB00..1FB92 UNKNOWN, // 1FB93 COMMON, // 1FB94..1FBCA UNKNOWN, // 1FBCB..1FBEF COMMON, // 1FBF0..1FBF9 UNKNOWN, // 1FBFA..1FFFF - HAN, // 20000..2A6DD - UNKNOWN, // 2A6DE..2A6FF - HAN, // 2A700..2B734 - UNKNOWN, // 2B735..2B73F + HAN, // 20000..2A6DF + UNKNOWN, // 2A6E0..2A6FF + HAN, // 2A700..2B738 + UNKNOWN, // 2B739..2B73F HAN, // 2B740..2B81D UNKNOWN, // 2B81E..2B81F HAN, // 2B820..2CEA1 @@ -8303,7 +8569,7 @@ class Character implements java.io.Serializable, Comparable, Constabl private static final HashMap aliases; static { - aliases = new HashMap<>((int)(157 / 0.75f + 1.0f)); + aliases = new HashMap<>((int)(162 / 0.75f + 1.0f)); aliases.put("ADLM", ADLAM); aliases.put("AGHB", CAUCASIAN_ALBANIAN); aliases.put("AHOM", AHOM); @@ -8329,6 +8595,7 @@ class Character implements java.io.Serializable, Comparable, Constabl aliases.put("CHER", CHEROKEE); aliases.put("CHRS", CHORASMIAN); aliases.put("COPT", COPTIC); + aliases.put("CPMN", CYPRO_MINOAN); aliases.put("CPRT", CYPRIOT); aliases.put("CYRL", CYRILLIC); aliases.put("DEVA", DEVANAGARI); @@ -8409,6 +8676,7 @@ class Character implements java.io.Serializable, Comparable, Constabl aliases.put("ORYA", ORIYA); aliases.put("OSGE", OSAGE); aliases.put("OSMA", OSMANYA); + aliases.put("OUGR", OLD_UYGHUR); aliases.put("PALM", PALMYRENE); aliases.put("PAUC", PAU_CIN_HAU); aliases.put("PERM", OLD_PERMIC); @@ -8451,8 +8719,11 @@ class Character implements java.io.Serializable, Comparable, Constabl aliases.put("THAI", THAI); aliases.put("TIBT", TIBETAN); aliases.put("TIRH", TIRHUTA); + aliases.put("TNSA", TANGSA); + aliases.put("TOTO", TOTO); aliases.put("UGAR", UGARITIC); aliases.put("VAII", VAI); + aliases.put("VITH", VITHKUQI); aliases.put("WARA", WARANG_CITI); aliases.put("WCHO", WANCHO); aliases.put("XPEO", OLD_PERSIAN); @@ -8495,8 +8766,8 @@ class Character implements java.io.Serializable, Comparable, Constabl /** * Returns the UnicodeScript constant with the given Unicode script * name or the script name alias. Script names and their aliases are - * determined by The Unicode Standard. The files {@code Scripts.txt} - * and {@code PropertyValueAliases.txt} define script names + * determined by The Unicode Standard. The files {@code Scripts.txt} + * and {@code PropertyValueAliases.txt} define script names * and the script name aliases for a particular version of the * standard. The {@link Character} class specifies the version of * the standard that it supports. @@ -10031,9 +10302,10 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see Character#isJavaIdentifierPart(char) * @see Character#isLetter(char) * @see Character#isUnicodeIdentifierStart(char) - * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence) + * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.1 */ + @SuppressWarnings("doclint:reference") // cross-module links public static boolean isJavaIdentifierStart(char ch) { return isJavaIdentifierStart((int)ch); } @@ -10060,9 +10332,10 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see Character#isJavaIdentifierPart(int) * @see Character#isLetter(int) * @see Character#isUnicodeIdentifierStart(int) - * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence) + * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.5 */ + @SuppressWarnings("doclint:reference") // cross-module links public static boolean isJavaIdentifierStart(int codePoint) { return CharacterData.of(codePoint).isJavaIdentifierStart(codePoint); } @@ -10097,9 +10370,10 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see Character#isJavaIdentifierStart(char) * @see Character#isLetterOrDigit(char) * @see Character#isUnicodeIdentifierPart(char) - * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence) + * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.1 */ + @SuppressWarnings("doclint:reference") // cross-module links public static boolean isJavaIdentifierPart(char ch) { return isJavaIdentifierPart((int)ch); } @@ -10130,9 +10404,10 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see Character#isJavaIdentifierStart(int) * @see Character#isLetterOrDigit(int) * @see Character#isUnicodeIdentifierPart(int) - * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence) + * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.5 */ + @SuppressWarnings("doclint:reference") // cross-module links public static boolean isJavaIdentifierPart(int codePoint) { return CharacterData.of(codePoint).isJavaIdentifierPart(codePoint); } diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 7eb5256e5e8f4b44493eb40383dd2ffa0a9afa06..fb936b149891d9f3a4cd4a7059dda3d808bd579e 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1582,7 +1582,7 @@ public final class Class implements java.io.Serializable, * representing the class in which it was declared. This method returns * null if this class or interface is not a member of any other class. If * this {@code Class} object represents an array class, a primitive - * type, or void,then this method returns null. + * type, or void, then this method returns null. * * @return the declaring class for this class * @throws SecurityException @@ -2080,6 +2080,7 @@ public final class Class implements java.io.Serializable, * s.checkPackageAccess()} denies access to the package * of this class. * + * @see #getDeclaredConstructors() * @since 1.1 */ @CallerSensitive @@ -2279,7 +2280,9 @@ public final class Class implements java.io.Serializable, * @param parameterTypes the parameter array * @return the {@code Constructor} object of the public constructor that * matches the specified {@code parameterTypes} - * @throws NoSuchMethodException if a matching method is not found. + * @throws NoSuchMethodException if a matching constructor is not found, + * including when this {@code Class} object represents + * an interface, a primitive type, an array class, or void. * @throws SecurityException * If a security manager, s, is present and * the caller's class loader is not the same as or an @@ -2288,6 +2291,7 @@ public final class Class implements java.io.Serializable, * s.checkPackageAccess()} denies access to the package * of this class. * + * @see #getDeclaredConstructor(Class[]) * @since 1.1 */ @CallerSensitive @@ -2536,21 +2540,20 @@ public final class Class implements java.io.Serializable, return copyMethods(privateGetDeclaredMethods(false)); } - /** * Returns an array of {@code Constructor} objects reflecting all the - * constructors declared by the class represented by this + * constructors implicitly or explicitly declared by the class represented by this * {@code Class} object. These are public, protected, default * (package) access, and private constructors. The elements in the array * returned are not sorted and are not in any particular order. If the - * class has a default constructor, it is included in the returned array. + * class has a default constructor (JLS {@jls 8.8.9}), it is included in the returned array. + * If a record class has a canonical constructor (JLS {@jls + * 8.10.4.1}, {@jls 8.10.4.2}), it is included in the returned array. + * * This method returns an array of length 0 if this {@code Class} * object represents an interface, a primitive type, an array class, or * void. * - *

    See The Java Language Specification, - * section {@jls 8.2}. - * * @return the array of {@code Constructor} objects representing all the * declared constructors of this class * @throws SecurityException @@ -2575,6 +2578,7 @@ public final class Class implements java.io.Serializable, * * * @since 1.1 + * @see #getConstructors() * @jls 8.8 Constructor Declarations */ @CallerSensitive @@ -2736,7 +2740,7 @@ public final class Class implements java.io.Serializable, /** * Returns a {@code Constructor} object that reflects the specified - * constructor of the class or interface represented by this + * constructor of the class represented by this * {@code Class} object. The {@code parameterTypes} parameter is * an array of {@code Class} objects that identify the constructor's * formal parameter types, in declared order. @@ -2748,7 +2752,9 @@ public final class Class implements java.io.Serializable, * @param parameterTypes the parameter array * @return The {@code Constructor} object for the constructor with the * specified parameter list - * @throws NoSuchMethodException if a matching method is not found. + * @throws NoSuchMethodException if a matching constructor is not found, + * including when this {@code Class} object represents + * an interface, a primitive type, an array class, or void. * @throws SecurityException * If a security manager, s, is present and any of the * following conditions is met: @@ -2770,6 +2776,7 @@ public final class Class implements java.io.Serializable, * * * + * @see #getConstructor(Class[]) * @since 1.1 */ @CallerSensitive @@ -3820,12 +3827,13 @@ public final class Class implements java.io.Serializable, // Fetches the factory for reflective objects @SuppressWarnings("removal") private static ReflectionFactory getReflectionFactory() { - if (reflectionFactory == null) { - reflectionFactory = - java.security.AccessController.doPrivileged - (new ReflectionFactory.GetReflectionFactoryAction()); + var factory = reflectionFactory; + if (factory != null) { + return factory; } - return reflectionFactory; + return reflectionFactory = + java.security.AccessController.doPrivileged + (new ReflectionFactory.GetReflectionFactoryAction()); } private static ReflectionFactory reflectionFactory; diff --git a/src/java.base/share/classes/java/lang/Enum.java b/src/java.base/share/classes/java/lang/Enum.java index 636ad7c757e471c46c86a8ed4b524880b89387af..55926fc3a40140346cdba684ac16bec060cee482 100644 --- a/src/java.base/share/classes/java/lang/Enum.java +++ b/src/java.base/share/classes/java/lang/Enum.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,8 +51,9 @@ import static java.util.Objects.requireNonNull; * by the serialization mechanism. The serialized representation used * for enum constants cannot be customized. Declarations of methods * and fields that would otherwise interact with serialization are - * ignored, including {@code serialVersionUID}; see the Java - * Object Serialization Specification for details. + * ignored, including {@code serialVersionUID}; see the + * Java + * Object Serialization Specification for details. * *

    Note that when using an enumeration type as the type of a set * or as the type of the keys in a map, specialized and efficient @@ -275,8 +276,13 @@ public abstract class Enum> /** * enum classes cannot have finalize methods. + * + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. */ - @SuppressWarnings("deprecation") + @Deprecated(since="18", forRemoval=true) + @SuppressWarnings("removal") protected final void finalize() { } /** diff --git a/src/java.base/share/classes/java/lang/Integer.java b/src/java.base/share/classes/java/lang/Integer.java index 7d200e7edf531b224cc00c143d748dfbcbab4a91..9ec9d3941f898be8868cd8772a684db155db96c0 100644 --- a/src/java.base/share/classes/java/lang/Integer.java +++ b/src/java.base/share/classes/java/lang/Integer.java @@ -517,13 +517,9 @@ public final class Integer extends Number } // We know there are at most two digits left at this point. - q = i / 10; - r = (q * 10) - i; - buf[--charPos] = (byte)('0' + r); - - // Whatever left is the remaining digit. - if (q < 0) { - buf[--charPos] = (byte)('0' - q); + buf[--charPos] = DigitOnes[-i]; + if (i < -9) { + buf[--charPos] = DigitTens[-i]; } if (negative) { diff --git a/src/java.base/share/classes/java/lang/Long.java b/src/java.base/share/classes/java/lang/Long.java index 630b9e242b89c841e2c0bcb67432db6fd40d1301..2a5a230b321ca1146f0b7cc769d85aaa101600d7 100644 --- a/src/java.base/share/classes/java/lang/Long.java +++ b/src/java.base/share/classes/java/lang/Long.java @@ -565,13 +565,9 @@ public final class Long extends Number } // We know there are at most two digits left at this point. - q2 = i2 / 10; - r = (q2 * 10) - i2; - buf[--charPos] = (byte)('0' + r); - - // Whatever left is the remaining digit. - if (q2 < 0) { - buf[--charPos] = (byte)('0' - q2); + buf[--charPos] = Integer.DigitOnes[-i2]; + if (i2 < -9) { + buf[--charPos] = Integer.DigitTens[-i2]; } if (negative) { diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index b8085b230afb03ebf03ae8c6fbc3b1354deb655c..52028ba99a7c42f53659e9ee45a6b5d4b31357a4 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -478,6 +478,12 @@ public class Object { * A subclass overrides the {@code finalize} method to dispose of * system resources or to perform other cleanup. *

    + * When running in a Java virtual machine in which finalization has been + * disabled or removed, the garbage collector will never call + * {@code finalize()}. In a Java virtual machine in which finalization is + * enabled, the garbage collector might call {@code finalize} only after an + * indefinite delay. + *

    * The general contract of {@code finalize} is that it is invoked * if and when the Java virtual * machine has determined that there is no longer any @@ -543,27 +549,29 @@ public class Object { * } * } * - * @deprecated The finalization mechanism is inherently problematic. - * Finalization can lead to performance issues, deadlocks, and hangs. - * Errors in finalizers can lead to resource leaks; there is no way to cancel - * finalization if it is no longer necessary; and no ordering is specified - * among calls to {@code finalize} methods of different objects. - * Furthermore, there are no guarantees regarding the timing of finalization. - * The {@code finalize} method might be called on a finalizable object - * only after an indefinite delay, if at all. - * - * Classes whose instances hold non-heap resources should provide a method - * to enable explicit release of those resources, and they should also - * implement {@link AutoCloseable} if appropriate. - * The {@link java.lang.ref.Cleaner} and {@link java.lang.ref.PhantomReference} - * provide more flexible and efficient ways to release resources when an object - * becomes unreachable. + * @deprecated Finalization is deprecated and subject to removal in a future + * release. The use of finalization can lead to problems with security, + * performance, and reliability. + * See JEP 421 for + * discussion and alternatives. + *

    + * Subclasses that override {@code finalize} to perform cleanup should use + * alternative cleanup mechanisms and remove the {@code finalize} method. + * Use {@link java.lang.ref.Cleaner} and + * {@link java.lang.ref.PhantomReference} as safer ways to release resources + * when an object becomes unreachable. Alternatively, add a {@code close} + * method to explicitly release resources, and implement + * {@code AutoCloseable} to enable use of the {@code try}-with-resources + * statement. + *

    + * This method will remain in place until finalizers have been removed from + * most existing code. * * @throws Throwable the {@code Exception} raised by this method * @see java.lang.ref.WeakReference * @see java.lang.ref.PhantomReference * @jls 12.6 Finalization of Class Instances */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) protected void finalize() throws Throwable { } } diff --git a/src/java.base/share/classes/java/lang/Runtime.java b/src/java.base/share/classes/java/lang/Runtime.java index 2288aca4d1114e4c839dee525a5e995020885f49..c674880c636170f221a1b0f4c35706fa910e066d 100644 --- a/src/java.base/share/classes/java/lang/Runtime.java +++ b/src/java.base/share/classes/java/lang/Runtime.java @@ -707,8 +707,17 @@ public class Runtime { * The method {@link System#runFinalization()} is the conventional * and convenient means of invoking this method. * + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. + *

    + * When running in a JVM in which finalization has been disabled or removed, + * no objects will be pending finalization, so this method does nothing. + * * @see java.lang.Object#finalize() + * @jls 12.6 Finalization of Class Instances */ + @Deprecated(since="18", forRemoval=true) public void runFinalization() { SharedSecrets.getJavaLangRefAccess().runFinalization(); } diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index abb35ebaeb16cc81bca8404eecfb0c9dd9ac571e..e79884bd4cc62d1d98d43bc05f7b074a18d4519b 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -230,7 +230,7 @@ public final class String * * A String instance is written into an ObjectOutputStream according to * - * Object Serialization Specification, Section 6.2, "Stream Elements" + * Java Object Serialization Specification, Section 6.2, "Stream Elements" */ @java.io.Serial private static final ObjectStreamField[] serialPersistentFields = @@ -541,8 +541,7 @@ public final class String offset++; continue; } - if ((b1 == (byte)0xc2 || b1 == (byte)0xc3) && - offset + 1 < sl) { + if ((b1 & 0xfe) == 0xc2 && offset + 1 < sl) { // b1 either 0xc2 or 0xc3 int b2 = bytes[offset + 1]; if (!isNotContinuation(b2)) { dst[dp++] = (byte)decode2(b1, b2); @@ -698,8 +697,7 @@ public final class String offset++; continue; } - if ((b1 == (byte) 0xc2 || b1 == (byte) 0xc3) && - offset + 1 < sl) { + if ((b1 & 0xfe) == 0xc2 && offset + 1 < sl) { // b1 either 0xc2 or 0xc3 int b2 = bytes[offset + 1]; if (!isNotContinuation(b2)) { dst[dp++] = (byte) decode2(b1, b2); @@ -1284,14 +1282,17 @@ public final class String int sp = 0; int sl = val.length >> 1; byte[] dst = new byte[sl * 3]; - char c; - while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') { + while (sp < sl) { // ascii fast loop; + char c = StringUTF16.getChar(val, sp); + if (c >= '\u0080') { + break; + } dst[dp++] = (byte)c; sp++; } while (sp < sl) { - c = StringUTF16.getChar(val, sp++); + char c = StringUTF16.getChar(val, sp++); if (c < 0x80) { dst[dp++] = (byte)c; } else if (c < 0x800) { diff --git a/src/java.base/share/classes/java/lang/StringBuffer.java b/src/java.base/share/classes/java/lang/StringBuffer.java index e2ca48fdaf6e6ddf7664c6af146e746a06131cd8..1ba12bd29bc2b798dcabebf537d28a8cbe8ca612 100644 --- a/src/java.base/share/classes/java/lang/StringBuffer.java +++ b/src/java.base/share/classes/java/lang/StringBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,12 @@ package java.lang; import java.io.IOException; -import java.util.Arrays; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; +import java.io.Serial; +import java.io.Serializable; +import java.io.StreamCorruptedException; import jdk.internal.vm.annotation.IntrinsicCandidate; /** @@ -106,7 +111,7 @@ import jdk.internal.vm.annotation.IntrinsicCandidate; */ public final class StringBuffer extends AbstractStringBuilder - implements java.io.Serializable, Comparable, CharSequence + implements Serializable, Comparable, CharSequence { /** @@ -116,7 +121,7 @@ import jdk.internal.vm.annotation.IntrinsicCandidate; private transient String toStringCache; /** use serialVersionUID from JDK 1.0.2 for interoperability */ - @java.io.Serial + @Serial static final long serialVersionUID = 3388685877147921107L; /** @@ -725,25 +730,25 @@ import jdk.internal.vm.annotation.IntrinsicCandidate; * A flag indicating whether the backing array is shared. * The value is ignored upon deserialization. */ - @java.io.Serial - private static final java.io.ObjectStreamField[] serialPersistentFields = + @Serial + private static final ObjectStreamField[] serialPersistentFields = { - new java.io.ObjectStreamField("value", char[].class), - new java.io.ObjectStreamField("count", Integer.TYPE), - new java.io.ObjectStreamField("shared", Boolean.TYPE), + new ObjectStreamField("value", char[].class), + new ObjectStreamField("count", Integer.TYPE), + new ObjectStreamField("shared", Boolean.TYPE), }; /** - * The {@code writeObject} method is called to write the state of the {@code StringBuffer} to - * a stream. + * The {@code writeObject} method is called to write the state of the + * {@code StringBuffer} to a stream. * * @param s the {@code ObjectOutputStream} to which data is written * @throws IOException if an I/O error occurs */ - @java.io.Serial - private synchronized void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - java.io.ObjectOutputStream.PutField fields = s.putFields(); + @Serial + private synchronized void writeObject(ObjectOutputStream s) + throws IOException { + ObjectOutputStream.PutField fields = s.putFields(); char[] val = new char[capacity()]; if (isLatin1()) { StringLatin1.getChars(value, 0, count, val, 0); @@ -757,20 +762,26 @@ import jdk.internal.vm.annotation.IntrinsicCandidate; } /** - * The {@code readObject} method is called to restore the state of the {@code StringBuffer} from - * a stream. + * The {@code readObject} method is called to restore the state of the + * {@code StringBuffer} from a stream. * * @param s the {@code ObjectInputStream} from which data is read * @throws IOException if an I/O error occurs * @throws ClassNotFoundException if a serialized class cannot be loaded */ - @java.io.Serial - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - java.io.ObjectInputStream.GetField fields = s.readFields(); + @Serial + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + ObjectInputStream.GetField fields = s.readFields(); + char[] val = (char[])fields.get("value", null); + int c = fields.get("count", 0); + if (c < 0 || c > val.length) { + throw new StreamCorruptedException("count value invalid"); + } initBytes(val, 0, val.length); - count = fields.get("count", 0); + count = c; + // ignore shared field } synchronized void getBytes(byte[] dst, int dstBegin, byte coder) { diff --git a/src/java.base/share/classes/java/lang/StringBuilder.java b/src/java.base/share/classes/java/lang/StringBuilder.java index b22ed99dbfc6b271db37e957826faf2dfa69fe16..8e759c213a9a80ae8631107feb6958c5fcf66bcb 100644 --- a/src/java.base/share/classes/java/lang/StringBuilder.java +++ b/src/java.base/share/classes/java/lang/StringBuilder.java @@ -28,6 +28,10 @@ package java.lang; import jdk.internal.vm.annotation.IntrinsicCandidate; import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serial; +import java.io.StreamCorruptedException; /** * A mutable sequence of characters. This class provides an API compatible @@ -90,7 +94,7 @@ public final class StringBuilder { /** use serialVersionUID for interoperability */ - @java.io.Serial + @Serial static final long serialVersionUID = 4383685877147921099L; /** @@ -464,9 +468,8 @@ public final class StringBuilder * @param s the {@code ObjectOutputStream} to which data is written * @throws IOException if an I/O error occurs */ - @java.io.Serial - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { + @Serial + private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject(); s.writeInt(count); char[] val = new char[capacity()]; @@ -486,13 +489,16 @@ public final class StringBuilder * @throws IOException if an I/O error occurs * @throws ClassNotFoundException if a serialized class cannot be loaded */ - @java.io.Serial - private void readObject(java.io.ObjectInputStream s) - throws IOException, ClassNotFoundException { + @Serial + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { s.defaultReadObject(); - count = s.readInt(); + int c = s.readInt(); char[] val = (char[]) s.readObject(); + if (c < 0 || c > val.length) { + throw new StreamCorruptedException("count value invalid"); + } initBytes(val, 0, val.length); + count = c; } - } diff --git a/src/java.base/share/classes/java/lang/StringUTF16.java b/src/java.base/share/classes/java/lang/StringUTF16.java index 29287aaa22cf1b8bf36af37a8ac7d214edf0fb89..b59b21fd1806205f5992fbe19009b72b1c0e237c 100644 --- a/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/src/java.base/share/classes/java/lang/StringUTF16.java @@ -1549,13 +1549,9 @@ final class StringUTF16 { } // We know there are at most two digits left at this point. - q = i / 10; - r = (q * 10) - i; - putChar(buf, --charPos, '0' + r); - - // Whatever left is the remaining digit. - if (q < 0) { - putChar(buf, --charPos, '0' - q); + putChar(buf, --charPos, Integer.DigitOnes[-i]); + if (i < -9) { + putChar(buf, --charPos, Integer.DigitTens[-i]); } if (negative) { @@ -1604,13 +1600,9 @@ final class StringUTF16 { } // We know there are at most two digits left at this point. - q2 = i2 / 10; - r = (q2 * 10) - i2; - putChar(buf, --charPos, '0' + r); - - // Whatever left is the remaining digit. - if (q2 < 0) { - putChar(buf, --charPos, '0' - q2); + putChar(buf, --charPos, Integer.DigitOnes[-i2]); + if (i2 < -9) { + putChar(buf, --charPos, Integer.DigitTens[-i2]); } if (negative) { diff --git a/src/java.base/share/classes/java/lang/SuppressWarnings.java b/src/java.base/share/classes/java/lang/SuppressWarnings.java index 09ab6c4724b0b21d050eeb10ffcc6a0e25648aec..fd115fb8bef35ace0b2f875a614efa51bc9689ae 100644 --- a/src/java.base/share/classes/java/lang/SuppressWarnings.java +++ b/src/java.base/share/classes/java/lang/SuppressWarnings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,21 +29,52 @@ import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; /** - * Indicates that the named compiler warnings should be suppressed in the - * annotated element (and in all program elements contained in the annotated - * element). Note that the set of warnings suppressed in a given element is - * a superset of the warnings suppressed in all containing elements. For - * example, if you annotate a class to suppress one warning and annotate a - * method to suppress another, both warnings will be suppressed in the method. - * However, note that if a warning is suppressed in a {@code - * module-info} file, the suppression applies to elements within the - * file and not to types contained within the module. + * Indicates the warnings to be suppressed at compile time in the + * annotated element, and in all elements contained in the annotated + * element. * - *

    As a matter of style, programmers should always use this annotation - * on the most deeply nested element where it is effective. If you want to + *

    The {@code SuppressWarnings} annotation interface is applicable + * in all declaration contexts, so an {@code @SuppressWarnings} + * annotation can be used on any element. As a matter of style, + * programmers should always use this annotation on the most deeply + * nested element where it is effective. For example, if you want to * suppress a warning in a particular method, you should annotate that * method rather than its class. * + *

    The set of warnings suppressed in a given element is a union of + * the warnings suppressed in all containing elements. For example, + * if you annotate a class to suppress one warning and annotate a + * method in the class to suppress another, both warnings will be + * suppressed in the method. However, note that if a warning is + * suppressed in a {@code module-info} file, the suppression applies + * to elements within the file and not to types contained + * within the module. Likewise, if a warning is suppressed in a + * {@code package-info} file, the suppression applies to elements + * within the file and not to types contained within the + * package. + * + *

    Java compilers must recognize all the kinds of warnings defined + * in the Java Language Specification (JLS section {@jls + * 9.6.4.5}) which include: + * + *

      + *
    • Unchecked warnings, specified by the string {@code "unchecked"}. + *
    • Deprecation warnings, specified by the string {@code "deprecation"}. + *
    • Removal warnings, specified by the string {@code "removal"}. + *
    • Preview warnings, specified by the string {@code "preview"}. + *
    + * + * Whether or not a Java compiler recognizes other strings is a + * quality of implementation concern. Compiler vendors should + * document the additional warning names they support. Vendors are + * encouraged to cooperate to ensure that the same names work across + * multiple compilers. + * + * @implNote + * In addition to the mandated suppression strings, the {@code javac} + * reference implementation recognizes compilation-related warning + * names documented in its {@code --help-lint} output. + * * @author Josh Bloch * @since 1.5 * @jls 4.8 Raw Types @@ -52,7 +83,7 @@ import static java.lang.annotation.ElementType.*; * @jls 5.5 Casting Contexts * @jls 9.6.4.5 @SuppressWarnings */ -@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE}) +// Implicitly target all declaration contexts by omitting a @Target annotation @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { /** @@ -63,12 +94,6 @@ public @interface SuppressWarnings { * ignore any warning names they do not recognize. They are, however, * free to emit a warning if an annotation contains an unrecognized * warning name. - * - *

    The string {@code "unchecked"} is used to suppress - * unchecked warnings. Compiler vendors should document the - * additional warning names they support in conjunction with this - * annotation type. They are encouraged to cooperate to ensure - * that the same names work across multiple compilers. * @return the set of warnings to be suppressed */ String[] value(); diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 12a8281343319970c74df440dcaa136a34ef1d88..96b32ecabb63e986abe4dc0b28229dab67fb9e64 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1207,7 +1207,7 @@ public final class System { * Severity values and Mapping to {@code java.util.logging.Level}. *

    * {@linkplain System.Logger.Level System logger levels} are mapped to - * {@linkplain java.util.logging.Level java.util.logging levels} + * {@linkplain java.logging/java.util.logging.Level java.util.logging levels} * of corresponding severity. *
    The mapping is as follows: *

    @@ -1219,19 +1219,19 @@ public final class System { * * * {@link Logger.Level#ALL ALL} - * {@link java.util.logging.Level#ALL ALL} + * {@link java.logging/java.util.logging.Level#ALL ALL} * {@link Logger.Level#TRACE TRACE} - * {@link java.util.logging.Level#FINER FINER} + * {@link java.logging/java.util.logging.Level#FINER FINER} * {@link Logger.Level#DEBUG DEBUG} - * {@link java.util.logging.Level#FINE FINE} + * {@link java.logging/java.util.logging.Level#FINE FINE} * {@link Logger.Level#INFO INFO} - * {@link java.util.logging.Level#INFO INFO} + * {@link java.logging/java.util.logging.Level#INFO INFO} * {@link Logger.Level#WARNING WARNING} - * {@link java.util.logging.Level#WARNING WARNING} + * {@link java.logging/java.util.logging.Level#WARNING WARNING} * {@link Logger.Level#ERROR ERROR} - * {@link java.util.logging.Level#SEVERE SEVERE} + * {@link java.logging/java.util.logging.Level#SEVERE SEVERE} * {@link Logger.Level#OFF OFF} - * {@link java.util.logging.Level#OFF OFF} + * {@link java.logging/java.util.logging.Level#OFF OFF} * * * @@ -1240,6 +1240,7 @@ public final class System { * @see java.lang.System.LoggerFinder * @see java.lang.System.Logger */ + @SuppressWarnings("doclint:reference") // cross-module links public enum Level { // for convenience, we're reusing java.util.logging.Level int values @@ -1542,7 +1543,7 @@ public final class System { * {@code java.util.logging} as the backend framework when the * {@code java.logging} module is present. * It returns a {@linkplain System.Logger logger} instance - * that will route log messages to a {@link java.util.logging.Logger + * that will route log messages to a {@link java.logging/java.util.logging.Logger * java.util.logging.Logger}. Otherwise, if {@code java.logging} is not * present, the default implementation will return a simple logger * instance that will route log messages of {@code INFO} level and above to @@ -1556,7 +1557,7 @@ public final class System { * logging backend, and usually requires using APIs specific to that backend. *

    For the default {@code LoggerFinder} implementation * using {@code java.util.logging} as its backend, refer to - * {@link java.util.logging java.util.logging} for logging configuration. + * {@link java.logging/java.util.logging java.util.logging} for logging configuration. * For the default {@code LoggerFinder} implementation returning simple loggers * when the {@code java.logging} module is absent, the configuration * is implementation dependent. @@ -1591,7 +1592,7 @@ public final class System { * System.Logger.Level} to a level supported by the logging backend it uses. *
    The default LoggerFinder using {@code java.util.logging} as the backend * maps {@code System.Logger} levels to - * {@linkplain java.util.logging.Level java.util.logging} levels + * {@linkplain java.logging/java.util.logging.Level java.util.logging} levels * of corresponding severity - as described in {@link Logger.Level * Logger.Level}. * @@ -1600,6 +1601,7 @@ public final class System { * * @since 9 */ + @SuppressWarnings("doclint:reference") // cross-module links public abstract static class LoggerFinder { /** * The {@code RuntimePermission("loggerFinder")} is @@ -1922,8 +1924,18 @@ public final class System { * Runtime.getRuntime().runFinalization() * * + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. + *

    + * When running in a JVM in which finalization has been disabled or removed, + * no objects will be pending finalization, so this method does nothing. + * * @see java.lang.Runtime#runFinalization() + * @jls 12.6 Finalization of Class Instances */ + @Deprecated(since="18", forRemoval=true) + @SuppressWarnings("removal") public static void runFinalization() { Runtime.getRuntime().runFinalization(); } @@ -2321,7 +2333,7 @@ public final class System { public Thread newThreadWithAcc(Runnable target, @SuppressWarnings("removal") AccessControlContext acc) { return new Thread(target, acc); } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") public void invokeFinalize(Object o) throws Throwable { o.finalize(); } diff --git a/src/java.base/share/classes/java/lang/Thread.java b/src/java.base/share/classes/java/lang/Thread.java index 797a7f9f82ec26aa1e1ae87e852d223304ca5e30..0d41973b99e42884622acc54320b818aa963e891 100644 --- a/src/java.base/share/classes/java/lang/Thread.java +++ b/src/java.base/share/classes/java/lang/Thread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,11 @@ package java.lang; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; import java.security.AccessController; import java.security.AccessControlContext; import java.security.PrivilegedAction; import java.util.Map; import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; @@ -1672,16 +1667,15 @@ public class Thread implements Runnable { } /** cache of subclass security audit results */ - /* Replace with ConcurrentReferenceHashMap when/if it appears in a future - * release */ private static class Caches { /** cache of subclass security audit results */ - static final ConcurrentMap subclassAudits = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to audited subclasses */ - static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue<>(); + static final ClassValue subclassAudits = + new ClassValue<>() { + @Override + protected Boolean computeValue(Class type) { + return auditSubclass(type); + } + }; } /** @@ -1694,15 +1688,7 @@ public class Thread implements Runnable { if (cl == Thread.class) return false; - processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); - WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); - Boolean result = Caches.subclassAudits.get(key); - if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); - Caches.subclassAudits.putIfAbsent(key, result); - } - - return result.booleanValue(); + return Caches.subclassAudits.get(cl); } /** @@ -1976,8 +1962,8 @@ public class Thread implements Runnable { * @return the uncaught exception handler for this thread */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { - return uncaughtExceptionHandler != null ? - uncaughtExceptionHandler : group; + UncaughtExceptionHandler handler = this.uncaughtExceptionHandler; + return handler != null ? handler : group; } /** @@ -2008,69 +1994,6 @@ public class Thread implements Runnable { getUncaughtExceptionHandler().uncaughtException(this, e); } - /** - * Removes from the specified map any keys that have been enqueued - * on the specified reference queue. - */ - static void processQueue(ReferenceQueue> queue, - ConcurrentMap>, ?> map) - { - Reference> ref; - while((ref = queue.poll()) != null) { - map.remove(ref); - } - } - - /** - * Weak key for Class objects. - **/ - static class WeakClassKey extends WeakReference> { - /** - * saved value of the referent's identity hash code, to maintain - * a consistent hash code after the referent has been cleared - */ - private final int hash; - - /** - * Create a new WeakClassKey to the given object, registered - * with a queue. - */ - WeakClassKey(Class cl, ReferenceQueue> refQueue) { - super(cl, refQueue); - hash = System.identityHashCode(cl); - } - - /** - * Returns the identity hash code of the original referent. - */ - @Override - public int hashCode() { - return hash; - } - - /** - * Returns true if the given object is this identical - * WeakClassKey instance, or, if this object's referent has not - * been cleared, if the given object is another WeakClassKey - * instance with the identical non-null referent as this one. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - - if (obj instanceof WeakClassKey) { - Class referent = get(); - return (referent != null) && - (((WeakClassKey) obj).refersTo(referent)); - } else { - return false; - } - } - } - - // The following three initially uninitialized fields are exclusively // managed by class java.util.concurrent.ThreadLocalRandom. These // fields are used to build the high-performance PRNGs in the diff --git a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index c687916dde4926ce50b2c70939fd7e0c7a6e056e..ca5bf8a765634b74bfa40cbff616b25b7b250183 100644 --- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -683,6 +683,7 @@ class InvokerBytecodeGenerator { } private static MemberName resolveFrom(String name, MethodType type, Class holder) { + assert(!UNSAFE.shouldBeInitialized(holder)) : holder + "not initialized"; MemberName member = new MemberName(holder, name, type, REF_invokeStatic); MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder, LM_TRUSTED); traceLambdaForm(name, type, holder, resolvedMember); diff --git a/src/java.base/share/classes/java/lang/invoke/MemoryAccessVarHandleBase.java b/src/java.base/share/classes/java/lang/invoke/MemoryAccessVarHandleBase.java index 59098e9fa74dcd720ed825f7397b5de788beefd7..7703c997fc3393788f444a02c04e330f223dbd5e 100644 --- a/src/java.base/share/classes/java/lang/invoke/MemoryAccessVarHandleBase.java +++ b/src/java.base/share/classes/java/lang/invoke/MemoryAccessVarHandleBase.java @@ -50,7 +50,7 @@ abstract class MemoryAccessVarHandleBase extends VarHandle { this.alignmentMask = alignmentMask; } - static IllegalStateException newIllegalStateExceptionForMisalignedAccess(long address) { - return new IllegalStateException("Misaligned access at address: " + address); + static IllegalArgumentException newIllegalArgumentExceptionForMisalignedAccess(long address) { + return new IllegalArgumentException("Misaligned access at address: " + address); } } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java index 4dd2b1fce7ecb5c9a6e2e513db8ad9dd85ded2a4..69d975a7289012e282494d8805571026990ac656 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,11 @@ package java.lang.invoke; import java.lang.reflect.*; import java.security.AccessController; import java.security.PrivilegedAction; + +import jdk.internal.access.JavaLangReflectAccess; +import jdk.internal.access.SharedSecrets; import sun.invoke.WrapperInstance; import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; @@ -88,7 +90,7 @@ public class MethodHandleProxies { * Therefore, each instance must implement a unique single-method interface. * Implementations may not bundle together * multiple single-method interfaces onto single implementation classes - * in the style of {@link java.awt.AWTEventMulticaster}. + * in the style of {@link java.desktop/java.awt.AWTEventMulticaster}. *

    * The method handle may throw an undeclared exception, * which means any checked exception (or other checked throwable) @@ -152,7 +154,8 @@ public class MethodHandleProxies { // entry points, must be covered by hand-written or automatically // generated adapter classes. // - @SuppressWarnings("removal") + @SuppressWarnings({"removal", + "doclint:reference"}) // cross-module links @CallerSensitive public static T asInterfaceInstance(final Class intfc, final MethodHandle target) { if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) @@ -184,8 +187,6 @@ public class MethodHandleProxies { checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class)); vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount()); } - final ConcurrentHashMap defaultMethodMap = - hasDefaultMethods(intfc) ? new ConcurrentHashMap<>() : null; final InvocationHandler ih = new InvocationHandler() { private Object getArg(String name) { if ((Object)name == "getWrapperInstanceTarget") return target; @@ -202,7 +203,8 @@ public class MethodHandleProxies { if (isObjectMethod(method)) return callObjectMethod(proxy, method, args); if (isDefaultMethod(method)) { - return callDefaultMethod(defaultMethodMap, proxy, intfc, method, args); + // no additional access check is performed + return JLRA.invokeDefault(proxy, method, args, null); } throw newInternalError("bad proxy method: "+method); } @@ -292,7 +294,7 @@ public class MethodHandleProxies { private static Object callObjectMethod(Object self, Method m, Object[] args) { assert(isObjectMethod(m)) : m; return switch (m.getName()) { - case "toString" -> self.getClass().getName() + "@" + Integer.toHexString(self.hashCode()); + case "toString" -> java.util.Objects.toIdentityString(self); case "hashCode" -> System.identityHashCode(self); case "equals" -> (self == args[0]); default -> null; @@ -320,37 +322,5 @@ public class MethodHandleProxies { return !Modifier.isAbstract(m.getModifiers()); } - private static boolean hasDefaultMethods(Class intfc) { - for (Method m : intfc.getMethods()) { - if (!isObjectMethod(m) && - !Modifier.isAbstract(m.getModifiers())) { - return true; - } - } - return false; - } - - private static Object callDefaultMethod(ConcurrentHashMap defaultMethodMap, - Object self, Class intfc, Method m, Object[] args) throws Throwable { - assert(isDefaultMethod(m) && !isObjectMethod(m)) : m; - - // Lazily compute the associated method handle from the method - MethodHandle dmh = defaultMethodMap.computeIfAbsent(m, mk -> { - try { - // Look up the default method for special invocation thereby - // avoiding recursive invocation back to the proxy - MethodHandle mh = MethodHandles.Lookup.IMPL_LOOKUP.findSpecial( - intfc, mk.getName(), - MethodType.methodType(mk.getReturnType(), mk.getParameterTypes()), - self.getClass()); - return mh.asSpreader(Object[].class, mk.getParameterCount()); - } catch (NoSuchMethodException | IllegalAccessException e) { - // The method is known to exist and should be accessible, this - // method would not be called unless the invokeinterface to the - // default (public) method passed access control checks - throw new InternalError(e); - } - }); - return dmh.invoke(self, args); - } + private static final JavaLangReflectAccess JLRA = SharedSecrets.getJavaLangReflectAccess(); } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 743ebb6675996de06691fbb2cbded1afef2d46fc..b7d5bde0aebab2f4486065562ae5b7b956b101db 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2002,7 +2002,7 @@ public class MethodHandles { * there is no internal form available to record in any class's constant pool. * A hidden class or interface is not discoverable by {@link Class#forName(String, boolean, ClassLoader)}, * {@link ClassLoader#loadClass(String, boolean)}, or {@link #findClass(String)}, and - * is not {@linkplain java.lang.instrument.Instrumentation#isModifiableClass(Class) + * is not {@linkplain java.instrument/java.lang.instrument.Instrumentation#isModifiableClass(Class) * modifiable} by Java agents or tool agents using the * JVM Tool Interface. * @@ -2105,6 +2105,7 @@ public class MethodHandles { * @jvms 5.5 Initialization * @jls 12.7 Unloading of Classes and Interfaces */ + @SuppressWarnings("doclint:reference") // cross-module links public Lookup defineHiddenClass(byte[] bytes, boolean initialize, ClassOption... options) throws IllegalAccessException { diff --git a/src/java.base/share/classes/java/lang/invoke/X-VarHandleMemoryAccess.java.template b/src/java.base/share/classes/java/lang/invoke/X-VarHandleMemoryAccess.java.template index 0bdfd212e0783a1f22517fad179c350c1e836aee..bdb4904d9942d988fa40668159a71b192ab4acd7 100644 --- a/src/java.base/share/classes/java/lang/invoke/X-VarHandleMemoryAccess.java.template +++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandleMemoryAccess.java.template @@ -106,7 +106,7 @@ final class MemoryAccessVarHandle$Type$Helper extends MemoryAccessVarHandleBase static long offset(boolean skipAlignmentMaskCheck, MemorySegmentProxy bb, long offset, long alignmentMask) { long address = offsetNoVMAlignCheck(skipAlignmentMaskCheck, bb, offset, alignmentMask); if ((address & VM_ALIGN) != 0) { - throw MemoryAccessVarHandleBase.newIllegalStateExceptionForMisalignedAccess(address); + throw MemoryAccessVarHandleBase.newIllegalArgumentExceptionForMisalignedAccess(address); } return address; } @@ -115,14 +115,15 @@ final class MemoryAccessVarHandle$Type$Helper extends MemoryAccessVarHandleBase static long offsetNoVMAlignCheck(boolean skipAlignmentMaskCheck, MemorySegmentProxy bb, long offset, long alignmentMask) { long base = bb.unsafeGetOffset(); long address = base + offset; + long maxAlignMask = bb.maxAlignMask(); if (skipAlignmentMaskCheck) { //note: the offset portion has already been aligned-checked, by construction - if ((base & alignmentMask) != 0) { - throw MemoryAccessVarHandleBase.newIllegalStateExceptionForMisalignedAccess(address); + if (((base | maxAlignMask) & alignmentMask) != 0) { + throw MemoryAccessVarHandleBase.newIllegalArgumentExceptionForMisalignedAccess(address); } } else { - if ((address & alignmentMask) != 0) { - throw MemoryAccessVarHandleBase.newIllegalStateExceptionForMisalignedAccess(address); + if (((address | maxAlignMask) & alignmentMask) != 0) { + throw MemoryAccessVarHandleBase.newIllegalArgumentExceptionForMisalignedAccess(address); } } return address; diff --git a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java index 86ea7602c60639e74c87126e56b5ebf23092e3ca..05b010c18747557d5d0d85eec97c551a964a957d 100644 --- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java +++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java @@ -893,7 +893,8 @@ public class ModuleDescriptor * integer or a string. Tokens are separated by the punctuation characters * {@code '.'}, {@code '-'}, or {@code '+'}, or by transitions from a * sequence of digits to a sequence of characters that are neither digits - * nor punctuation characters, or vice versa. + * nor punctuation characters, or vice versa. Consecutive repeated + * punctuation characters are treated as a single punctuation character. * *

      * diff --git a/src/java.base/share/classes/java/lang/ref/Cleaner.java b/src/java.base/share/classes/java/lang/ref/Cleaner.java index a736f23ad2f80734b84797791e6d43d41bc5a6a8..a4769e112b6e689118408c71f3399de400601b47 100644 --- a/src/java.base/share/classes/java/lang/ref/Cleaner.java +++ b/src/java.base/share/classes/java/lang/ref/Cleaner.java @@ -86,9 +86,13 @@ import java.util.function.Function; * by the Cleaner when the CleaningExample instance has become phantom reachable. *
      {@code
        * public class CleaningExample implements AutoCloseable {
      - *        // A cleaner, preferably one shared within a library
      - *        private static final Cleaner cleaner = ;
      + *        // A cleaner (preferably one shared within a library,
      +          // but for the sake of example, a new one is created here)
      + *        private static final Cleaner cleaner = Cleaner.create();
        *
      + *        // State class captures information necessary for cleanup.
      + *        // It must hold no reference to the instance being cleaned
      + *        // and therefore it is a static inner class in this example.
        *        static class State implements Runnable {
        *
        *            State(...) {
      diff --git a/src/java.base/share/classes/java/lang/ref/Finalizer.java b/src/java.base/share/classes/java/lang/ref/Finalizer.java
      index d5838b7a6b1b461d7dff80b400895ffbf089e606..18aedf11bb316f1a7a301559f11c84eeb8c8efa6 100644
      --- a/src/java.base/share/classes/java/lang/ref/Finalizer.java
      +++ b/src/java.base/share/classes/java/lang/ref/Finalizer.java
      @@ -61,9 +61,17 @@ final class Finalizer extends FinalReference { /* Package-private; must
               return queue;
           }
       
      +    static final boolean ENABLED = isFinalizationEnabled();
      +
      +    private static native boolean isFinalizationEnabled();
      +
           /* Invoked by VM */
           static void register(Object finalizee) {
      -        new Finalizer(finalizee);
      +        if (ENABLED) {
      +            new Finalizer(finalizee);
      +        } else {
      +            throw new InternalError("unexpected call to Finalizer::register when finalization is disabled");
      +        }
           }
       
           private void runFinalizer(JavaLangAccess jla) {
      @@ -130,7 +138,7 @@ final class Finalizer extends FinalReference { /* Package-private; must
       
           /* Called by Runtime.runFinalization() */
           static void runFinalization() {
      -        if (VM.initLevel() == 0) {
      +        if (VM.initLevel() == 0 || ! ENABLED) {
                   return;
               }
       
      @@ -182,14 +190,16 @@ final class Finalizer extends FinalReference { /* Package-private; must
           }
       
           static {
      -        ThreadGroup tg = Thread.currentThread().getThreadGroup();
      -        for (ThreadGroup tgn = tg;
      -             tgn != null;
      -             tg = tgn, tgn = tg.getParent());
      -        Thread finalizer = new FinalizerThread(tg);
      -        finalizer.setPriority(Thread.MAX_PRIORITY - 2);
      -        finalizer.setDaemon(true);
      -        finalizer.start();
      +        if (ENABLED) {
      +            ThreadGroup tg = Thread.currentThread().getThreadGroup();
      +            for (ThreadGroup tgn = tg;
      +                 tgn != null;
      +                 tg = tgn, tgn = tg.getParent());
      +            Thread finalizer = new FinalizerThread(tg);
      +            finalizer.setPriority(Thread.MAX_PRIORITY - 2);
      +            finalizer.setDaemon(true);
      +            finalizer.start();
      +        }
           }
       
       }
      diff --git a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java
      index 19dbce14b7571ed919efe62f3b43a5465cbdcb67..2b620967a8aecc8df06248e87115953e93e1d6f6 100644
      --- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java
      +++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * This code is free software; you can redistribute it and/or modify it
      @@ -168,6 +168,15 @@ public class AccessibleObject implements AnnotatedElement {
            *     open module. 
            * 
            *
      +     * 

      This method may be used by JNI code + * with no caller class on the stack to enable access to a {@link Member member} + * of {@link Member#getDeclaringClass() declaring class} {@code D} if and only if: + *

        + *
      • The member is {@code public} and {@code D} is {@code public} in + * a package that the module containing {@code D} {@link + * Module#isExported(String,Module) exports} unconditionally.
      • + *
      + * *

      This method cannot be used to enable access to private members, * members with default (package) access, protected instance members, or * protected constructors when the declaring class is in a different module @@ -246,6 +255,11 @@ public class AccessibleObject implements AnnotatedElement { * } * } * + *

      If this method is invoked by JNI code + * with no caller class on the stack, the {@code accessible} flag can + * only be set if the member and the declaring class are public, and + * the class is in a package that is exported unconditionally.

      + * *

      If there is a security manager, its {@code checkPermission} method * is first called with a {@code ReflectPermission("suppressAccessChecks")} * permission.

      @@ -304,6 +318,16 @@ public class AccessibleObject implements AnnotatedElement { throw new IllegalCallerException(); // should not happen } + if (caller == null) { + // No caller frame when a native thread attaches to the VM + // only allow access to a public accessible member + boolean canAccess = Reflection.verifyPublicMemberAccess(declaringClass, declaringClass.getModifiers()); + if (!canAccess && throwExceptionIfDenied) { + throwInaccessibleObjectException(caller, declaringClass); + } + return canAccess; + } + Module callerModule = caller.getModule(); Module declaringModule = declaringClass.getModule(); @@ -312,12 +336,7 @@ public class AccessibleObject implements AnnotatedElement { if (!declaringModule.isNamed()) return true; String pn = declaringClass.getPackageName(); - int modifiers; - if (this instanceof Executable) { - modifiers = ((Executable) this).getModifiers(); - } else { - modifiers = ((Field) this).getModifiers(); - } + int modifiers = ((Member)this).getModifiers(); // class is public and package is exported to caller boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers()); @@ -341,25 +360,37 @@ public class AccessibleObject implements AnnotatedElement { } if (throwExceptionIfDenied) { - // not accessible - String msg = "Unable to make "; - if (this instanceof Field) - msg += "field "; - msg += this + " accessible: " + declaringModule + " does not \""; - if (isClassPublic && Modifier.isPublic(modifiers)) - msg += "exports"; - else - msg += "opens"; - msg += " " + pn + "\" to " + callerModule; - InaccessibleObjectException e = new InaccessibleObjectException(msg); - if (printStackTraceWhenAccessFails()) { - e.printStackTrace(System.err); - } - throw e; + throwInaccessibleObjectException(caller, declaringClass); } return false; } + private void throwInaccessibleObjectException(Class caller, Class declaringClass) { + boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers()); + String pn = declaringClass.getPackageName(); + int modifiers = ((Member)this).getModifiers(); + + // not accessible + String msg = "Unable to make "; + if (this instanceof Field) + msg += "field "; + msg += this + " accessible"; + msg += caller == null ? " by JNI attached native thread with no caller frame: " : ": "; + msg += declaringClass.getModule() + " does not \""; + if (isClassPublic && Modifier.isPublic(modifiers)) + msg += "exports"; + else + msg += "opens"; + msg += " " + pn + "\"" ; + if (caller != null) + msg += " to " + caller.getModule(); + InaccessibleObjectException e = new InaccessibleObjectException(msg); + if (printStackTraceWhenAccessFails()) { + e.printStackTrace(System.err); + } + throw e; + } + private boolean isSubclassOf(Class queryClass, Class ofClass) { while (queryClass != null) { if (queryClass == ofClass) { @@ -409,7 +440,11 @@ public class AccessibleObject implements AnnotatedElement { * is set to {@code true}, i.e. the checks for Java language access control * are suppressed, or if the caller can access the member as * specified in The Java Language Specification, - * with the variation noted in the class description.

      + * with the variation noted in the class description. + * If this method is invoked by JNI code + * with no caller class on the stack, this method returns {@code true} + * if the member and the declaring class are public, and the class is in + * a package that is exported unconditionally.

      * * @param obj an instance object of the declaring class of this reflected * object if it is an instance method or field diff --git a/src/java.base/share/classes/java/lang/reflect/Constructor.java b/src/java.base/share/classes/java/lang/reflect/Constructor.java index 73ad66d5d5dc62a621ab2f6b40fc86e34b7e63bd..17277c7eb35590bf0da774581d2bda34dd499974 100644 --- a/src/java.base/share/classes/java/lang/reflect/Constructor.java +++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java @@ -371,7 +371,7 @@ public final class Constructor extends Executable { sb.append(getDeclaringClass().getTypeName()); sb.append('('); StringJoiner sj = new StringJoiner(","); - for (Class parameterType : getParameterTypes()) { + for (Class parameterType : getSharedParameterTypes()) { sj.add(parameterType.getTypeName()); } sb.append(sj); diff --git a/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java b/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java index 4ca59906367966d51fae53e7f52a59ba3f394594..d5d00f34c868f42ef0520ee363f99a49f809c711 100644 --- a/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java +++ b/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java @@ -28,7 +28,6 @@ package java.lang.reflect; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; -import java.lang.invoke.MethodHandle; import java.util.Objects; /** @@ -262,33 +261,6 @@ public interface InvocationHandler { throws Throwable { Objects.requireNonNull(proxy); Objects.requireNonNull(method); - - // verify that the object is actually a proxy instance - if (!Proxy.isProxyClass(proxy.getClass())) { - throw new IllegalArgumentException("'proxy' is not a proxy instance"); - } - if (!method.isDefault()) { - throw new IllegalArgumentException("\"" + method + "\" is not a default method"); - } - @SuppressWarnings("unchecked") - Class proxyClass = (Class)proxy.getClass(); - - Class intf = method.getDeclaringClass(); - // access check on the default method - method.checkAccess(Reflection.getCallerClass(), intf, proxyClass, method.getModifiers()); - - MethodHandle mh = Proxy.defaultMethodHandle(proxyClass, method); - // invoke the super method - try { - // the args array can be null if the number of formal parameters required by - // the method is zero (consistent with Method::invoke) - Object[] params = args != null ? args : Proxy.EMPTY_ARGS; - return mh.invokeExact(proxy, params); - } catch (ClassCastException | NullPointerException e) { - throw new IllegalArgumentException(e.getMessage(), e); - } catch (Proxy.InvocationException e) { - // unwrap and throw the exception thrown by the default method - throw e.getCause(); - } + return Proxy.invokeDefault(proxy, method, args, Reflection.getCallerClass()); } } diff --git a/src/java.base/share/classes/java/lang/reflect/Method.java b/src/java.base/share/classes/java/lang/reflect/Method.java index 5d8fe026b406eae1662b134f940cd01097c42346..2aff745d55367f5db32ee48211d7660c841c0210 100644 --- a/src/java.base/share/classes/java/lang/reflect/Method.java +++ b/src/java.base/share/classes/java/lang/reflect/Method.java @@ -431,7 +431,7 @@ public final class Method extends Executable { String toShortSignature() { StringJoiner sj = new StringJoiner(",", getName() + "(", ")"); - for (Class parameterType : getParameterTypes()) { + for (Class parameterType : getSharedParameterTypes()) { sj.add(parameterType.getTypeName()); } return sj.toString(); diff --git a/src/java.base/share/classes/java/lang/reflect/Proxy.java b/src/java.base/share/classes/java/lang/reflect/Proxy.java index c9e3bb259ae44bbd68edbdae7a29308fa6c07925..6dd5b3ef1db42a65e34371feb49599bf65f16277 100644 --- a/src/java.base/share/classes/java/lang/reflect/Proxy.java +++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java @@ -1314,6 +1314,46 @@ public class Proxy implements java.io.Serializable { }); } + /* + * Invoke the default method of the given proxy with an explicit caller class. + * + * @throws IllegalAccessException if the proxy interface is inaccessible to the caller + * if caller is non-null + */ + static Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable { + // verify that the object is actually a proxy instance + if (!Proxy.isProxyClass(proxy.getClass())) { + throw new IllegalArgumentException("'proxy' is not a proxy instance"); + } + if (!method.isDefault()) { + throw new IllegalArgumentException("\"" + method + "\" is not a default method"); + } + @SuppressWarnings("unchecked") + Class proxyClass = (Class)proxy.getClass(); + + // skip access check if caller is null + if (caller != null) { + Class intf = method.getDeclaringClass(); + // access check on the default method + method.checkAccess(caller, intf, proxyClass, method.getModifiers()); + } + + MethodHandle mh = Proxy.defaultMethodHandle(proxyClass, method); + // invoke the super method + try { + // the args array can be null if the number of formal parameters required by + // the method is zero (consistent with Method::invoke) + Object[] params = args != null ? args : Proxy.EMPTY_ARGS; + return mh.invokeExact(proxy, params); + } catch (ClassCastException | NullPointerException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } catch (Proxy.InvocationException e) { + // unwrap and throw the exception thrown by the default method + throw e.getCause(); + } + } + /** * Internal exception type to wrap the exception thrown by the default method * so that it can distinguish CCE and NPE thrown due to the arguments diff --git a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java index 6ac890156b0f5668520da4c46283d67fa07c0269..fa5a5d453ec02c1398bfb821d1be5bfac5322647 100644 --- a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java +++ b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java @@ -127,4 +127,9 @@ class ReflectAccess implements jdk.internal.access.JavaLangReflectAccess { { return ctor.newInstanceWithCaller(args, true, caller); } + + public Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable { + return Proxy.invokeDefault(proxy, method, args, caller); + } } diff --git a/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java b/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java index 5d092328f756e75c39052406b9eda4e5d94896e8..c2d388d01bac0ed9935571a2b130cf49bd256e4d 100644 --- a/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java +++ b/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java @@ -396,15 +396,15 @@ public class ObjectMethods { * if invoked by a condy * @throws IllegalArgumentException if the bootstrap arguments are invalid * or inconsistent - * @throws NullPointerException if any argument but {@code lookup} is {@code null}, - * in the case of the {@code getters} argument, its - * contents cannot be {@code null} either + * @throws NullPointerException if any argument is {@code null} or if any element + * in the {@code getters} array is {@code null} * @throws Throwable if any exception is thrown during call site construction */ public static Object bootstrap(MethodHandles.Lookup lookup, String methodName, TypeDescriptor type, Class recordClass, String names, MethodHandle... getters) throws Throwable { + requireNonNull(lookup); requireNonNull(methodName); requireNonNull(type); requireNonNull(recordClass); diff --git a/src/java.base/share/classes/java/math/BigDecimal.java b/src/java.base/share/classes/java/math/BigDecimal.java index 8660a4513959af83beb6e9c0ec34b8a96c7cc4c7..c491346f9f58d9bab187904d67bb32874a77a70b 100644 --- a/src/java.base/share/classes/java/math/BigDecimal.java +++ b/src/java.base/share/classes/java/math/BigDecimal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1791,7 +1791,7 @@ public class BigDecimal extends Number implements Comparable { * @throws ArithmeticException if the result is inexact but the * rounding mode is {@code UNNECESSARY} or * {@code mc.precision == 0} and the quotient has a - * non-terminating decimal expansion,including dividing by zero + * non-terminating decimal expansion, including dividing by zero * @since 1.5 */ public BigDecimal divide(BigDecimal divisor, MathContext mc) { @@ -4405,7 +4405,7 @@ public class BigDecimal extends Number implements Comparable { x = -x; if (y < 0) y = -y; - return (x < y) ? -1 : ((x == y) ? 0 : 1); + return Long.compare(x, y); } private static int saturateLong(long s) { diff --git a/src/java.base/share/classes/java/net/CookieManager.java b/src/java.base/share/classes/java/net/CookieManager.java index adc405b9b81b3788a2aa72e15201a3b52a6df181..b1540ad5612b9dca151c740cb3fe97782f12aef3 100644 --- a/src/java.base/share/classes/java/net/CookieManager.java +++ b/src/java.base/share/classes/java/net/CookieManager.java @@ -447,13 +447,7 @@ public class CookieManager extends CookieHandler // Check creation time. Sort older first long creation1 = c1.getCreationTime(); long creation2 = c2.getCreationTime(); - if (creation1 < creation2) { - return -1; - } - if (creation1 > creation2) { - return 1; - } - return 0; + return Long.compare(creation1, creation2); } } } diff --git a/src/java.base/share/classes/java/net/ServerSocket.java b/src/java.base/share/classes/java/net/ServerSocket.java index 3d985f84df3cebf5e761d441a807714c56c49f3d..9441e6476e31967d88795e8667b966dd6749ee48 100644 --- a/src/java.base/share/classes/java/net/ServerSocket.java +++ b/src/java.base/share/classes/java/net/ServerSocket.java @@ -78,17 +78,17 @@ import sun.net.PlatformSocketImpl; */ public class ServerSocket implements java.io.Closeable { /** - * Various states of this socket. + * The underlying SocketImpl */ - private boolean created = false; - private boolean bound = false; - private boolean closed = false; - private Object closeLock = new Object(); + private final SocketImpl impl; /** - * The implementation of this Socket. + * Various states of this socket, need stateLock to change. */ - private SocketImpl impl; + private volatile boolean created; // impl.create(boolean) called + private volatile boolean bound; + private volatile boolean closed; + private final Object stateLock = new Object(); /** * Creates a server socket with a user-specified {@code SocketImpl}. @@ -124,7 +124,7 @@ public class ServerSocket implements java.io.Closeable { * @revised 1.4 */ public ServerSocket() throws IOException { - setImpl(); + this.impl = createImpl(); } /** @@ -264,18 +264,15 @@ public class ServerSocket implements java.io.Closeable { * @since 1.1 */ public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException { - setImpl(); if (port < 0 || port > 0xFFFF) - throw new IllegalArgumentException( - "Port value out of range: " + port); + throw new IllegalArgumentException("Port value out of range: " + port); if (backlog < 1) - backlog = 50; + backlog = 50; + + this.impl = createImpl(); try { bind(new InetSocketAddress(bindAddr, port), backlog); - } catch(SecurityException e) { - close(); - throw e; - } catch(IOException e) { + } catch (IOException | SecurityException e) { close(); throw e; } @@ -289,35 +286,36 @@ public class ServerSocket implements java.io.Closeable { * @throws SocketException if creation fails. * @since 1.4 */ - SocketImpl getImpl() throws SocketException { - if (!created) - createImpl(); + private SocketImpl getImpl() throws SocketException { + if (!created) { + synchronized (stateLock) { + if (!created) { + if (closed) { + throw new SocketException("Socket is closed"); + } + try { + impl.create(true); + } catch (SocketException e) { + throw e; + } catch (IOException e) { + throw new SocketException(e.getMessage()); + } + created = true; + } + } + } return impl; } - private void setImpl() { + /** + * Create a SocketImpl for a server socket. + */ + private static SocketImpl createImpl() { SocketImplFactory factory = ServerSocket.factory; if (factory != null) { - impl = factory.createSocketImpl(); + return factory.createSocketImpl(); } else { - impl = SocketImpl.createPlatformSocketImpl(true); - } - } - - /** - * Creates the socket implementation. - * - * @throws SocketException if creation fails - * @since 1.4 - */ - void createImpl() throws SocketException { - if (impl == null) - setImpl(); - try { - impl.create(true); - created = true; - } catch (IOException e) { - throw new SocketException(e.getMessage()); + return SocketImpl.createPlatformSocketImpl(true); } } @@ -379,21 +377,21 @@ public class ServerSocket implements java.io.Closeable { if (epoint.isUnresolved()) throw new SocketException("Unresolved address"); if (backlog < 1) - backlog = 50; - try { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkListen(epoint.getPort()); + backlog = 50; + + @SuppressWarnings("removal") + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkListen(epoint.getPort()); + + synchronized (stateLock) { + if (closed) + throw new SocketException("Socket is closed"); + if (bound) + throw new SocketException("Already bound"); getImpl().bind(epoint.getAddress(), epoint.getPort()); getImpl().listen(backlog); bound = true; - } catch(SecurityException e) { - bound = false; - throw e; - } catch(IOException e) { - bound = false; - throw e; } } @@ -711,12 +709,15 @@ public class ServerSocket implements java.io.Closeable { * @revised 1.4 */ public void close() throws IOException { - synchronized(closeLock) { - if (isClosed()) - return; - if (created) - impl.close(); - closed = true; + synchronized (stateLock) { + if (!closed) { + closed = true; + + // close underlying socket if created + if (created) { + impl.close(); + } + } } } @@ -760,9 +761,7 @@ public class ServerSocket implements java.io.Closeable { * @since 1.4 */ public boolean isClosed() { - synchronized(closeLock) { - return closed; - } + return closed; } /** @@ -783,7 +782,7 @@ public class ServerSocket implements java.io.Closeable { * @since 1.1 * @see #getSoTimeout() */ - public synchronized void setSoTimeout(int timeout) throws SocketException { + public void setSoTimeout(int timeout) throws SocketException { if (isClosed()) throw new SocketException("Socket is closed"); if (timeout < 0) @@ -799,7 +798,7 @@ public class ServerSocket implements java.io.Closeable { * @since 1.1 * @see #setSoTimeout(int) */ - public synchronized int getSoTimeout() throws IOException { + public int getSoTimeout() throws IOException { if (isClosed()) throw new SocketException("Socket is closed"); Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); @@ -984,7 +983,7 @@ public class ServerSocket implements java.io.Closeable { * @since 1.4 * @see #getReceiveBufferSize */ - public synchronized void setReceiveBufferSize (int size) throws SocketException { + public void setReceiveBufferSize (int size) throws SocketException { if (!(size > 0)) { throw new IllegalArgumentException("negative receive size"); } @@ -1007,8 +1006,7 @@ public class ServerSocket implements java.io.Closeable { * @see #setReceiveBufferSize(int) * @since 1.4 */ - public synchronized int getReceiveBufferSize() - throws SocketException{ + public int getReceiveBufferSize() throws SocketException { if (isClosed()) throw new SocketException("Socket is closed"); int result = 0; diff --git a/src/java.base/share/classes/java/net/doc-files/net-properties.html b/src/java.base/share/classes/java/net/doc-files/net-properties.html index 0c2d3e232dad4ef40d03d713ec36b1679dbc5cbd..2bd355804328ef1cd643a71f793eae9dadaee7d3 100644 --- a/src/java.base/share/classes/java/net/doc-files/net-properties.html +++ b/src/java.base/share/classes/java/net/doc-files/net-properties.html @@ -214,6 +214,22 @@ of proxies.

      property is defined, then its value will be used as the domain name.

      +
    • {@systemProperty jdk.https.negotiate.cbt} (default: <never>)
      + This controls the generation and sending of TLS channel binding tokens (CBT) when Kerberos + or the Negotiate authentication scheme using Kerberos are employed over HTTPS with + {@code HttpsURLConnection}. There are three possible settings:

      +
        +
      1. "never". This is also the default value if the property is not set. In this case, + CBTs are never sent.

        +
      2. "always". CBTs are sent for all Kerberos authentication attempts over HTTPS.

        +
      3. "domain:<comma separated domain list>" Each domain in the list specifies destination + host or hosts for which a CBT is sent. Domains can be single hosts like foo, or foo.com, + or literal IP addresses as specified in RFC 2732, or wildcards like *.foo.com which matches + all hosts under foo.com and its sub-domains. CBTs are not sent to any destinations + that don't match one of the list entries

        +
      +

      The channel binding tokens generated are of the type "tls-server-end-point" as defined in + RFC 5929.

      All these properties are checked only once at startup.

      diff --git a/src/java.base/share/classes/java/net/package-info.java b/src/java.base/share/classes/java/net/package-info.java index b221c6bf2f73de4f12967a0d464afdc6ea715d2c..6fc9913dfedd3b520cdf07ab611ef1af4822c8c7 100644 --- a/src/java.base/share/classes/java/net/package-info.java +++ b/src/java.base/share/classes/java/net/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,7 +122,7 @@ *
    • {@link java.net.HttpURLConnection} is a subclass of URLConnection * and provides some additional functionalities specific to the * HTTP protocol. This API has been superseded by the newer - * {@linkplain java.net.http HTTP Client API}.
    • + * {@linkplain java.net.http/java.net.http HTTP Client API}. * *

      The recommended usage is to use {@link java.net.URI} to identify * resources, then convert it into a {@link java.net.URL} when it is time to @@ -157,4 +157,5 @@ * * @since 1.0 */ +@SuppressWarnings("doclint:reference") // cross-module links package java.net; diff --git a/src/java.base/share/classes/java/net/spi/InetAddressResolverProvider.java b/src/java.base/share/classes/java/net/spi/InetAddressResolverProvider.java index 30f1c4f5b3e7e33bc4bc441c3a8a45c883420349..6dff033ffc8897763324c7c18d126f4ea40a13aa 100644 --- a/src/java.base/share/classes/java/net/spi/InetAddressResolverProvider.java +++ b/src/java.base/share/classes/java/net/spi/InetAddressResolverProvider.java @@ -66,7 +66,8 @@ import java.util.ServiceLoader; * *

      If instantiating a custom resolver from a provider discovered in * step 1 throws an error or exception, the system-wide resolver will not be - * set and the error or exception will be propagated to the calling thread. + * set and the error or exception will be propagated to the caller of the method + * that triggered the lookup operation. * Otherwise, any lookup operation will be performed using the * system-wide resolver. * @@ -85,7 +86,7 @@ public abstract class InetAddressResolverProvider { * *

      Any error or exception thrown by this method is considered as * a failure of {@code InetAddressResolver} instantiation and will be propagated to - * the calling thread. + * the caller of the method that triggered the lookup operation. * @param configuration a {@link Configuration} instance containing platform built-in address * resolution configuration. * @return the resolver provided by this provider diff --git a/src/java.base/share/classes/java/nio/Buffer.java b/src/java.base/share/classes/java/nio/Buffer.java index 92c9f80dca8c439fc6e54e411b0b70265333d968..a452b1a28dd435e454104f05c36dc5e4a1dee223 100644 --- a/src/java.base/share/classes/java/nio/Buffer.java +++ b/src/java.base/share/classes/java/nio/Buffer.java @@ -767,7 +767,11 @@ public abstract class Buffer { final void checkScope() { ScopedMemoryAccess.Scope scope = scope(); if (scope != null) { - scope.checkValidState(); + try { + scope.checkValidState(); + } catch (ScopedMemoryAccess.Scope.ScopedAccessError e) { + throw new IllegalStateException("This segment is already closed"); + } } } diff --git a/src/java.base/share/classes/java/nio/channels/Channels.java b/src/java.base/share/classes/java/nio/channels/Channels.java index 3e68d49b2b7023f2890f25435067d6dc5a1f563a..1d2ccaa778889a66a14436c8654e1cd668be23fe 100644 --- a/src/java.base/share/classes/java/nio/channels/Channels.java +++ b/src/java.base/share/classes/java/nio/channels/Channels.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,8 +40,6 @@ import java.nio.charset.UnsupportedCharsetException; import java.nio.channels.spi.AbstractInterruptibleChannel; import java.util.Objects; import java.util.concurrent.ExecutionException; -import sun.nio.ch.ChannelInputStream; -import sun.nio.ch.ChannelOutputStream; import sun.nio.cs.StreamDecoder; import sun.nio.cs.StreamEncoder; @@ -87,7 +85,7 @@ public final class Channels { */ public static InputStream newInputStream(ReadableByteChannel ch) { Objects.requireNonNull(ch, "ch"); - return new ChannelInputStream(ch); + return sun.nio.ch.Streams.of(ch); } /** @@ -106,7 +104,7 @@ public final class Channels { */ public static OutputStream newOutputStream(WritableByteChannel ch) { Objects.requireNonNull(ch, "ch"); - return new ChannelOutputStream(ch); + return sun.nio.ch.Streams.of(ch); } /** diff --git a/src/java.base/share/classes/java/nio/channels/FileChannel.java b/src/java.base/share/classes/java/nio/channels/FileChannel.java index 2ea213b3509e859c1f6086d211b89c8fac49da93..9d9c35fbc1f760c8b829b869ddc7b897c5212671 100644 --- a/src/java.base/share/classes/java/nio/channels/FileChannel.java +++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,16 @@ package java.nio.channels; -import java.io.*; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.spi.AbstractInterruptibleChannel; -import java.nio.file.*; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.nio.file.attribute.FileAttribute; -import java.nio.file.spi.*; +import java.nio.file.spi.FileSystemProvider; import java.util.Set; import java.util.HashSet; import java.util.Collections; @@ -403,6 +406,9 @@ public abstract class FileChannel * with the number of bytes actually written. Otherwise this method * behaves exactly as specified by the {@link WritableByteChannel} * interface.

      + * + * @throws NonWritableChannelException + * If this channel was not opened for writing */ public abstract int write(ByteBuffer src) throws IOException; @@ -417,6 +423,9 @@ public abstract class FileChannel * with the number of bytes actually written. Otherwise this method * behaves exactly as specified in the {@link GatheringByteChannel} * interface.

      + * + * @throws NonWritableChannelException + * If this channel was not opened for writing */ public abstract long write(ByteBuffer[] srcs, int offset, int length) throws IOException; @@ -431,6 +440,9 @@ public abstract class FileChannel * with the number of bytes actually written. Otherwise this method * behaves exactly as specified in the {@link GatheringByteChannel} * interface.

      + * + * @throws NonWritableChannelException + * If this channel was not opened for writing */ public final long write(ByteBuffer[] srcs) throws IOException { return write(srcs, 0, srcs.length); @@ -554,8 +566,11 @@ public abstract class FileChannel * actually done is system-dependent and is therefore unspecified. * *

      This method is only guaranteed to force changes that were made to - * this channel's file via the methods defined in this class. It may or - * may not force changes that were made by modifying the content of a + * this channel's file via the methods defined in this class, or the methods + * defined by {@link java.io.FileOutputStream} or + * {@link java.io.RandomAccessFile} when the channel was obtained with the + * {@code getChannel} method. It may or may not force changes that were made + * by modifying the content of a * {@link MappedByteBuffer mapped byte buffer} obtained by * invoking the {@link #map map} method. Invoking the {@link * MappedByteBuffer#force force} method of the mapped byte buffer will @@ -1030,7 +1045,7 @@ public abstract class FileChannel * region * * @throws NonReadableChannelException - * If {@code shared} is {@code true} this channel was not + * If {@code shared} is {@code true} but this channel was not * opened for reading * * @throws NonWritableChannelException @@ -1148,6 +1163,14 @@ public abstract class FileChannel * blocked in this method and is attempting to lock an overlapping * region of the same file * + * @throws NonReadableChannelException + * If {@code shared} is {@code true} but this channel was not + * opened for reading + * + * @throws NonWritableChannelException + * If {@code shared} is {@code false} but this channel was not + * opened for writing + * * @throws IOException * If some other I/O error occurs * @@ -1180,6 +1203,9 @@ public abstract class FileChannel * blocked in this method and is attempting to lock an overlapping * region * + * @throws NonWritableChannelException + * If this channel was not opened for writing + * * @throws IOException * If some other I/O error occurs * diff --git a/src/java.base/share/classes/java/nio/channels/Selector.java b/src/java.base/share/classes/java/nio/channels/Selector.java index 4fb98f3a8cea70373c49c5b0e4887d35a588bd26..d8c0dc261bd6a9835fcd848b2a0a588a06d2dca1 100644 --- a/src/java.base/share/classes/java/nio/channels/Selector.java +++ b/src/java.base/share/classes/java/nio/channels/Selector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -355,7 +355,8 @@ public abstract class Selector implements Closeable { * of the {@link #wakeup wakeup} method.

      * * @return The number of keys, possibly zero, whose ready-operation sets - * were updated by the selection operation + * now indicate readiness for at least one category of operations + * for which the channel was not previously detected to be ready * * @throws IOException * If an I/O error occurs @@ -383,8 +384,9 @@ public abstract class Selector implements Closeable { * channel to become ready; if zero, block indefinitely; * must not be negative * - * @return The number of keys, possibly zero, - * whose ready-operation sets were updated + * @return The number of keys, possibly zero, whose ready-operation sets + * now indicate readiness for at least one category of operations + * for which the channel was not previously detected to be ready * * @throws IOException * If an I/O error occurs @@ -406,8 +408,9 @@ public abstract class Selector implements Closeable { * this selector's {@link #wakeup wakeup} method is invoked, or the current * thread is interrupted, whichever comes first.

      * - * @return The number of keys, possibly zero, - * whose ready-operation sets were updated + * @return The number of keys, possibly zero, whose ready-operation sets + * now indicate readiness for at least one category of operations + * for which the channel was not previously detected to be ready * * @throws IOException * If an I/O error occurs diff --git a/src/java.base/share/classes/java/nio/file/Files.java b/src/java.base/share/classes/java/nio/file/Files.java index 9c1f92614faef7fe68a4df2df2daf4237aa7c439..0d9bba9cbcae707d327d8d685e179a1536c86771 100644 --- a/src/java.base/share/classes/java/nio/file/Files.java +++ b/src/java.base/share/classes/java/nio/file/Files.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -824,7 +824,7 @@ public final class Files { * java.io.File#createTempFile(String,String,File)} method. * *

      As with the {@code File.createTempFile} methods, this method is only - * part of a temporary-file facility. Where used as a work files, + * part of a temporary-file facility. Where used as a work file, * the resulting file may be opened using the {@link * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the * file is deleted when the appropriate {@code close} method is invoked. diff --git a/src/java.base/share/classes/java/security/AccessControlContext.java b/src/java.base/share/classes/java/security/AccessControlContext.java index a7f3641bedadcc5181e6f99dd887596c65bbaddf..1cb35d9bdfc407c4532eb2d5a99bbbaac07a9f6b 100644 --- a/src/java.base/share/classes/java/security/AccessControlContext.java +++ b/src/java.base/share/classes/java/security/AccessControlContext.java @@ -916,7 +916,6 @@ public final class AccessControlContext { private boolean containsAllLimits(AccessControlContext that) { boolean match = false; - Permission thisPerm; if (this.permissions == null && that.permissions == null) return true; diff --git a/src/java.base/share/classes/java/security/Key.java b/src/java.base/share/classes/java/security/Key.java index b0159f0b33e207dd9b22928fb5fb876054974f36..4ea5ae0887b08807eec9b9107abb8c1d6885e7ca 100644 --- a/src/java.base/share/classes/java/security/Key.java +++ b/src/java.base/share/classes/java/security/Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,7 @@ package java.security; * which should not be exposed in untrusted environments. See the * * Security Appendix - * of the Serialization Specification for more information. + * of the Java Object Serialization Specification for more information. * * @see PublicKey * @see PrivateKey diff --git a/src/java.base/share/classes/java/security/KeyRep.java b/src/java.base/share/classes/java/security/KeyRep.java index 341c3d99af1bf819836c4a8a18c289290a3573e3..779f5a7181afb2c8d9da0bf36a54874520d39804 100644 --- a/src/java.base/share/classes/java/security/KeyRep.java +++ b/src/java.base/share/classes/java/security/KeyRep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ import javax.crypto.spec.SecretKeySpec; * which should not be exposed in untrusted environments. See the * * Security Appendix - * of the Serialization Specification for more information. + * of the Java Object Serialization Specification for more information. * * @see Key * @see KeyFactory diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java index 11c8eb29ca70ebcd85dbe7e4047d0a1f19eeb5c4..4a458cae7f8f29341c7ca9a9ba264eecd7ca4863 100644 --- a/src/java.base/share/classes/java/security/Provider.java +++ b/src/java.base/share/classes/java/security/Provider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -191,6 +191,8 @@ public abstract class Provider extends Properties { this.versionStr = Double.toString(version); this.info = info; this.serviceMap = new ConcurrentHashMap<>(); + this.legacyMap = new ConcurrentHashMap<>(); + this.prngAlgos = new LinkedHashSet(6); putId(); initialized = true; } @@ -229,6 +231,8 @@ public abstract class Provider extends Properties { this.version = parseVersionStr(versionStr); this.info = info; this.serviceMap = new ConcurrentHashMap<>(); + this.legacyMap = new ConcurrentHashMap<>(); + this.prngAlgos = new LinkedHashSet(6); putId(); initialized = true; } @@ -572,7 +576,6 @@ public abstract class Provider extends Properties { public synchronized boolean replace(Object key, Object oldValue, Object newValue) { check("putProviderProperty." + name); - if (debug != null) { debug.println("Replace " + name + " provider property " + key); } @@ -598,7 +601,6 @@ public abstract class Provider extends Properties { @Override public synchronized Object replace(Object key, Object value) { check("putProviderProperty." + name); - if (debug != null) { debug.println("Replace " + name + " provider property " + key); } @@ -627,7 +629,6 @@ public abstract class Provider extends Properties { public synchronized void replaceAll(BiFunction function) { check("putProviderProperty." + name); - if (debug != null) { debug.println("ReplaceAll " + name + " provider property "); } @@ -657,7 +658,6 @@ public abstract class Provider extends Properties { ? super Object, ? extends Object> remappingFunction) { check("putProviderProperty." + name); check("removeProviderProperty." + name); - if (debug != null) { debug.println("Compute " + name + " provider property " + key); } @@ -684,11 +684,10 @@ public abstract class Provider extends Properties { * @since 1.8 */ @Override - public synchronized Object computeIfAbsent(Object key, Function mappingFunction) { + public synchronized Object computeIfAbsent(Object key, + Function mappingFunction) { check("putProviderProperty." + name); check("removeProviderProperty." + name); - if (debug != null) { debug.println("ComputeIfAbsent " + name + " provider property " + key); @@ -714,11 +713,11 @@ public abstract class Provider extends Properties { * @since 1.8 */ @Override - public synchronized Object computeIfPresent(Object key, BiFunction remappingFunction) { + public synchronized Object computeIfPresent(Object key, + BiFunction + remappingFunction) { check("putProviderProperty." + name); check("removeProviderProperty." + name); - if (debug != null) { debug.println("ComputeIfPresent " + name + " provider property " + key); @@ -747,11 +746,11 @@ public abstract class Provider extends Properties { * @since 1.8 */ @Override - public synchronized Object merge(Object key, Object value, BiFunction remappingFunction) { + public synchronized Object merge(Object key, Object value, + BiFunction + remappingFunction) { check("putProviderProperty." + name); check("removeProviderProperty." + name); - if (debug != null) { debug.println("Merge " + name + " provider property " + key); } @@ -777,7 +776,8 @@ public abstract class Provider extends Properties { * @since 1.8 */ @Override - public synchronized void forEach(BiConsumer action) { + public synchronized void forEach(BiConsumer + action) { checkInitialized(); super.forEach(action); } @@ -817,14 +817,11 @@ public abstract class Provider extends Properties { } } - // legacy properties changed since last call to any services method? - private transient boolean legacyChanged; + // legacyMap changed since last call to getServices() + private transient volatile boolean legacyChanged; // serviceMap changed since last call to getServices() private transient volatile boolean servicesChanged; - // Map used to keep track of legacy registration - private transient Map legacyStrings; - // Map // used for services added via putService(), initialized on demand private transient Map serviceMap; @@ -832,6 +829,9 @@ public abstract class Provider extends Properties { // For backward compatibility, the registration ordering of // SecureRandom (RNG) algorithms needs to be preserved for // "new SecureRandom()" calls when this provider is used + // NOTE: may need extra mechanism for providers to indicate their + // preferred ordering of SecureRandom algorithms since registration + // ordering info is lost once serialized private transient Set prngAlgos; // Map @@ -840,7 +840,7 @@ public abstract class Provider extends Properties { // Set // Unmodifiable set of all services. Initialized on demand. - private transient Set serviceSet; + private transient volatile Set serviceSet; // register the id attributes for this provider // this is to ensure that equals() and hashCode() do not incorrectly @@ -872,6 +872,7 @@ public abstract class Provider extends Properties { for (Map.Entry entry : super.entrySet()) { copy.put(entry.getKey(), entry.getValue()); } + defaults = null; in.defaultReadObject(); if (this.versionStr == null) { @@ -882,23 +883,22 @@ public abstract class Provider extends Properties { this.version = parseVersionStr(this.versionStr); } this.serviceMap = new ConcurrentHashMap<>(); + this.legacyMap = new ConcurrentHashMap<>(); + this.prngAlgos = new LinkedHashSet(6); implClear(); initialized = true; putAll(copy); } - // check whether to update 'legacyString' with the specified key - private boolean checkLegacy(Object key) { - String keyString = (String)key; - if (keyString.startsWith("Provider.")) { + // returns false if no update necessary, i.e. key isn't String or + // is String but it's provider-related (name/version/info/className) + private static boolean checkLegacy(Object key) { + if (key instanceof String && ((String)key).startsWith("Provider.")) { + // ignore provider related updates return false; + } else { + return true; } - - legacyChanged = true; - if (legacyStrings == null) { - legacyStrings = new LinkedHashMap<>(); - } - return true; } /** @@ -913,149 +913,161 @@ public abstract class Provider extends Properties { } private Object implRemove(Object key) { - if (key instanceof String) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.remove((String)key); + if (!checkLegacy(key)) return null; + + Object o = super.remove(key); + if (o instanceof String so && key instanceof String sk) { + parseLegacy(sk, so, OPType.REMOVE); } - return super.remove(key); + return o; } private boolean implRemove(Object key, Object value) { - if (key instanceof String && value instanceof String) { - if (!checkLegacy(key)) { - return false; - } - legacyStrings.remove((String)key, (String)value); + if (!checkLegacy(key)) return false; + + boolean result = super.remove(key, value); + if (result && key instanceof String sk && value instanceof String sv) { + parseLegacy(sk, sv, OPType.REMOVE); } - return super.remove(key, value); + return result; } private boolean implReplace(Object key, Object oldValue, Object newValue) { - if ((key instanceof String) && (oldValue instanceof String) && - (newValue instanceof String)) { - if (!checkLegacy(key)) { - return false; + if (!checkLegacy(key)) return false; + + boolean result = super.replace(key, oldValue, newValue); + if (result && key instanceof String sk) { + if (newValue instanceof String sv) { + parseLegacy(sk, sv, OPType.ADD); + } else if (oldValue instanceof String sv) { + parseLegacy(sk, sv, OPType.REMOVE); } - legacyStrings.replace((String)key, (String)oldValue, - (String)newValue); } - return super.replace(key, oldValue, newValue); + return result; } private Object implReplace(Object key, Object value) { - if ((key instanceof String) && (value instanceof String)) { - if (!checkLegacy(key)) { - return null; + if (!checkLegacy(key)) return null; + + Object o = super.replace(key, value); + if (key instanceof String sk) { + if (o instanceof String so) { + if (value instanceof String sv) { + parseLegacy(sk, sv, OPType.ADD); + } else { + parseLegacy(sk, so, OPType.REMOVE); + } } - legacyStrings.replace((String)key, (String)value); } - return super.replace(key, value); + return o; } @SuppressWarnings("unchecked") // Function must actually operate over strings private void implReplaceAll(BiFunction function) { + + super.replaceAll(function); + // clear out all existing mappings and start fresh + legacyMap.clear(); legacyChanged = true; - if (legacyStrings == null) { - legacyStrings = new LinkedHashMap<>(); - } else { - legacyStrings.replaceAll((BiFunction) function); + for (Map.Entry entry : super.entrySet()) { + Object key = entry.getKey(); + Object value = entry.getValue(); + if ((key instanceof String sk) && (value instanceof String sv)) { + if (!checkLegacy(sk)) { + continue; + } + parseLegacy(sk, sv, OPType.ADD); + } } - super.replaceAll(function); } @SuppressWarnings("unchecked") // Function must actually operate over strings private Object implMerge(Object key, Object value, BiFunction remappingFunction) { - if ((key instanceof String) && (value instanceof String)) { - if (!checkLegacy(key)) { - return null; + if (!checkLegacy(key)) return null; + + Object o = super.merge(key, value, remappingFunction); + if (key instanceof String sk) { + if (o == null) { + parseLegacy(sk, null, OPType.REMOVE); + } else if (o instanceof String so) { + parseLegacy(sk, so, OPType.ADD); } - legacyStrings.merge((String)key, (String)value, - (BiFunction) remappingFunction); } - return super.merge(key, value, remappingFunction); + return o; } @SuppressWarnings("unchecked") // Function must actually operate over strings private Object implCompute(Object key, BiFunction remappingFunction) { - if (key instanceof String) { - if (!checkLegacy(key)) { - return null; + + if (!checkLegacy(key)) return null; + + Object o = super.compute(key, remappingFunction); + if (key instanceof String sk) { + if (o == null) { + parseLegacy(sk, null, OPType.REMOVE); + } else if (o instanceof String so) { + parseLegacy(sk, so, OPType.ADD); } - legacyStrings.compute((String) key, - (BiFunction) remappingFunction); } - return super.compute(key, remappingFunction); + return o; } @SuppressWarnings("unchecked") // Function must actually operate over strings private Object implComputeIfAbsent(Object key, Function mappingFunction) { - if (key instanceof String) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.computeIfAbsent((String) key, - (Function) - mappingFunction); + if (!checkLegacy(key)) return null; + + Object o = super.computeIfAbsent(key, mappingFunction); + if (o instanceof String so && key instanceof String sk) { + parseLegacy(sk, so, OPType.ADD); } - return super.computeIfAbsent(key, mappingFunction); + return o; } @SuppressWarnings("unchecked") // Function must actually operate over strings private Object implComputeIfPresent(Object key, BiFunction remappingFunction) { - if (key instanceof String) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.computeIfPresent((String) key, - (BiFunction) remappingFunction); + if (!checkLegacy(key)) return null; + + Object o = super.computeIfPresent(key, remappingFunction); + if (o instanceof String so && key instanceof String sk) { + parseLegacy(sk, so, OPType.ADD); } - return super.computeIfPresent(key, remappingFunction); + return o; } private Object implPut(Object key, Object value) { - if ((key instanceof String) && (value instanceof String)) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.put((String)key, (String)value); + if (!checkLegacy(key)) return null; + + Object o = super.put(key, value); + if (key instanceof String sk && value instanceof String sv) { + parseLegacy(sk, sv, OPType.ADD); } - return super.put(key, value); + return o; } private Object implPutIfAbsent(Object key, Object value) { - if ((key instanceof String) && (value instanceof String)) { - if (!checkLegacy(key)) { - return null; - } - legacyStrings.putIfAbsent((String)key, (String)value); + if (!checkLegacy(key)) return null; + + Object o = super.putIfAbsent(key, value); + if (o == null && key instanceof String sk && + value instanceof String sv) { + parseLegacy(sk, sv, OPType.ADD); } - return super.putIfAbsent(key, value); + return o; } private void implClear() { - if (legacyStrings != null) { - legacyStrings.clear(); - } - if (legacyMap != null) { - legacyMap.clear(); - } + legacyMap.clear(); serviceMap.clear(); legacyChanged = false; servicesChanged = false; serviceSet = null; - prngAlgos = null; + prngAlgos.clear(); super.clear(); putId(); } @@ -1085,40 +1097,8 @@ public abstract class Provider extends Properties { boolean matches(String type, String algorithm) { return (this.type == type) && (this.originalAlgorithm == algorithm); } - } - - /** - * Ensure all the legacy String properties are fully parsed into - * service objects. - */ - private void ensureLegacyParsed() { - if (legacyChanged == false || (legacyStrings == null)) { - return; - } - serviceSet = null; - if (legacyMap == null) { - legacyMap = new ConcurrentHashMap<>(); - } else { - legacyMap.clear(); - } - for (Map.Entry entry : legacyStrings.entrySet()) { - parseLegacyPut(entry.getKey(), entry.getValue()); - } - removeInvalidServices(legacyMap); - legacyChanged = false; - } - - /** - * Remove all invalid services from the Map. Invalid services can only - * occur if the legacy properties are inconsistent or incomplete. - */ - private void removeInvalidServices(Map map) { - for (Iterator> t = - map.entrySet().iterator(); t.hasNext(); ) { - Service s = t.next().getValue(); - if (s.isValid() == false) { - t.remove(); - } + public String toString() { + return type + "." + algorithm; } } @@ -1140,67 +1120,127 @@ public abstract class Provider extends Properties { private static final String ALIAS_PREFIX_LOWER = "alg.alias."; private static final int ALIAS_LENGTH = ALIAS_PREFIX.length(); - private void parseLegacyPut(String name, String value) { + private static enum OPType { + ADD, REMOVE; + } + + private void parseLegacy(String name, String value, OPType opType) { + // alias if (name.toLowerCase(ENGLISH).startsWith(ALIAS_PREFIX_LOWER)) { // e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1"); // aliasKey ~ MessageDigest.SHA - String stdAlg = value; - String aliasKey = name.substring(ALIAS_LENGTH); - String[] typeAndAlg = getTypeAndAlgorithm(aliasKey); + String aliasKeyStr = name.substring(ALIAS_LENGTH); + String[] typeAndAlg = getTypeAndAlgorithm(aliasKeyStr); if (typeAndAlg == null) { return; } + legacyChanged = true; + Objects.requireNonNull(value, "alias value should map to an alg"); String type = getEngineName(typeAndAlg[0]); String aliasAlg = typeAndAlg[1].intern(); - ServiceKey key = new ServiceKey(type, stdAlg, true); - Service s = legacyMap.get(key); - if (s == null) { - s = new Service(this, type, stdAlg); - legacyMap.put(key, s); + ServiceKey stdKey = new ServiceKey(type, value, true); + Service stdService = legacyMap.get(stdKey); + ServiceKey aliasKey = new ServiceKey(type, aliasAlg, true); + switch (opType) { + case ADD: + // clean up old alias if present + Service prevAliasService = legacyMap.get(aliasKey); + if (prevAliasService != null) { + prevAliasService.removeAlias(aliasAlg); + } + if (stdService == null) { + // add standard mapping in order to add alias + stdService = new Service(this, type, value); + legacyMap.put(stdKey, stdService); + } + stdService.addAlias(aliasAlg); + legacyMap.put(aliasKey, stdService); + break; + case REMOVE: + if (stdService != null) { + stdService.removeAlias(aliasAlg); + } + legacyMap.remove(aliasKey); + break; + default: + throw new AssertionError(); } - legacyMap.put(new ServiceKey(type, aliasAlg, true), s); - s.addAlias(aliasAlg); } else { String[] typeAndAlg = getTypeAndAlgorithm(name); if (typeAndAlg == null) { return; } + legacyChanged = true; int i = typeAndAlg[1].indexOf(' '); + // regular registration if (i == -1) { // e.g. put("MessageDigest.SHA-1", "sun.security.provider.SHA"); String type = getEngineName(typeAndAlg[0]); String stdAlg = typeAndAlg[1].intern(); - String className = value; - ServiceKey key = new ServiceKey(type, stdAlg, true); - Service s = legacyMap.get(key); - if (s == null) { - s = new Service(this, type, stdAlg); - legacyMap.put(key, s); - } - s.className = className; - - if (type.equals("SecureRandom")) { - updateSecureRandomEntries(true, s.algorithm); + ServiceKey stdKey = new ServiceKey(type, stdAlg, true); + Service stdService = legacyMap.get(stdKey); + switch (opType) { + case ADD: + Objects.requireNonNull(value, + "className can't be null"); + if (stdService == null) { + stdService = new Service(this, type, stdAlg); + legacyMap.put(stdKey, stdService); + } + stdService.className = value; + break; + case REMOVE: + // only remove if value also matches when non-null + if (stdService != null) { + if (value == null) { + legacyMap.remove(stdKey); + } else if (stdService.className.equals(value)) { + legacyMap.remove(stdKey, stdService); + } + // remove all corresponding alias mappings + for (String alias : stdService.getAliases()) { + legacyMap.remove(new ServiceKey(type, alias, + true), stdService); + } + } + break; + default: + throw new AssertionError(); } + checkAndUpdateSecureRandom(type, stdAlg, + (opType != OPType.REMOVE)); } else { // attribute // e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software"); - String attributeValue = value; String type = getEngineName(typeAndAlg[0]); - String attributeString = typeAndAlg[1]; - String stdAlg = attributeString.substring(0, i).intern(); - String attributeName = attributeString.substring(i + 1); + String attrString = typeAndAlg[1]; + String stdAlg = attrString.substring(0, i).intern(); + String attrName = attrString.substring(i + 1); // kill additional spaces - while (attributeName.startsWith(" ")) { - attributeName = attributeName.substring(1); + while (attrName.startsWith(" ")) { + attrName = attrName.substring(1); } - attributeName = attributeName.intern(); - ServiceKey key = new ServiceKey(type, stdAlg, true); - Service s = legacyMap.get(key); - if (s == null) { - s = new Service(this, type, stdAlg); - legacyMap.put(key, s); + attrName = attrName.intern(); + ServiceKey stdKey = new ServiceKey(type, stdAlg, true); + Service stdService = legacyMap.get(stdKey); + switch (opType) { + case ADD: + Objects.requireNonNull(value, + "attribute value should not be null"); + + if (stdService == null) { + stdService = new Service(this, type, stdAlg); + legacyMap.put(stdKey, stdService); + } + stdService.addAttribute(attrName, value); + break; + case REMOVE: + if (stdService != null) { + stdService.removeAttribute(attrName, value); + } + break; + default: + throw new AssertionError(); } - s.addAttribute(attributeName, attributeValue); } } } @@ -1227,25 +1267,25 @@ public abstract class Provider extends Properties { */ public Service getService(String type, String algorithm) { checkInitialized(); - // avoid allocating a new ServiceKey object if possible ServiceKey key = previousKey; if (key.matches(type, algorithm) == false) { key = new ServiceKey(type, algorithm, false); previousKey = key; } - if (!serviceMap.isEmpty()) { - Service s = serviceMap.get(key); - if (s != null) { - return s; - } + + Service s = serviceMap.get(key); + if (s != null) { + return s; } - synchronized (this) { - ensureLegacyParsed(); - if (legacyMap != null && !legacyMap.isEmpty()) { - return legacyMap.get(key); - } + + s = legacyMap.get(key); + if (s != null && !s.isValid()) { + legacyMap.remove(key, s); + } else { + return s; } + return null; } @@ -1267,22 +1307,19 @@ public abstract class Provider extends Properties { * * @since 1.5 */ - public synchronized Set getServices() { + public Set getServices() { checkInitialized(); - if (legacyChanged || servicesChanged) { - serviceSet = null; - } - if (serviceSet == null) { - ensureLegacyParsed(); + if (serviceSet == null || legacyChanged || servicesChanged) { Set set = new LinkedHashSet<>(); if (!serviceMap.isEmpty()) { set.addAll(serviceMap.values()); } - if (legacyMap != null && !legacyMap.isEmpty()) { + if (!legacyMap.isEmpty()) { set.addAll(legacyMap.values()); } serviceSet = Collections.unmodifiableSet(set); servicesChanged = false; + legacyChanged = false; } return serviceSet; } @@ -1339,44 +1376,36 @@ public abstract class Provider extends Properties { servicesChanged = true; synchronized (this) { putPropertyStrings(s); - if (type.equals("SecureRandom")) { - updateSecureRandomEntries(true, s.algorithm); - } + checkAndUpdateSecureRandom(type, algorithm, true); } } - // keep tracks of the registered secure random algos and store them in order - private void updateSecureRandomEntries(boolean doAdd, String s) { - Objects.requireNonNull(s); - if (doAdd) { - if (prngAlgos == null) { - prngAlgos = new LinkedHashSet(); + private void checkAndUpdateSecureRandom(String type, String algo, + boolean doAdd) { + if (type.equalsIgnoreCase("SecureRandom")) { + if (doAdd) { + prngAlgos.add(algo); + } else { + prngAlgos.remove(algo); + } + if (debug != null) { + debug.println((doAdd? "Add":"Remove") + + " SecureRandom algo " + algo); } - prngAlgos.add(s); - } else { - prngAlgos.remove(s); - } - - if (debug != null) { - debug.println((doAdd? "Add":"Remove") + " SecureRandom algo " + s); } } // used by new SecureRandom() to find out the default SecureRandom // service for this provider - synchronized Service getDefaultSecureRandomService() { + Service getDefaultSecureRandomService() { checkInitialized(); - if (legacyChanged) { - prngAlgos = null; - ensureLegacyParsed(); - } - - if (prngAlgos != null && !prngAlgos.isEmpty()) { + if (!prngAlgos.isEmpty()) { + String algo = prngAlgos.iterator().next(); // IMPORTANT: use the Service obj returned by getService(...) call // as providers may override putService(...)/getService(...) and // return their own Service objects - return getService("SecureRandom", prngAlgos.iterator().next()); + return getService("SecureRandom", algo); } return null; @@ -1473,12 +1502,9 @@ public abstract class Provider extends Properties { for (String alias : s.getAliases()) { serviceMap.remove(new ServiceKey(type, alias, false)); } - synchronized (this) { - removePropertyStrings(s); - if (type.equals("SecureRandom")) { - updateSecureRandomEntries(false, s.algorithm); - } - } + + removePropertyStrings(s); + checkAndUpdateSecureRandom(type, algorithm, false); } // Wrapped String that behaves in a case insensitive way for equals/hashCode @@ -1513,21 +1539,12 @@ public abstract class Provider extends Properties { final String name; final boolean supportsParameter; final String constructorParameterClassName; - private volatile Class constructorParameterClass; EngineDescription(String name, boolean sp, String paramName) { this.name = name; this.supportsParameter = sp; this.constructorParameterClassName = paramName; } - Class getConstructorParameterClass() throws ClassNotFoundException { - Class clazz = constructorParameterClass; - if (clazz == null) { - clazz = Class.forName(constructorParameterClassName); - constructorParameterClass = clazz; - } - return clazz; - } } // built in knowledge of the engine types shipped as part of the JDK @@ -1686,6 +1703,13 @@ public abstract class Provider extends Properties { aliases.add(alias); } + private void removeAlias(String alias) { + if (aliases.isEmpty()) { + return; + } + aliases.remove(alias); + } + void addAttribute(String type, String value) { if (attributes.isEmpty()) { attributes = new HashMap<>(8); @@ -1693,6 +1717,17 @@ public abstract class Provider extends Properties { attributes.put(new UString(type), value); } + void removeAttribute(String type, String value) { + if (attributes.isEmpty()) { + return; + } + if (value == null) { + attributes.remove(new UString(type)); + } else { + attributes.remove(new UString(type), value); + } + } + /** * Construct a new service. * diff --git a/src/java.base/share/classes/java/security/Security.java b/src/java.base/share/classes/java/security/Security.java index 2ee706c2448ed6b72070b980b336b39a5cbc3b65..352dc5e7fac242fae09b8c1f1c531d32dcba8655 100644 --- a/src/java.base/share/classes/java/security/Security.java +++ b/src/java.base/share/classes/java/security/Security.java @@ -91,8 +91,7 @@ public final class Security { if (propFile.exists()) { InputStream is = null; try { - FileInputStream fis = new FileInputStream(propFile); - is = new BufferedInputStream(fis); + is = new FileInputStream(propFile); props.load(is); loadedProps = true; @@ -140,7 +139,7 @@ public final class Security { // now load the user-specified file so its values // will win if they conflict with the earlier values if (extraPropFile != null) { - BufferedInputStream bis = null; + InputStream is = null; try { URL propURL; @@ -152,8 +151,8 @@ public final class Security { } else { propURL = new URL(extraPropFile); } - bis = new BufferedInputStream(propURL.openStream()); - props.load(bis); + is = propURL.openStream(); + props.load(is); loadedProps = true; if (sdebug != null) { @@ -172,9 +171,9 @@ public final class Security { e.printStackTrace(); } } finally { - if (bis != null) { + if (is != null) { try { - bis.close(); + is.close(); } catch (IOException ioe) { if (sdebug != null) { sdebug.println("unable to close input stream"); diff --git a/src/java.base/share/classes/java/security/cert/PKIXCertPathBuilderResult.java b/src/java.base/share/classes/java/security/cert/PKIXCertPathBuilderResult.java index 01cedffe9c86bec98e103554e89518a4802b3a51..4812e380bb33784b5d5d69ea722d6505094b0d9e 100644 --- a/src/java.base/share/classes/java/security/cert/PKIXCertPathBuilderResult.java +++ b/src/java.base/share/classes/java/security/cert/PKIXCertPathBuilderResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -110,8 +110,8 @@ public class PKIXCertPathBuilderResult extends PKIXCertPathValidatorResult StringBuilder sb = new StringBuilder(); sb.append("PKIXCertPathBuilderResult: [\n"); sb.append(" Certification Path: " + certPath + "\n"); - sb.append(" Trust Anchor: " + getTrustAnchor().toString() + "\n"); - sb.append(" Policy Tree: " + String.valueOf(getPolicyTree()) + "\n"); + sb.append(" Trust Anchor: " + getTrustAnchor() + "\n"); + sb.append(" Policy Tree: " + getPolicyTree() + "\n"); sb.append(" Subject Public Key: " + getPublicKey() + "\n"); sb.append("]"); return sb.toString(); diff --git a/src/java.base/share/classes/java/security/cert/PKIXCertPathValidatorResult.java b/src/java.base/share/classes/java/security/cert/PKIXCertPathValidatorResult.java index 3ba1e335a5495be02b353008ad8d0aa08a4c0f16..5552078ff5cb5f73f49129367312d8fcbf163c24 100644 --- a/src/java.base/share/classes/java/security/cert/PKIXCertPathValidatorResult.java +++ b/src/java.base/share/classes/java/security/cert/PKIXCertPathValidatorResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -150,8 +150,8 @@ public class PKIXCertPathValidatorResult implements CertPathValidatorResult { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("PKIXCertPathValidatorResult: [\n"); - sb.append(" Trust Anchor: " + trustAnchor.toString() + "\n"); - sb.append(" Policy Tree: " + String.valueOf(policyTree) + "\n"); + sb.append(" Trust Anchor: " + trustAnchor + "\n"); + sb.append(" Policy Tree: " + policyTree + "\n"); sb.append(" Subject Public Key: " + subjectPublicKey + "\n"); sb.append("]"); return sb.toString(); diff --git a/src/java.base/share/classes/java/security/cert/PKIXParameters.java b/src/java.base/share/classes/java/security/cert/PKIXParameters.java index d29269e9c42bb31f41941b56f8aa0494d4e9e00f..88e77f0b6cfa936b7b25f13f06d3a8be67b44374 100644 --- a/src/java.base/share/classes/java/security/cert/PKIXParameters.java +++ b/src/java.base/share/classes/java/security/cert/PKIXParameters.java @@ -696,8 +696,7 @@ public class PKIXParameters implements CertPathParameters { /* start with trusted anchor info */ if (unmodTrustAnchors != null) { - sb.append(" Trust Anchors: " + unmodTrustAnchors.toString() - + "\n"); + sb.append(" Trust Anchors: " + unmodTrustAnchors + "\n"); } /* now, append initial state information */ @@ -706,13 +705,13 @@ public class PKIXParameters implements CertPathParameters { sb.append(" Initial Policy OIDs: any\n"); } else { sb.append(" Initial Policy OIDs: [" - + unmodInitialPolicies.toString() + "]\n"); + + unmodInitialPolicies + "]\n"); } } /* now, append constraints on all certificates in the path */ - sb.append(" Validity Date: " + String.valueOf(date) + "\n"); - sb.append(" Signature Provider: " + String.valueOf(sigProvider) + "\n"); + sb.append(" Validity Date: " + date + "\n"); + sb.append(" Signature Provider: " + sigProvider + "\n"); sb.append(" Default Revocation Enabled: " + revocationEnabled + "\n"); sb.append(" Explicit Policy Required: " + explicitPolicyRequired + "\n"); sb.append(" Policy Mapping Inhibited: " + policyMappingInhibited + "\n"); @@ -720,14 +719,14 @@ public class PKIXParameters implements CertPathParameters { sb.append(" Policy Qualifiers Rejected: " + policyQualifiersRejected + "\n"); /* now, append target cert requirements */ - sb.append(" Target Cert Constraints: " + String.valueOf(certSelector) + "\n"); + sb.append(" Target Cert Constraints: " + certSelector + "\n"); /* finally, append miscellaneous parameters */ if (certPathCheckers != null) sb.append(" Certification Path Checkers: [" - + certPathCheckers.toString() + "]\n"); + + certPathCheckers + "]\n"); if (certStores != null) - sb.append(" CertStores: [" + certStores.toString() + "]\n"); + sb.append(" CertStores: [" + certStores + "]\n"); sb.append("]"); return sb.toString(); } diff --git a/src/java.base/share/classes/java/security/cert/TrustAnchor.java b/src/java.base/share/classes/java/security/cert/TrustAnchor.java index f026bea41790b726be764ceb703003e3e37500cf..ab60b5cbd9ae6828e4805ff6e4a61a7f3d300927 100644 --- a/src/java.base/share/classes/java/security/cert/TrustAnchor.java +++ b/src/java.base/share/classes/java/security/cert/TrustAnchor.java @@ -323,14 +323,13 @@ public class TrustAnchor { StringBuilder sb = new StringBuilder(); sb.append("[\n"); if (pubKey != null) { - sb.append(" Trusted CA Public Key: " + pubKey.toString() + "\n"); - sb.append(" Trusted CA Issuer Name: " - + String.valueOf(caName) + "\n"); + sb.append(" Trusted CA Public Key: " + pubKey + "\n"); + sb.append(" Trusted CA Issuer Name: " + caName + "\n"); } else { - sb.append(" Trusted CA cert: " + trustedCert.toString() + "\n"); + sb.append(" Trusted CA cert: " + trustedCert + "\n"); } if (nc != null) - sb.append(" Name Constraints: " + nc.toString() + "\n"); + sb.append(" Name Constraints: " + nc + "\n"); return sb.toString(); } diff --git a/src/java.base/share/classes/java/security/cert/X509CertSelector.java b/src/java.base/share/classes/java/security/cert/X509CertSelector.java index 86c516191a956607ec8048ca12d82d0f4736d1b0..5a25ba5927f1a9f1815b7c0cd9375e56810cf34c 100644 --- a/src/java.base/share/classes/java/security/cert/X509CertSelector.java +++ b/src/java.base/share/classes/java/security/cert/X509CertSelector.java @@ -1763,10 +1763,10 @@ public class X509CertSelector implements CertSelector { StringBuilder sb = new StringBuilder(); sb.append("X509CertSelector: [\n"); if (x509Cert != null) { - sb.append(" Certificate: " + x509Cert.toString() + "\n"); + sb.append(" Certificate: " + x509Cert + "\n"); } if (serialNumber != null) { - sb.append(" Serial Number: " + serialNumber.toString() + "\n"); + sb.append(" Serial Number: " + serialNumber + "\n"); } if (issuer != null) { sb.append(" Issuer: " + getIssuerAsString() + "\n"); @@ -1775,7 +1775,7 @@ public class X509CertSelector implements CertSelector { sb.append(" Subject: " + getSubjectAsString() + "\n"); } sb.append(" matchAllSubjectAltNames flag: " - + String.valueOf(matchAllSubjectAltNames) + "\n"); + + matchAllSubjectAltNames + "\n"); if (subjectAlternativeNames != null) { sb.append(" SubjectAlternativeNames:\n"); for (List list : subjectAlternativeNames) { @@ -1795,29 +1795,29 @@ public class X509CertSelector implements CertSelector { } if (certificateValid != null) { sb.append(" Certificate Valid: " + - certificateValid.toString() + "\n"); + certificateValid + "\n"); } if (privateKeyValid != null) { sb.append(" Private Key Valid: " + - privateKeyValid.toString() + "\n"); + privateKeyValid + "\n"); } if (subjectPublicKeyAlgID != null) { sb.append(" Subject Public Key AlgID: " + - subjectPublicKeyAlgID.toString() + "\n"); + subjectPublicKeyAlgID + "\n"); } if (subjectPublicKey != null) { sb.append(" Subject Public Key: " + - subjectPublicKey.toString() + "\n"); + subjectPublicKey + "\n"); } if (keyUsage != null) { sb.append(" Key Usage: " + keyUsageToString(keyUsage) + "\n"); } if (keyPurposeSet != null) { sb.append(" Extended Key Usage: " + - keyPurposeSet.toString() + "\n"); + keyPurposeSet + "\n"); } if (policy != null) { - sb.append(" Policy: " + policy.toString() + "\n"); + sb.append(" Policy: " + policy + "\n"); } if (pathToGeneralNames != null) { sb.append(" Path to names:\n"); @@ -2145,7 +2145,7 @@ public class X509CertSelector implements CertSelector { debug.println("X509CertSelector.match: private key usage not " + "within validity date; ext.NOT_BEFORE: " + time + "; X509CertSelector: " - + this.toString()); + + this); e2.printStackTrace(); } return false; @@ -2153,7 +2153,7 @@ public class X509CertSelector implements CertSelector { if (debug != null) { debug.println("X509CertSelector.match: IOException in " + "private key usage check; X509CertSelector: " - + this.toString()); + + this); e4.printStackTrace(); } return false; diff --git a/src/java.base/share/classes/java/text/AttributedCharacterIterator.java b/src/java.base/share/classes/java/text/AttributedCharacterIterator.java index 31b5b7d8d3c64a82dee99978d8c1ba739b87836a..6a2f33630e0181e1c8ef5be8d7a7573d50917021 100644 --- a/src/java.base/share/classes/java/text/AttributedCharacterIterator.java +++ b/src/java.base/share/classes/java/text/AttributedCharacterIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,15 +67,15 @@ import java.util.Set; * *

      * Attribute keys are instances of {@link AttributedCharacterIterator.Attribute} and its - * subclasses, such as {@link java.awt.font.TextAttribute}. + * subclasses, such as {@link java.desktop/java.awt.font.TextAttribute}. * * @see AttributedCharacterIterator.Attribute - * @see java.awt.font.TextAttribute + * @see java.desktop/java.awt.font.TextAttribute * @see AttributedString * @see Annotation * @since 1.2 */ - +@SuppressWarnings("doclint:reference") // cross-module links public interface AttributedCharacterIterator extends CharacterIterator { /** diff --git a/src/java.base/share/classes/java/text/Bidi.java b/src/java.base/share/classes/java/text/Bidi.java index 00a878e1c6425c129ce52a9b6208681d5092e9e8..2ec7bea6988cf9d2fe8f1ce0c3b5154041959b13 100644 --- a/src/java.base/share/classes/java/text/Bidi.java +++ b/src/java.base/share/classes/java/text/Bidi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,10 +121,11 @@ public final class Bidi { * * @param paragraph a paragraph of text with optional character and paragraph attribute information * - * @see java.awt.font.TextAttribute#BIDI_EMBEDDING - * @see java.awt.font.TextAttribute#NUMERIC_SHAPING - * @see java.awt.font.TextAttribute#RUN_DIRECTION + * @see java.desktop/java.awt.font.TextAttribute#BIDI_EMBEDDING + * @see java.desktop/java.awt.font.TextAttribute#NUMERIC_SHAPING + * @see java.desktop/java.awt.font.TextAttribute#RUN_DIRECTION */ + @SuppressWarnings("doclint:reference") // cross-module links public Bidi(AttributedCharacterIterator paragraph) { if (paragraph == null) { throw new IllegalArgumentException("paragraph is null"); diff --git a/src/java.base/share/classes/java/text/MessageFormat.java b/src/java.base/share/classes/java/text/MessageFormat.java index e304d072411401b427f7c169179dbed2113e8372..98f9d1a144d91389cc3d0a9931528704e00b4610 100644 --- a/src/java.base/share/classes/java/text/MessageFormat.java +++ b/src/java.base/share/classes/java/text/MessageFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -778,7 +778,7 @@ public class MessageFormat extends Format { * {@code null} or has fewer than argumentIndex+1 elements. * * - * + * * * *
      Examples of subformat,argument,and formatted textExamples of subformat, argument, and formatted text
      Subformat diff --git a/src/java.base/share/classes/java/time/chrono/HijrahChronology.java b/src/java.base/share/classes/java/time/chrono/HijrahChronology.java index 87f307e15d3c878d46dc9a6009868fb293eec30a..1ce99906708aa197d0ec4e95c6cd4b8446e490e0 100644 --- a/src/java.base/share/classes/java/time/chrono/HijrahChronology.java +++ b/src/java.base/share/classes/java/time/chrono/HijrahChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -533,18 +533,14 @@ public final class HijrahChronology extends AbstractChronology implements Serial @Override public ValueRange range(ChronoField field) { checkCalendarInit(); - if (field instanceof ChronoField) { - ChronoField f = field; - return switch (f) { - case DAY_OF_MONTH -> ValueRange.of(1, 1, getMinimumMonthLength(), getMaximumMonthLength()); - case DAY_OF_YEAR -> ValueRange.of(1, getMaximumDayOfYear()); - case ALIGNED_WEEK_OF_MONTH -> ValueRange.of(1, 5); - case YEAR, YEAR_OF_ERA -> ValueRange.of(getMinimumYear(), getMaximumYear()); - case ERA -> ValueRange.of(1, 1); - default -> field.range(); - }; - } - return field.range(); + return switch (field) { + case DAY_OF_MONTH -> ValueRange.of(1, 1, getMinimumMonthLength(), getMaximumMonthLength()); + case DAY_OF_YEAR -> ValueRange.of(1, getMaximumDayOfYear()); + case ALIGNED_WEEK_OF_MONTH -> ValueRange.of(1, 5); + case YEAR, YEAR_OF_ERA -> ValueRange.of(getMinimumYear(), getMaximumYear()); + case ERA -> ValueRange.of(1, 1); + default -> field.range(); + }; } //----------------------------------------------------------------------- diff --git a/src/java.base/share/classes/java/util/Calendar.java b/src/java.base/share/classes/java/util/Calendar.java index 08954ac010430f33f2df80b8809acf8eb9724f09..5a31aade9187910721275db42558766105fadaa7 100644 --- a/src/java.base/share/classes/java/util/Calendar.java +++ b/src/java.base/share/classes/java/util/Calendar.java @@ -3416,8 +3416,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable t) ? 1 : (thisTime == t) ? 0 : -1; + return Long.compare(getMillisOf(this), t); } private static long getMillisOf(Calendar calendar) { diff --git a/src/java.base/share/classes/java/util/Date.java b/src/java.base/share/classes/java/util/Date.java index d0b31a4026848df7e1f6401f63a33964b21016aa..52b70b55d9876901e47a0b00b5e8f9fba75e1236 100644 --- a/src/java.base/share/classes/java/util/Date.java +++ b/src/java.base/share/classes/java/util/Date.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,13 @@ package java.util; import java.text.DateFormat; -import java.time.LocalDate; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; -import java.lang.ref.SoftReference; import java.time.Instant; import sun.util.calendar.BaseCalendar; -import sun.util.calendar.CalendarDate; import sun.util.calendar.CalendarSystem; import sun.util.calendar.CalendarUtils; -import sun.util.calendar.Era; -import sun.util.calendar.Gregorian; import sun.util.calendar.ZoneInfo; /** @@ -975,10 +970,9 @@ public class Date * @since 1.2 * @throws NullPointerException if {@code anotherDate} is null. */ + @Override public int compareTo(Date anotherDate) { - long thisTime = getMillisOf(this); - long anotherTime = getMillisOf(anotherDate); - return (thisTime // fixed string, "%n", or "%%" - fs.print(null, l); + fs.print(this, null, l); case -1 -> { // relative index if (last < 0 || (args != null && last > args.length - 1)) throw new MissingFormatArgumentException(fs.toString()); - fs.print((args == null ? null : args[last]), l); + fs.print(this, (args == null ? null : args[last]), l); } case 0 -> { // ordinary index lasto++; last = lasto; if (args != null && lasto > args.length - 1) throw new MissingFormatArgumentException(fs.toString()); - fs.print((args == null ? null : args[lasto]), l); + fs.print(this, (args == null ? null : args[lasto]), l); } default -> { // explicit index last = index - 1; if (args != null && last > args.length - 1) throw new MissingFormatArgumentException(fs.toString()); - fs.print((args == null ? null : args[last]), l); + fs.print(this, (args == null ? null : args[last]), l); } } } catch (IOException x) { @@ -2836,11 +2836,11 @@ public final class Formatter implements Closeable, Flushable { private interface FormatString { int index(); - void print(Object arg, Locale l) throws IOException; + void print(Formatter fmt, Object arg, Locale l) throws IOException; String toString(); } - private class FixedString implements FormatString { + private static class FixedString implements FormatString { private final String s; private final int start; private final int end; @@ -2850,8 +2850,8 @@ public final class Formatter implements Closeable, Flushable { this.end = end; } public int index() { return -2; } - public void print(Object arg, Locale l) - throws IOException { a.append(s, start, end); } + public void print(Formatter fmt, Object arg, Locale l) + throws IOException { fmt.a.append(s, start, end); } public String toString() { return s.substring(start, end); } } @@ -2870,10 +2870,10 @@ public final class Formatter implements Closeable, Flushable { DECIMAL_FLOAT }; - private class FormatSpecifier implements FormatString { + private static class FormatSpecifier implements FormatString { private int index = 0; - private Flags f = Flags.NONE; + private int flags = Flags.NONE; private int width = -1; private int precision = -1; private boolean dt = false; @@ -2898,8 +2898,8 @@ public final class Formatter implements Closeable, Flushable { } private void flags(String s, int start, int end) { - f = Flags.parse(s, start, end); - if (f.contains(Flags.PREVIOUS)) + flags = Flags.parse(s, start, end); + if (Flags.contains(flags, Flags.PREVIOUS)) index = -1; } @@ -2935,7 +2935,7 @@ public final class Formatter implements Closeable, Flushable { throw new UnknownFormatConversionException(String.valueOf(c)); } if (Character.isUpperCase(c)) { - f.add(Flags.UPPERCASE); + flags = Flags.add(flags, Flags.UPPERCASE); c = Character.toLowerCase(c); } if (Conversion.isText(c)) { @@ -2947,7 +2947,7 @@ public final class Formatter implements Closeable, Flushable { FormatSpecifier(char conv) { c = conv; if (Character.isUpperCase(conv)) { - f = Flags.UPPERCASE; + flags = Flags.UPPERCASE; c = Character.toLowerCase(conv); } if (Conversion.isText(conv)) { @@ -2965,7 +2965,7 @@ public final class Formatter implements Closeable, Flushable { if (tTStart >= 0) { dt = true; if (s.charAt(tTStart) == 'T') { - f.add(Flags.UPPERCASE); + flags = Flags.add(flags, Flags.UPPERCASE); } } conversion(s.charAt(m.start(6))); @@ -2986,79 +2986,79 @@ public final class Formatter implements Closeable, Flushable { throw new UnknownFormatConversionException(String.valueOf(c)); } - public void print(Object arg, Locale l) throws IOException { + public void print(Formatter fmt, Object arg, Locale l) throws IOException { if (dt) { - printDateTime(arg, l); + printDateTime(fmt, arg, l); return; } switch(c) { case Conversion.DECIMAL_INTEGER: case Conversion.OCTAL_INTEGER: case Conversion.HEXADECIMAL_INTEGER: - printInteger(arg, l); + printInteger(fmt, arg, l); break; case Conversion.SCIENTIFIC: case Conversion.GENERAL: case Conversion.DECIMAL_FLOAT: case Conversion.HEXADECIMAL_FLOAT: - printFloat(arg, l); + printFloat(fmt, arg, l); break; case Conversion.CHARACTER: - printCharacter(arg, l); + printCharacter(fmt, arg, l); break; case Conversion.BOOLEAN: - printBoolean(arg, l); + printBoolean(fmt, arg, l); break; case Conversion.STRING: - printString(arg, l); + printString(fmt, arg, l); break; case Conversion.HASHCODE: - printHashCode(arg, l); + printHashCode(fmt, arg, l); break; case Conversion.LINE_SEPARATOR: - a.append(System.lineSeparator()); + fmt.a.append(System.lineSeparator()); break; case Conversion.PERCENT_SIGN: - print("%", l); + print(fmt, "%", l); break; default: assert false; } } - private void printInteger(Object arg, Locale l) throws IOException { + private void printInteger(Formatter fmt, Object arg, Locale l) throws IOException { if (arg == null) - print("null", l); + print(fmt, "null", l); else if (arg instanceof Byte) - print(((Byte)arg).byteValue(), l); + print(fmt, ((Byte)arg).byteValue(), l); else if (arg instanceof Short) - print(((Short)arg).shortValue(), l); + print(fmt, ((Short)arg).shortValue(), l); else if (arg instanceof Integer) - print(((Integer)arg).intValue(), l); + print(fmt, ((Integer)arg).intValue(), l); else if (arg instanceof Long) - print(((Long)arg).longValue(), l); + print(fmt, ((Long)arg).longValue(), l); else if (arg instanceof BigInteger) - print(((BigInteger)arg), l); + print(fmt, ((BigInteger)arg), l); else failConversion(c, arg); } - private void printFloat(Object arg, Locale l) throws IOException { + private void printFloat(Formatter fmt, Object arg, Locale l) throws IOException { if (arg == null) - print("null", l); + print(fmt, "null", l); else if (arg instanceof Float) - print(((Float)arg).floatValue(), l); + print(fmt, ((Float)arg).floatValue(), l); else if (arg instanceof Double) - print(((Double)arg).doubleValue(), l); + print(fmt, ((Double)arg).doubleValue(), l); else if (arg instanceof BigDecimal) - print(((BigDecimal)arg), l); + print(fmt, ((BigDecimal)arg), l); else failConversion(c, arg); } - private void printDateTime(Object arg, Locale l) throws IOException { + private void printDateTime(Formatter fmt, Object arg, Locale l) throws IOException { if (arg == null) { - print("null", l); + print(fmt, "null", l); return; } Calendar cal = null; @@ -3079,19 +3079,19 @@ public final class Formatter implements Closeable, Flushable { cal = (Calendar) ((Calendar) arg).clone(); cal.setLenient(true); } else if (arg instanceof TemporalAccessor) { - print((TemporalAccessor) arg, c, l); + print(fmt, (TemporalAccessor) arg, c, l); return; } else { failConversion(c, arg); } // Use the provided locale so that invocations of // localizedMagnitude() use optimizations for null. - print(cal, c, l); + print(fmt, cal, c, l); } - private void printCharacter(Object arg, Locale l) throws IOException { + private void printCharacter(Formatter fmt, Object arg, Locale l) throws IOException { if (arg == null) { - print("null", l); + print(fmt, "null", l); return; } String s = null; @@ -3118,26 +3118,25 @@ public final class Formatter implements Closeable, Flushable { } else { failConversion(c, arg); } - print(s, l); + print(fmt, s, l); } - private void printString(Object arg, Locale l) throws IOException { + private void printString(Formatter fmt, Object arg, Locale l) throws IOException { if (arg instanceof Formattable) { - Formatter fmt = Formatter.this; if (fmt.locale() != l) fmt = new Formatter(fmt.out(), l); - ((Formattable)arg).formatTo(fmt, f.valueOf(), width, precision); + ((Formattable)arg).formatTo(fmt, flags, width, precision); } else { - if (f.contains(Flags.ALTERNATE)) + if (Flags.contains(flags, Flags.ALTERNATE)) failMismatch(Flags.ALTERNATE, 's'); if (arg == null) - print("null", l); + print(fmt, "null", l); else - print(arg.toString(), l); + print(fmt, arg.toString(), l); } } - private void printBoolean(Object arg, Locale l) throws IOException { + private void printBoolean(Formatter fmt, Object arg, Locale l) throws IOException { String s; if (arg != null) s = ((arg instanceof Boolean) @@ -3145,22 +3144,22 @@ public final class Formatter implements Closeable, Flushable { : Boolean.toString(true)); else s = Boolean.toString(false); - print(s, l); + print(fmt, s, l); } - private void printHashCode(Object arg, Locale l) throws IOException { + private void printHashCode(Formatter fmt, Object arg, Locale l) throws IOException { String s = (arg == null ? "null" : Integer.toHexString(arg.hashCode())); - print(s, l); + print(fmt, s, l); } - private void print(String s, Locale l) throws IOException { + private void print(Formatter fmt, String s, Locale l) throws IOException { if (precision != -1 && precision < s.length()) s = s.substring(0, precision); - if (f.contains(Flags.UPPERCASE)) + if (Flags.contains(flags, Flags.UPPERCASE)) s = toUpperCaseWithLocale(s, l); - appendJustified(a, s); + appendJustified(fmt.a, s); } private String toUpperCaseWithLocale(String s, Locale l) { @@ -3173,7 +3172,7 @@ public final class Formatter implements Closeable, Flushable { a.append(cs); return; } - boolean padRight = f.contains(Flags.LEFT_JUSTIFY); + boolean padRight = Flags.contains(flags, Flags.LEFT_JUSTIFY); int sp = width - cs.length(); if (padRight) { a.append(cs); @@ -3189,8 +3188,7 @@ public final class Formatter implements Closeable, Flushable { public String toString() { StringBuilder sb = new StringBuilder("%"); // Flags.UPPERCASE is set internally for legal conversions. - Flags dupf = f.dup().remove(Flags.UPPERCASE); - sb.append(dupf.toString()); + sb.append(Flags.toString(Flags.remove(flags, Flags.UPPERCASE))); if (index > 0) sb.append(index).append('$'); if (width != -1) @@ -3198,21 +3196,21 @@ public final class Formatter implements Closeable, Flushable { if (precision != -1) sb.append('.').append(precision); if (dt) - sb.append(f.contains(Flags.UPPERCASE) ? 'T' : 't'); - sb.append(f.contains(Flags.UPPERCASE) + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? 'T' : 't'); + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? Character.toUpperCase(c) : c); return sb.toString(); } private void checkGeneral() { if ((c == Conversion.BOOLEAN || c == Conversion.HASHCODE) - && f.contains(Flags.ALTERNATE)) + && Flags.contains(flags, Flags.ALTERNATE)) failMismatch(Flags.ALTERNATE, c); // '-' requires a width - if (width == -1 && f.contains(Flags.LEFT_JUSTIFY)) + if (width == -1 && Flags.contains(flags, Flags.LEFT_JUSTIFY)) throw new MissingFormatWidthException(toString()); - checkBadFlags(Flags.PLUS, Flags.LEADING_SPACE, Flags.ZERO_PAD, - Flags.GROUP, Flags.PARENTHESES); + checkBadFlags(Flags.PLUS | Flags.LEADING_SPACE | Flags.ZERO_PAD | + Flags.GROUP | Flags.PARENTHESES); } private void checkDateTime() { @@ -3220,20 +3218,20 @@ public final class Formatter implements Closeable, Flushable { throw new IllegalFormatPrecisionException(precision); if (!DateTime.isValid(c)) throw new UnknownFormatConversionException("t" + c); - checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE, - Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES); + checkBadFlags(Flags.ALTERNATE | Flags.PLUS | Flags.LEADING_SPACE | + Flags.ZERO_PAD | Flags.GROUP | Flags.PARENTHESES); // '-' requires a width - if (width == -1 && f.contains(Flags.LEFT_JUSTIFY)) + if (width == -1 && Flags.contains(flags, Flags.LEFT_JUSTIFY)) throw new MissingFormatWidthException(toString()); } private void checkCharacter() { if (precision != -1) throw new IllegalFormatPrecisionException(precision); - checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE, - Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES); + checkBadFlags(Flags.ALTERNATE | Flags.PLUS | Flags.LEADING_SPACE | + Flags.ZERO_PAD | Flags.GROUP | Flags.PARENTHESES); // '-' requires a width - if (width == -1 && f.contains(Flags.LEFT_JUSTIFY)) + if (width == -1 && Flags.contains(flags, Flags.LEFT_JUSTIFY)) throw new MissingFormatWidthException(toString()); } @@ -3250,17 +3248,17 @@ public final class Formatter implements Closeable, Flushable { checkBadFlags(Flags.GROUP); } - private void checkBadFlags(Flags ... badFlags) { - for (Flags badFlag : badFlags) - if (f.contains(badFlag)) - failMismatch(badFlag, c); + private void checkBadFlags(int badFlags) { + if ((flags & badFlags) != 0) { + failMismatch(flags & badFlags, c); + } } private void checkFloat() { checkNumeric(); if (c == Conversion.DECIMAL_FLOAT) { } else if (c == Conversion.HEXADECIMAL_FLOAT) { - checkBadFlags(Flags.PARENTHESES, Flags.GROUP); + checkBadFlags(Flags.PARENTHESES | Flags.GROUP); } else if (c == Conversion.SCIENTIFIC) { checkBadFlags(Flags.GROUP); } else if (c == Conversion.GENERAL) { @@ -3277,13 +3275,13 @@ public final class Formatter implements Closeable, Flushable { // '-' and '0' require a width if (width == -1 - && (f.contains(Flags.LEFT_JUSTIFY) || f.contains(Flags.ZERO_PAD))) + && (Flags.containsAny(flags, Flags.LEFT_JUSTIFY | Flags.ZERO_PAD))) throw new MissingFormatWidthException(toString()); // bad combination - if ((f.contains(Flags.PLUS) && f.contains(Flags.LEADING_SPACE)) - || (f.contains(Flags.LEFT_JUSTIFY) && f.contains(Flags.ZERO_PAD))) - throw new IllegalFormatFlagsException(f.toString()); + if ((Flags.contains(flags, Flags.PLUS | Flags.LEADING_SPACE)) + || (Flags.contains(flags, Flags.LEFT_JUSTIFY | Flags.ZERO_PAD))) + throw new IllegalFormatFlagsException(Flags.toString(flags)); } private void checkText() { @@ -3291,35 +3289,35 @@ public final class Formatter implements Closeable, Flushable { throw new IllegalFormatPrecisionException(precision); switch (c) { case Conversion.PERCENT_SIGN: - if (f.valueOf() != Flags.LEFT_JUSTIFY.valueOf() - && f.valueOf() != Flags.NONE.valueOf()) - throw new IllegalFormatFlagsException(f.toString()); + if (flags != Flags.LEFT_JUSTIFY + && flags != Flags.NONE) + throw new IllegalFormatFlagsException(Flags.toString(flags)); // '-' requires a width - if (width == -1 && f.contains(Flags.LEFT_JUSTIFY)) + if (width == -1 && Flags.contains(flags, Flags.LEFT_JUSTIFY)) throw new MissingFormatWidthException(toString()); break; case Conversion.LINE_SEPARATOR: if (width != -1) throw new IllegalFormatWidthException(width); - if (f.valueOf() != Flags.NONE.valueOf()) - throw new IllegalFormatFlagsException(f.toString()); + if (flags != Flags.NONE) + throw new IllegalFormatFlagsException(Flags.toString(flags)); break; default: assert false; } } - private void print(byte value, Locale l) throws IOException { + private void print(Formatter fmt, byte value, Locale l) throws IOException { long v = value; if (value < 0 && (c == Conversion.OCTAL_INTEGER || c == Conversion.HEXADECIMAL_INTEGER)) { v += (1L << 8); } - print(v, l); + print(fmt, v, l); } - private void print(short value, Locale l) throws IOException { + private void print(Formatter fmt, short value, Locale l) throws IOException { long v = value; if (value < 0 && (c == Conversion.OCTAL_INTEGER @@ -3327,10 +3325,10 @@ public final class Formatter implements Closeable, Flushable { v += (1L << 16); assert v >= 0 : v; } - print(v, l); + print(fmt, v, l); } - private void print(int value, Locale l) throws IOException { + private void print(Formatter fmt, int value, Locale l) throws IOException { long v = value; if (value < 0 && (c == Conversion.OCTAL_INTEGER @@ -3338,10 +3336,10 @@ public final class Formatter implements Closeable, Flushable { v += (1L << 32); assert v >= 0 : v; } - print(v, l); + print(fmt, v, l); } - private void print(long value, Locale l) throws IOException { + private void print(Formatter fmt, long value, Locale l) throws IOException { StringBuilder sb = new StringBuilder(); @@ -3353,58 +3351,56 @@ public final class Formatter implements Closeable, Flushable { leadingSign(sb, neg); // the value - localizedMagnitude(sb, valueStr, neg ? 1 : 0, f, adjustWidth(width, f, neg), l); + localizedMagnitude(fmt, sb, valueStr, neg ? 1 : 0, flags, adjustWidth(width, flags, neg), l); // trailing sign indicator trailingSign(sb, neg); } else if (c == Conversion.OCTAL_INTEGER) { - checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE, - Flags.PLUS); + checkBadFlags(Flags.PARENTHESES | Flags.LEADING_SPACE | Flags.PLUS); String s = Long.toOctalString(value); - int len = (f.contains(Flags.ALTERNATE) + int len = (Flags.contains(flags, Flags.ALTERNATE) ? s.length() + 1 : s.length()); // apply ALTERNATE (radix indicator for octal) before ZERO_PAD - if (f.contains(Flags.ALTERNATE)) + if (Flags.contains(flags, Flags.ALTERNATE)) sb.append('0'); - if (f.contains(Flags.ZERO_PAD)) { + if (Flags.contains(flags, Flags.ZERO_PAD)) { trailingZeros(sb, width - len); } sb.append(s); } else if (c == Conversion.HEXADECIMAL_INTEGER) { - checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE, - Flags.PLUS); + checkBadFlags(Flags.PARENTHESES | Flags.LEADING_SPACE | Flags.PLUS); String s = Long.toHexString(value); - int len = (f.contains(Flags.ALTERNATE) + int len = (Flags.contains(flags, Flags.ALTERNATE) ? s.length() + 2 : s.length()); // apply ALTERNATE (radix indicator for hex) before ZERO_PAD - if (f.contains(Flags.ALTERNATE)) - sb.append(f.contains(Flags.UPPERCASE) ? "0X" : "0x"); - if (f.contains(Flags.ZERO_PAD)) { + if (Flags.contains(flags, Flags.ALTERNATE)) + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? "0X" : "0x"); + if (Flags.contains(flags, Flags.ZERO_PAD)) { trailingZeros(sb, width - len); } - if (f.contains(Flags.UPPERCASE)) + if (Flags.contains(flags, Flags.UPPERCASE)) s = toUpperCaseWithLocale(s, l); sb.append(s); } // justify based on width - appendJustified(a, sb); + appendJustified(fmt.a, sb); } // neg := val < 0 private StringBuilder leadingSign(StringBuilder sb, boolean neg) { if (!neg) { - if (f.contains(Flags.PLUS)) { + if (Flags.contains(flags, Flags.PLUS)) { sb.append('+'); - } else if (f.contains(Flags.LEADING_SPACE)) { + } else if (Flags.contains(flags, Flags.LEADING_SPACE)) { sb.append(' '); } } else { - if (f.contains(Flags.PARENTHESES)) + if (Flags.contains(flags, Flags.PARENTHESES)) sb.append('('); else sb.append('-'); @@ -3414,12 +3410,12 @@ public final class Formatter implements Closeable, Flushable { // neg := val < 0 private StringBuilder trailingSign(StringBuilder sb, boolean neg) { - if (neg && f.contains(Flags.PARENTHESES)) + if (neg && Flags.contains(flags, Flags.PARENTHESES)) sb.append(')'); return sb; } - private void print(BigInteger value, Locale l) throws IOException { + private void print(Formatter fmt, BigInteger value, Locale l) throws IOException { StringBuilder sb = new StringBuilder(); boolean neg = value.signum() == -1; BigInteger v = value.abs(); @@ -3429,20 +3425,20 @@ public final class Formatter implements Closeable, Flushable { // the value if (c == Conversion.DECIMAL_INTEGER) { - localizedMagnitude(sb, v.toString(), 0, f, adjustWidth(width, f, neg), l); + localizedMagnitude(fmt, sb, v.toString(), 0, flags, adjustWidth(width, flags, neg), l); } else if (c == Conversion.OCTAL_INTEGER) { String s = v.toString(8); int len = s.length() + sb.length(); - if (neg && f.contains(Flags.PARENTHESES)) + if (neg && Flags.contains(flags, Flags.PARENTHESES)) len++; // apply ALTERNATE (radix indicator for octal) before ZERO_PAD - if (f.contains(Flags.ALTERNATE)) { + if (Flags.contains(flags, Flags.ALTERNATE)) { len++; sb.append('0'); } - if (f.contains(Flags.ZERO_PAD)) { + if (Flags.contains(flags, Flags.ZERO_PAD)) { trailingZeros(sb, width - len); } sb.append(s); @@ -3450,18 +3446,18 @@ public final class Formatter implements Closeable, Flushable { String s = v.toString(16); int len = s.length() + sb.length(); - if (neg && f.contains(Flags.PARENTHESES)) + if (neg && Flags.contains(flags, Flags.PARENTHESES)) len++; // apply ALTERNATE (radix indicator for hex) before ZERO_PAD - if (f.contains(Flags.ALTERNATE)) { + if (Flags.contains(flags, Flags.ALTERNATE)) { len += 2; - sb.append(f.contains(Flags.UPPERCASE) ? "0X" : "0x"); + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? "0X" : "0x"); } - if (f.contains(Flags.ZERO_PAD)) { + if (Flags.contains(flags, Flags.ZERO_PAD)) { trailingZeros(sb, width - len); } - if (f.contains(Flags.UPPERCASE)) + if (Flags.contains(flags, Flags.UPPERCASE)) s = toUpperCaseWithLocale(s, l); sb.append(s); } @@ -3470,14 +3466,14 @@ public final class Formatter implements Closeable, Flushable { trailingSign(sb, (value.signum() == -1)); // justify based on width - appendJustified(a, sb); + appendJustified(fmt.a, sb); } - private void print(float value, Locale l) throws IOException { - print((double) value, l); + private void print(Formatter fmt, float value, Locale l) throws IOException { + print(fmt, (double) value, l); } - private void print(double value, Locale l) throws IOException { + private void print(Formatter fmt, double value, Locale l) throws IOException { StringBuilder sb = new StringBuilder(); boolean neg = Double.compare(value, 0.0) == -1; @@ -3489,24 +3485,24 @@ public final class Formatter implements Closeable, Flushable { // the value if (!Double.isInfinite(v)) - print(sb, v, l, f, c, precision, neg); + print(fmt, sb, v, l, flags, c, precision, neg); else - sb.append(f.contains(Flags.UPPERCASE) + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? "INFINITY" : "Infinity"); // trailing sign indicator trailingSign(sb, neg); } else { - sb.append(f.contains(Flags.UPPERCASE) ? "NAN" : "NaN"); + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? "NAN" : "NaN"); } // justify based on width - appendJustified(a, sb); + appendJustified(fmt.a, sb); } // !Double.isInfinite(value) && !Double.isNaN(value) - private void print(StringBuilder sb, double value, Locale l, - Flags f, char c, int precision, boolean neg) + private void print(Formatter fmt, StringBuilder sb, double value, Locale l, + int flags, char c, int precision, boolean neg) throws IOException { if (c == Conversion.SCIENTIFIC) { @@ -3523,7 +3519,7 @@ public final class Formatter implements Closeable, Flushable { // If the precision is zero and the '#' flag is set, add the // requested decimal point. - if (f.contains(Flags.ALTERNATE) && (prec == 0)) { + if (Flags.contains(flags, Flags.ALTERNATE) && (prec == 0)) { mant.append('.'); } @@ -3532,17 +3528,17 @@ public final class Formatter implements Closeable, Flushable { int newW = width; if (width != -1) { - newW = adjustWidth(width - exp.length - 1, f, neg); + newW = adjustWidth(width - exp.length - 1, flags, neg); } - localizedMagnitude(sb, mant, 0, f, newW, l); + localizedMagnitude(fmt, sb, mant, 0, flags, newW, l); - sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e'); + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? 'E' : 'e'); char sign = exp[0]; assert(sign == '+' || sign == '-'); sb.append(sign); - localizedMagnitudeExp(sb, exp, 1, l); + localizedMagnitudeExp(fmt, sb, exp, 1, l); } else if (c == Conversion.DECIMAL_FLOAT) { // Create a new FormattedFloatingDecimal with the desired // precision. @@ -3557,13 +3553,13 @@ public final class Formatter implements Closeable, Flushable { // If the precision is zero and the '#' flag is set, add the // requested decimal point. - if (f.contains(Flags.ALTERNATE) && (prec == 0)) + if (Flags.contains(flags, Flags.ALTERNATE) && (prec == 0)) mant.append('.'); int newW = width; if (width != -1) - newW = adjustWidth(width, f, neg); - localizedMagnitude(sb, mant, 0, f, newW, l); + newW = adjustWidth(width, flags, neg); + localizedMagnitude(fmt, sb, mant, 0, flags, newW, l); } else if (c == Conversion.GENERAL) { int prec = precision; if (precision == -1) @@ -3596,27 +3592,27 @@ public final class Formatter implements Closeable, Flushable { addZeros(mant, prec); // If the precision is zero and the '#' flag is set, add the // requested decimal point. - if (f.contains(Flags.ALTERNATE) && (prec == 0)) { + if (Flags.contains(flags, Flags.ALTERNATE) && (prec == 0)) { mant.append('.'); } int newW = width; if (width != -1) { if (exp != null) - newW = adjustWidth(width - exp.length - 1, f, neg); + newW = adjustWidth(width - exp.length - 1, flags, neg); else - newW = adjustWidth(width, f, neg); + newW = adjustWidth(width, flags, neg); } - localizedMagnitude(sb, mant, 0, f, newW, l); + localizedMagnitude(fmt, sb, mant, 0, flags, newW, l); if (exp != null) { - sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e'); + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? 'E' : 'e'); char sign = exp[0]; assert(sign == '+' || sign == '-'); sb.append(sign); - localizedMagnitudeExp(sb, exp, 1, l); + localizedMagnitudeExp(fmt, sb, exp, 1, l); } } else if (c == Conversion.HEXADECIMAL_FLOAT) { int prec = precision; @@ -3629,13 +3625,13 @@ public final class Formatter implements Closeable, Flushable { String s = hexDouble(value, prec); StringBuilder va = new StringBuilder(); - boolean upper = f.contains(Flags.UPPERCASE); + boolean upper = Flags.contains(flags, Flags.UPPERCASE); sb.append(upper ? "0X" : "0x"); - if (f.contains(Flags.ZERO_PAD)) { + if (Flags.contains(flags, Flags.ZERO_PAD)) { int leadingCharacters = 2; - if(f.contains(Flags.LEADING_SPACE) || - f.contains(Flags.PLUS) || neg) { + if(Flags.contains(flags, Flags.LEADING_SPACE) || + Flags.contains(flags, Flags.PLUS) || neg) { leadingCharacters = 3; } trailingZeros(sb, width - s.length() - leadingCharacters); @@ -3774,7 +3770,7 @@ public final class Formatter implements Closeable, Flushable { } } - private void print(BigDecimal value, Locale l) throws IOException { + private void print(Formatter fmt, BigDecimal value, Locale l) throws IOException { if (c == Conversion.HEXADECIMAL_FLOAT) failConversion(c, value); StringBuilder sb = new StringBuilder(); @@ -3784,18 +3780,18 @@ public final class Formatter implements Closeable, Flushable { leadingSign(sb, neg); // the value - print(sb, v, l, f, c, precision, neg); + print(fmt, sb, v, l, flags, c, precision, neg); // trailing sign indicator trailingSign(sb, neg); // justify based on width - appendJustified(a, sb); + appendJustified(fmt.a, sb); } // value > 0 - private void print(StringBuilder sb, BigDecimal value, Locale l, - Flags f, char c, int precision, boolean neg) + private void print(Formatter fmt, StringBuilder sb, BigDecimal value, Locale l, + int flags, char c, int precision, boolean neg) throws IOException { if (c == Conversion.SCIENTIFIC) { @@ -3829,7 +3825,7 @@ public final class Formatter implements Closeable, Flushable { // precision is one. Append a decimal point if '#' is set or if // we require zero padding to get to the requested precision. if ((origPrec == 1 || !bdl.hasDot()) - && (nzeros > 0 || (f.contains(Flags.ALTERNATE)))) { + && (nzeros > 0 || (Flags.contains(flags, Flags.ALTERNATE)))) { mant.append('.'); } @@ -3840,18 +3836,18 @@ public final class Formatter implements Closeable, Flushable { StringBuilder exp = bdl.exponent(); int newW = width; if (width != -1) { - newW = adjustWidth(width - exp.length() - 1, f, neg); + newW = adjustWidth(width - exp.length() - 1, flags, neg); } - localizedMagnitude(sb, mant, 0, f, newW, l); + localizedMagnitude(fmt, sb, mant, 0, flags, newW, l); - sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e'); + sb.append(Flags.contains(flags, Flags.UPPERCASE) ? 'E' : 'e'); - Flags flags = f.dup().remove(Flags.GROUP); + int adaptedFlags = Flags.remove(flags, Flags.GROUP); char sign = exp.charAt(0); assert(sign == '+' || sign == '-'); sb.append(sign); - sb.append(localizedMagnitude(null, exp, 1, flags, -1, l)); + sb.append(localizedMagnitude(fmt, null, exp, 1, adaptedFlags, -1, l)); } else if (c == Conversion.DECIMAL_FLOAT) { // Create a new BigDecimal with the desired precision. int prec = (precision == -1 ? 6 : precision); @@ -3883,7 +3879,7 @@ public final class Formatter implements Closeable, Flushable { // representation has no fractional part). Append a decimal // point if '#' is set or we require zero padding to get to the // requested precision. - if (bdl.scale() == 0 && (f.contains(Flags.ALTERNATE) + if (bdl.scale() == 0 && (Flags.contains(flags, Flags.ALTERNATE) || nzeros > 0)) { mant.append('.'); } @@ -3892,7 +3888,7 @@ public final class Formatter implements Closeable, Flushable { // number of available digits after the decimal separator. trailingZeros(mant, nzeros); - localizedMagnitude(sb, mant, 0, f, adjustWidth(width, f, neg), l); + localizedMagnitude(fmt, sb, mant, 0, flags, adjustWidth(width, flags, neg), l); } else if (c == Conversion.GENERAL) { int prec = precision; if (precision == -1) @@ -3920,10 +3916,10 @@ public final class Formatter implements Closeable, Flushable { // => f precision = g precision - exponent - 1 prec = prec - e - 1; - print(sb, value, l, f, Conversion.DECIMAL_FLOAT, prec, + print(fmt, sb, value, l, flags, Conversion.DECIMAL_FLOAT, prec, neg); } else { - print(sb, value, l, f, Conversion.SCIENTIFIC, prec - 1, neg); + print(fmt, sb, value, l, flags, Conversion.SCIENTIFIC, prec - 1, neg); } } else if (c == Conversion.HEXADECIMAL_FLOAT) { // This conversion isn't supported. The error should be @@ -4045,9 +4041,9 @@ public final class Formatter implements Closeable, Flushable { } } - private int adjustWidth(int width, Flags f, boolean neg) { + private int adjustWidth(int width, int flags, boolean neg) { int newW = width; - if (newW != -1 && neg && f.contains(Flags.PARENTHESES)) + if (newW != -1 && neg && Flags.contains(flags, Flags.PARENTHESES)) newW--; return newW; } @@ -4059,19 +4055,19 @@ public final class Formatter implements Closeable, Flushable { } } - private void print(Calendar t, char c, Locale l) throws IOException { + private void print(Formatter fmt, Calendar t, char c, Locale l) throws IOException { StringBuilder sb = new StringBuilder(); - print(sb, t, c, l); + print(fmt, sb, t, c, l); // justify based on width - if (f.contains(Flags.UPPERCASE)) { - appendJustified(a, toUpperCaseWithLocale(sb.toString(), l)); + if (Flags.contains(flags, Flags.UPPERCASE)) { + appendJustified(fmt.a, toUpperCaseWithLocale(sb.toString(), l)); } else { - appendJustified(a, sb); + appendJustified(fmt.a, sb); } } - private Appendable print(StringBuilder sb, Calendar t, char c, Locale l) + private Appendable print(Formatter fmt, StringBuilder sb, Calendar t, char c, Locale l) throws IOException { if (sb == null) sb = new StringBuilder(); @@ -4083,35 +4079,31 @@ public final class Formatter implements Closeable, Flushable { int i = t.get(Calendar.HOUR_OF_DAY); if (c == DateTime.HOUR_0 || c == DateTime.HOUR) i = (i == 0 || i == 12 ? 12 : i % 12); - Flags flags = (c == DateTime.HOUR_OF_DAY_0 + int flags = (c == DateTime.HOUR_OF_DAY_0 || c == DateTime.HOUR_0 ? Flags.ZERO_PAD : Flags.NONE); - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, flags, 2, l)); break; } case DateTime.MINUTE: { // 'M' (00 - 59) int i = t.get(Calendar.MINUTE); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 2, l)); break; } case DateTime.NANOSECOND: { // 'N' (000000000 - 999999999) int i = t.get(Calendar.MILLISECOND) * 1000000; - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 9, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 9, l)); break; } case DateTime.MILLISECOND: { // 'L' (000 - 999) int i = t.get(Calendar.MILLISECOND); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 3, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 3, l)); break; } case DateTime.MILLISECOND_SINCE_EPOCH: { // 'Q' (0 - 99...?) long i = t.getTimeInMillis(); - Flags flags = Flags.NONE; - sb.append(localizedMagnitude(null, i, flags, width, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.NONE, width, l)); break; } case DateTime.AM_PM: { // 'p' (am or pm) @@ -4128,14 +4120,12 @@ public final class Formatter implements Closeable, Flushable { } case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?) long i = t.getTimeInMillis() / 1000; - Flags flags = Flags.NONE; - sb.append(localizedMagnitude(null, i, flags, width, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.NONE, width, l)); break; } case DateTime.SECOND: { // 'S' (00 - 60 - leap second) int i = t.get(Calendar.SECOND); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 2, l)); break; } case DateTime.ZONE_NUMERIC: { // 'z' ({-|+}####) - ls minus? @@ -4147,9 +4137,8 @@ public final class Formatter implements Closeable, Flushable { int min = i / 60000; // combine minute and hour into a single integer int offset = (min / 60) * 100 + (min % 60); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, offset, flags, 4, l)); + sb.append(localizedMagnitude(fmt, null, offset, Flags.ZERO_PAD, 4, l)); break; } case DateTime.ZONE: { // 'Z' (symbol) @@ -4194,29 +4183,26 @@ public final class Formatter implements Closeable, Flushable { case DateTime.YEAR_2 -> i %= 100; case DateTime.YEAR_4 -> size = 4; } - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, size, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, size, l)); break; } case DateTime.DAY_OF_MONTH_0: // 'd' (01 - 31) case DateTime.DAY_OF_MONTH: { // 'e' (1 - 31) -- like d int i = t.get(Calendar.DATE); - Flags flags = (c == DateTime.DAY_OF_MONTH_0 + int flags = (c == DateTime.DAY_OF_MONTH_0 ? Flags.ZERO_PAD : Flags.NONE); - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, flags, 2, l)); break; } case DateTime.DAY_OF_YEAR: { // 'j' (001 - 366) int i = t.get(Calendar.DAY_OF_YEAR); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 3, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 3, l)); break; } case DateTime.MONTH: { // 'm' (01 - 12) int i = t.get(Calendar.MONTH) + 1; - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 2, l)); break; } @@ -4224,48 +4210,48 @@ public final class Formatter implements Closeable, Flushable { case DateTime.TIME: // 'T' (24 hour hh:mm:ss - %tH:%tM:%tS) case DateTime.TIME_24_HOUR: { // 'R' (hh:mm same as %H:%M) char sep = ':'; - print(sb, t, DateTime.HOUR_OF_DAY_0, l).append(sep); - print(sb, t, DateTime.MINUTE, l); + print(fmt, sb, t, DateTime.HOUR_OF_DAY_0, l).append(sep); + print(fmt, sb, t, DateTime.MINUTE, l); if (c == DateTime.TIME) { sb.append(sep); - print(sb, t, DateTime.SECOND, l); + print(fmt, sb, t, DateTime.SECOND, l); } break; } case DateTime.TIME_12_HOUR: { // 'r' (hh:mm:ss [AP]M) char sep = ':'; - print(sb, t, DateTime.HOUR_0, l).append(sep); - print(sb, t, DateTime.MINUTE, l).append(sep); - print(sb, t, DateTime.SECOND, l).append(' '); + print(fmt, sb, t, DateTime.HOUR_0, l).append(sep); + print(fmt, sb, t, DateTime.MINUTE, l).append(sep); + print(fmt, sb, t, DateTime.SECOND, l).append(' '); // this may be in wrong place for some locales StringBuilder tsb = new StringBuilder(); - print(tsb, t, DateTime.AM_PM, l); + print(fmt, tsb, t, DateTime.AM_PM, l); sb.append(toUpperCaseWithLocale(tsb.toString(), l)); break; } case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999) char sep = ' '; - print(sb, t, DateTime.NAME_OF_DAY_ABBREV, l).append(sep); - print(sb, t, DateTime.NAME_OF_MONTH_ABBREV, l).append(sep); - print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep); - print(sb, t, DateTime.TIME, l).append(sep); - print(sb, t, DateTime.ZONE, l).append(sep); - print(sb, t, DateTime.YEAR_4, l); + print(fmt, sb, t, DateTime.NAME_OF_DAY_ABBREV, l).append(sep); + print(fmt, sb, t, DateTime.NAME_OF_MONTH_ABBREV, l).append(sep); + print(fmt, sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep); + print(fmt, sb, t, DateTime.TIME, l).append(sep); + print(fmt, sb, t, DateTime.ZONE, l).append(sep); + print(fmt, sb, t, DateTime.YEAR_4, l); break; } case DateTime.DATE: { // 'D' (mm/dd/yy) char sep = '/'; - print(sb, t, DateTime.MONTH, l).append(sep); - print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep); - print(sb, t, DateTime.YEAR_2, l); + print(fmt, sb, t, DateTime.MONTH, l).append(sep); + print(fmt, sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep); + print(fmt, sb, t, DateTime.YEAR_2, l); break; } case DateTime.ISO_STANDARD_DATE: { // 'F' (%Y-%m-%d) char sep = '-'; - print(sb, t, DateTime.YEAR_4, l).append(sep); - print(sb, t, DateTime.MONTH, l).append(sep); - print(sb, t, DateTime.DAY_OF_MONTH_0, l); + print(fmt, sb, t, DateTime.YEAR_4, l).append(sep); + print(fmt, sb, t, DateTime.MONTH, l).append(sep); + print(fmt, sb, t, DateTime.DAY_OF_MONTH_0, l); break; } default: @@ -4274,18 +4260,18 @@ public final class Formatter implements Closeable, Flushable { return sb; } - private void print(TemporalAccessor t, char c, Locale l) throws IOException { + private void print(Formatter fmt, TemporalAccessor t, char c, Locale l) throws IOException { StringBuilder sb = new StringBuilder(); - print(sb, t, c, l); + print(fmt, sb, t, c, l); // justify based on width - if (f.contains(Flags.UPPERCASE)) { - appendJustified(a, toUpperCaseWithLocale(sb.toString(), l)); + if (Flags.contains(flags, Flags.UPPERCASE)) { + appendJustified(fmt.a, toUpperCaseWithLocale(sb.toString(), l)); } else { - appendJustified(a, sb); + appendJustified(fmt.a, sb); } } - private Appendable print(StringBuilder sb, TemporalAccessor t, char c, + private Appendable print(Formatter fmt, StringBuilder sb, TemporalAccessor t, char c, Locale l) throws IOException { if (sb == null) sb = new StringBuilder(); @@ -4293,28 +4279,27 @@ public final class Formatter implements Closeable, Flushable { switch (c) { case DateTime.HOUR_OF_DAY_0: { // 'H' (00 - 23) int i = t.get(ChronoField.HOUR_OF_DAY); - sb.append(localizedMagnitude(null, i, Flags.ZERO_PAD, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 2, l)); break; } case DateTime.HOUR_OF_DAY: { // 'k' (0 - 23) -- like H int i = t.get(ChronoField.HOUR_OF_DAY); - sb.append(localizedMagnitude(null, i, Flags.NONE, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.NONE, 2, l)); break; } case DateTime.HOUR_0: { // 'I' (01 - 12) int i = t.get(ChronoField.CLOCK_HOUR_OF_AMPM); - sb.append(localizedMagnitude(null, i, Flags.ZERO_PAD, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 2, l)); break; } case DateTime.HOUR: { // 'l' (1 - 12) -- like I int i = t.get(ChronoField.CLOCK_HOUR_OF_AMPM); - sb.append(localizedMagnitude(null, i, Flags.NONE, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.NONE, 2, l)); break; } case DateTime.MINUTE: { // 'M' (00 - 59) int i = t.get(ChronoField.MINUTE_OF_HOUR); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 2, l)); break; } case DateTime.NANOSECOND: { // 'N' (000000000 - 999999999) @@ -4324,21 +4309,18 @@ public final class Formatter implements Closeable, Flushable { } catch (UnsupportedTemporalTypeException u) { i = t.get(ChronoField.MILLI_OF_SECOND) * 1000000; } - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 9, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 9, l)); break; } case DateTime.MILLISECOND: { // 'L' (000 - 999) int i = t.get(ChronoField.MILLI_OF_SECOND); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 3, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 3, l)); break; } case DateTime.MILLISECOND_SINCE_EPOCH: { // 'Q' (0 - 99...?) long i = t.getLong(ChronoField.INSTANT_SECONDS) * 1000L + t.getLong(ChronoField.MILLI_OF_SECOND); - Flags flags = Flags.NONE; - sb.append(localizedMagnitude(null, i, flags, width, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.NONE, width, l)); break; } case DateTime.AM_PM: { // 'p' (am or pm) @@ -4355,14 +4337,12 @@ public final class Formatter implements Closeable, Flushable { } case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?) long i = t.getLong(ChronoField.INSTANT_SECONDS); - Flags flags = Flags.NONE; - sb.append(localizedMagnitude(null, i, flags, width, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.NONE, width, l)); break; } case DateTime.SECOND: { // 'S' (00 - 60 - leap second) int i = t.get(ChronoField.SECOND_OF_MINUTE); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 2, l)); break; } case DateTime.ZONE_NUMERIC: { // 'z' ({-|+}####) - ls minus? @@ -4374,8 +4354,7 @@ public final class Formatter implements Closeable, Flushable { int min = i / 60; // combine minute and hour into a single integer int offset = (min / 60) * 100 + (min % 60); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, offset, flags, 4, l)); + sb.append(localizedMagnitude(fmt, null, offset, Flags.ZERO_PAD, 4, l)); break; } case DateTime.ZONE: { // 'Z' (symbol) @@ -4429,29 +4408,26 @@ public final class Formatter implements Closeable, Flushable { case DateTime.YEAR_2 -> i %= 100; case DateTime.YEAR_4 -> size = 4; } - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, size, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, size, l)); break; } case DateTime.DAY_OF_MONTH_0: // 'd' (01 - 31) case DateTime.DAY_OF_MONTH: { // 'e' (1 - 31) -- like d int i = t.get(ChronoField.DAY_OF_MONTH); - Flags flags = (c == DateTime.DAY_OF_MONTH_0 + int flags = (c == DateTime.DAY_OF_MONTH_0 ? Flags.ZERO_PAD : Flags.NONE); - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, flags, 2, l)); break; } case DateTime.DAY_OF_YEAR: { // 'j' (001 - 366) int i = t.get(ChronoField.DAY_OF_YEAR); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 3, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 3, l)); break; } case DateTime.MONTH: { // 'm' (01 - 12) int i = t.get(ChronoField.MONTH_OF_YEAR); - Flags flags = Flags.ZERO_PAD; - sb.append(localizedMagnitude(null, i, flags, 2, l)); + sb.append(localizedMagnitude(fmt, null, i, Flags.ZERO_PAD, 2, l)); break; } @@ -4459,47 +4435,47 @@ public final class Formatter implements Closeable, Flushable { case DateTime.TIME: // 'T' (24 hour hh:mm:ss - %tH:%tM:%tS) case DateTime.TIME_24_HOUR: { // 'R' (hh:mm same as %H:%M) char sep = ':'; - print(sb, t, DateTime.HOUR_OF_DAY_0, l).append(sep); - print(sb, t, DateTime.MINUTE, l); + print(fmt, sb, t, DateTime.HOUR_OF_DAY_0, l).append(sep); + print(fmt, sb, t, DateTime.MINUTE, l); if (c == DateTime.TIME) { sb.append(sep); - print(sb, t, DateTime.SECOND, l); + print(fmt, sb, t, DateTime.SECOND, l); } break; } case DateTime.TIME_12_HOUR: { // 'r' (hh:mm:ss [AP]M) char sep = ':'; - print(sb, t, DateTime.HOUR_0, l).append(sep); - print(sb, t, DateTime.MINUTE, l).append(sep); - print(sb, t, DateTime.SECOND, l).append(' '); + print(fmt, sb, t, DateTime.HOUR_0, l).append(sep); + print(fmt, sb, t, DateTime.MINUTE, l).append(sep); + print(fmt, sb, t, DateTime.SECOND, l).append(' '); // this may be in wrong place for some locales StringBuilder tsb = new StringBuilder(); - print(tsb, t, DateTime.AM_PM, l); + print(fmt, tsb, t, DateTime.AM_PM, l); sb.append(toUpperCaseWithLocale(tsb.toString(), l)); break; } case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999) char sep = ' '; - print(sb, t, DateTime.NAME_OF_DAY_ABBREV, l).append(sep); - print(sb, t, DateTime.NAME_OF_MONTH_ABBREV, l).append(sep); - print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep); - print(sb, t, DateTime.TIME, l).append(sep); - print(sb, t, DateTime.ZONE, l).append(sep); - print(sb, t, DateTime.YEAR_4, l); + print(fmt, sb, t, DateTime.NAME_OF_DAY_ABBREV, l).append(sep); + print(fmt, sb, t, DateTime.NAME_OF_MONTH_ABBREV, l).append(sep); + print(fmt, sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep); + print(fmt, sb, t, DateTime.TIME, l).append(sep); + print(fmt, sb, t, DateTime.ZONE, l).append(sep); + print(fmt, sb, t, DateTime.YEAR_4, l); break; } case DateTime.DATE: { // 'D' (mm/dd/yy) char sep = '/'; - print(sb, t, DateTime.MONTH, l).append(sep); - print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep); - print(sb, t, DateTime.YEAR_2, l); + print(fmt, sb, t, DateTime.MONTH, l).append(sep); + print(fmt, sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep); + print(fmt, sb, t, DateTime.YEAR_2, l); break; } case DateTime.ISO_STANDARD_DATE: { // 'F' (%Y-%m-%d) char sep = '-'; - print(sb, t, DateTime.YEAR_4, l).append(sep); - print(sb, t, DateTime.MONTH, l).append(sep); - print(sb, t, DateTime.DAY_OF_MONTH_0, l); + print(fmt, sb, t, DateTime.YEAR_4, l).append(sep); + print(fmt, sb, t, DateTime.MONTH, l).append(sep); + print(fmt, sb, t, DateTime.DAY_OF_MONTH_0, l); break; } default: @@ -4513,8 +4489,8 @@ public final class Formatter implements Closeable, Flushable { // -- Methods to support throwing exceptions -- - private void failMismatch(Flags f, char c) { - String fs = f.toString(); + private void failMismatch(int f, char c) { + String fs = Flags.toString(f); throw new FormatFlagsConversionMismatchException(fs, c); } @@ -4522,28 +4498,28 @@ public final class Formatter implements Closeable, Flushable { throw new IllegalFormatConversionException(c, arg.getClass()); } - private char getZero(Locale l) { - if ((l != null) && !l.equals(locale())) { + private char getZero(Formatter fmt, Locale l) { + if ((l != null) && !l.equals(fmt.locale())) { DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l); return dfs.getZeroDigit(); } - return zero(); + return fmt.zero(); } - private StringBuilder localizedMagnitude(StringBuilder sb, - long value, Flags f, int width, Locale l) { - return localizedMagnitude(sb, Long.toString(value, 10), 0, f, width, l); + private StringBuilder localizedMagnitude(Formatter fmt, StringBuilder sb, + long value, int flags, int width, Locale l) { + return localizedMagnitude(fmt, sb, Long.toString(value, 10), 0, flags, width, l); } - private StringBuilder localizedMagnitude(StringBuilder sb, - CharSequence value, final int offset, Flags f, int width, + private StringBuilder localizedMagnitude(Formatter fmt, StringBuilder sb, + CharSequence value, final int offset, int f, int width, Locale l) { if (sb == null) { sb = new StringBuilder(); } int begin = sb.length(); - char zero = getZero(l); + char zero = getZero(fmt, l); // determine localized grouping separator and size char grpSep = '\0'; @@ -4568,7 +4544,7 @@ public final class Formatter implements Closeable, Flushable { } } - if (f.contains(Flags.GROUP)) { + if (Flags.contains(f, Flags.GROUP)) { if (l == null || l.equals(Locale.US)) { grpSep = ','; grpSize = 3; @@ -4622,7 +4598,7 @@ public final class Formatter implements Closeable, Flushable { } // apply zero padding - if (width != -1 && f.contains(Flags.ZERO_PAD)) { + if (width != -1 && Flags.contains(f, Flags.ZERO_PAD)) { for (int k = sb.length(); k < width; k++) { sb.insert(begin, zero); } @@ -4634,9 +4610,9 @@ public final class Formatter implements Closeable, Flushable { // Specialized localization of exponents, where the source value can only // contain characters '0' through '9', starting at index offset, and no // group separators is added for any locale. - private void localizedMagnitudeExp(StringBuilder sb, char[] value, + private void localizedMagnitudeExp(Formatter fmt, StringBuilder sb, char[] value, final int offset, Locale l) { - char zero = getZero(l); + char zero = getZero(fmt, l); int len = value.length; for (int j = offset; j < len; j++) { @@ -4647,65 +4623,54 @@ public final class Formatter implements Closeable, Flushable { } private static class Flags { - private int flags; - static final Flags NONE = new Flags(0); // '' + static final int NONE = 0; // '' // duplicate declarations from Formattable.java - static final Flags LEFT_JUSTIFY = new Flags(1<<0); // '-' - static final Flags UPPERCASE = new Flags(1<<1); // '^' - static final Flags ALTERNATE = new Flags(1<<2); // '#' + static final int LEFT_JUSTIFY = 1<<0; // '-' + static final int UPPERCASE = 1<<1; // '^' + static final int ALTERNATE = 1<<2; // '#' // numerics - static final Flags PLUS = new Flags(1<<3); // '+' - static final Flags LEADING_SPACE = new Flags(1<<4); // ' ' - static final Flags ZERO_PAD = new Flags(1<<5); // '0' - static final Flags GROUP = new Flags(1<<6); // ',' - static final Flags PARENTHESES = new Flags(1<<7); // '(' + static final int PLUS = 1<<3; // '+' + static final int LEADING_SPACE = 1<<4; // ' ' + static final int ZERO_PAD = 1<<5; // '0' + static final int GROUP = 1<<6; // ',' + static final int PARENTHESES = 1<<7; // '(' // indexing - static final Flags PREVIOUS = new Flags(1<<8); // '<' - - private Flags(int f) { - flags = f; - } - - public int valueOf() { - return flags; - } + static final int PREVIOUS = 1<<8; // '<' - public boolean contains(Flags f) { - return (flags & f.valueOf()) == f.valueOf(); + public static boolean contains(int flags, int f) { + return (flags & f) == f; } - public Flags dup() { - return new Flags(flags); + public static boolean containsAny(int flags, int f) { + return (flags & f) != 0; } - private Flags add(Flags f) { - flags |= f.valueOf(); - return this; + private static int add(int flags, int f) { + return flags | f; } - public Flags remove(Flags f) { - flags &= ~f.valueOf(); - return this; + public static int remove(int flags, int f) { + return flags & ~f; } - public static Flags parse(String s, int start, int end) { - Flags f = new Flags(0); + public static int parse(String s, int start, int end) { + int f = 0; for (int i = start; i < end; i++) { char c = s.charAt(i); - Flags v = parse(c); - if (f.contains(v)) - throw new DuplicateFormatFlagsException(v.toString()); - f.add(v); + int v = parse(c); + if (contains(f, v)) + throw new DuplicateFormatFlagsException(toString(v)); + f = add(f, v); } return f; } // parse those flags which may be provided by users - private static Flags parse(char c) { + private static int parse(char c) { return switch (c) { case '-' -> LEFT_JUSTIFY; case '#' -> ALTERNATE; @@ -4720,21 +4685,17 @@ public final class Formatter implements Closeable, Flushable { } // Returns a string representation of the current {@code Flags}. - public static String toString(Flags f) { - return f.toString(); - } - - public String toString() { + public static String toString(int f) { StringBuilder sb = new StringBuilder(); - if (contains(LEFT_JUSTIFY)) sb.append('-'); - if (contains(UPPERCASE)) sb.append('^'); - if (contains(ALTERNATE)) sb.append('#'); - if (contains(PLUS)) sb.append('+'); - if (contains(LEADING_SPACE)) sb.append(' '); - if (contains(ZERO_PAD)) sb.append('0'); - if (contains(GROUP)) sb.append(','); - if (contains(PARENTHESES)) sb.append('('); - if (contains(PREVIOUS)) sb.append('<'); + if (contains(f, LEFT_JUSTIFY)) sb.append('-'); + if (contains(f, UPPERCASE)) sb.append('^'); + if (contains(f, ALTERNATE)) sb.append('#'); + if (contains(f, PLUS)) sb.append('+'); + if (contains(f, LEADING_SPACE)) sb.append(' '); + if (contains(f, ZERO_PAD)) sb.append('0'); + if (contains(f, GROUP)) sb.append(','); + if (contains(f, PARENTHESES)) sb.append('('); + if (contains(f, PREVIOUS)) sb.append('<'); return sb.toString(); } } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index c103df557901fa506b4f829b25da578f59002a05..5d722879bc03f1633f8aa5444ff620978cad017f 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1254,7 +1254,7 @@ public class Hashtable * Reconstitute the Hashtable from a stream (i.e., deserialize it). */ @java.io.Serial - private void readObject(java.io.ObjectInputStream s) + private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { readHashtable(s); } @@ -1263,14 +1263,16 @@ public class Hashtable * Perform deserialization of the Hashtable from an ObjectInputStream. * The Properties class overrides this method. */ - void readHashtable(java.io.ObjectInputStream s) + void readHashtable(ObjectInputStream s) throws IOException, ClassNotFoundException { - // Read in the threshold and loadFactor - s.defaultReadObject(); - // Validate loadFactor (ignore threshold - it will be re-computed) - if (loadFactor <= 0 || Float.isNaN(loadFactor)) - throw new StreamCorruptedException("Illegal Load: " + loadFactor); + ObjectInputStream.GetField fields = s.readFields(); + + // Read and validate loadFactor (ignore threshold - it will be re-computed) + float lf = fields.get("loadFactor", 0.75f); + if (lf <= 0 || Float.isNaN(lf)) + throw new StreamCorruptedException("Illegal load factor: " + lf); + lf = Math.min(Math.max(0.25f, lf), 4.0f); // Read the original length of the array and number of elements int origlength = s.readInt(); @@ -1282,13 +1284,13 @@ public class Hashtable // Clamp original length to be more than elements / loadFactor // (this is the invariant enforced with auto-growth) - origlength = Math.max(origlength, (int)(elements / loadFactor) + 1); + origlength = Math.max(origlength, (int)(elements / lf) + 1); // Compute new length with a bit of room 5% + 3 to grow but // no larger than the clamped original length. Make the length // odd if it's large enough, this helps distribute the entries. // Guard against the length ending up zero, that's not valid. - int length = (int)((elements + elements / 20) / loadFactor) + 3; + int length = (int)(elements * 1.05f / lf) + 3; if (length > elements && (length & 1) == 0) length--; length = Math.min(length, origlength); @@ -1300,8 +1302,9 @@ public class Hashtable // Check Map.Entry[].class since it's the nearest public type to // what we're actually creating. SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length); + Hashtable.UnsafeHolder.putLoadFactor(this, lf); table = new Entry[length]; - threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); + threshold = (int)Math.min(length * lf, MAX_ARRAY_SIZE + 1); count = 0; // Read the number of elements and then all the key/value objects @@ -1315,6 +1318,18 @@ public class Hashtable } } + // Support for resetting final field during deserializing + private static final class UnsafeHolder { + private UnsafeHolder() { throw new InternalError(); } + private static final jdk.internal.misc.Unsafe unsafe + = jdk.internal.misc.Unsafe.getUnsafe(); + private static final long LF_OFFSET + = unsafe.objectFieldOffset(Hashtable.class, "loadFactor"); + static void putLoadFactor(Hashtable table, float lf) { + unsafe.putFloat(table, LF_OFFSET, lf); + } + } + /** * The put method used by readObject. This is provided because put * is overridable and should not be called in readObject since the diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 34d6722ac098f12b5b5a56dc7b594a5a5a66da8f..4795c30b3d5ee1595504dd0700d8656695a69474 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ package java.util; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.lang.reflect.Array; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -1267,12 +1269,12 @@ public class IdentityHashMap * particular order. */ @java.io.Serial - private void writeObject(java.io.ObjectOutputStream s) + private void writeObject(ObjectOutputStream s) throws java.io.IOException { - // Write out and any hidden stuff + // Write out size (number of mappings) and any hidden stuff s.defaultWriteObject(); - // Write out size (number of Mappings) + // Write out size again (maintained for backward compatibility) s.writeInt(size); // Write out keys and values (alternating) @@ -1291,18 +1293,20 @@ public class IdentityHashMap * deserializes it). */ @java.io.Serial - private void readObject(java.io.ObjectInputStream s) + private void readObject(ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { - // Read in any hidden stuff - s.defaultReadObject(); + // Size (number of mappings) is written to the stream twice + // Read first size value and ignore it + s.readFields(); - // Read in size (number of Mappings) + // Read second size value, validate and assign to size field int size = s.readInt(); if (size < 0) throw new java.io.StreamCorruptedException ("Illegal mappings count: " + size); int cap = capacity(size); - SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap); + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap*2); + this.size = size; init(cap); // Read the keys and values, and put the mappings in the table diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index 90a242984f1763f25ab0a22698c3d7c4b212d74b..2da179a5dd7b74b6144b3d2f027e9f2d14d65cda 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2003,7 +2003,7 @@ public final class Locale implements Cloneable, Serializable { /** * Returns a name for the locale that is appropriate for display * to the user. This will be the values returned by - * getDisplayLanguage(), getDisplayScript(),getDisplayCountry() + * getDisplayLanguage(), getDisplayScript(), getDisplayCountry(), * getDisplayVariant(), and optional * Unicode extensions assembled into a single string. The non-empty * values are used in order, with the second and subsequent names in diff --git a/src/java.base/share/classes/java/util/Objects.java b/src/java.base/share/classes/java/util/Objects.java index c32a67441da9d069c00f0d57fc6f2cc34427dade..0b727d6310b6b26af562476956d497150c595312 100644 --- a/src/java.base/share/classes/java/util/Objects.java +++ b/src/java.base/share/classes/java/util/Objects.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -164,6 +164,30 @@ public final class Objects { return (o != null) ? o.toString() : nullDefault; } + /** + * {@return a string equivalent to the string returned by {@code + * Object.toString} if that method and {@code hashCode} are not + * overridden} + * + * @implNote + * This method constructs a string for an object without calling + * any overridable methods of the object. + * + * @implSpec + * The method returns a string equivalent to:
      + * {@code o.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(o))} + * + * @param o an object + * @throws NullPointerException if the argument is null + * @see Object#toString + * @see System#identityHashCode(Object) + * @since 19 + */ + public static String toIdentityString(Object o) { + requireNonNull(o); + return o.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(o)); + } + /** * Returns 0 if the arguments are identical and {@code * c.compare(a, b)} otherwise. diff --git a/src/java.base/share/classes/java/util/Observable.java b/src/java.base/share/classes/java/util/Observable.java index d71bf5d5d4c3bb40b7cbed8b11a210a7a8751bc7..01956702c2d82f43eafe01d836e84437c8bc5675 100644 --- a/src/java.base/share/classes/java/util/Observable.java +++ b/src/java.base/share/classes/java/util/Observable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,13 +66,14 @@ package java.util; * {@code Observable} is unspecified, and state changes are not in * one-for-one correspondence with notifications. * For a richer event model, consider using the - * {@link java.beans} package. For reliable and ordered + * {@link java.desktop/java.beans} package. For reliable and ordered * messaging among threads, consider using one of the concurrent data * structures in the {@link java.util.concurrent} package. * For reactive streams style programming, see the * {@link java.util.concurrent.Flow} API. */ @Deprecated(since="9") +@SuppressWarnings("doclint:reference") // cross-module links public class Observable { private boolean changed = false; private Vector obs; diff --git a/src/java.base/share/classes/java/util/Optional.java b/src/java.base/share/classes/java/util/Optional.java index 64647ee49d5c18f34d083e959c564d14fedff069..cd8b2b6048fb60a32445aef0f7d22e92eb31f329 100644 --- a/src/java.base/share/classes/java/util/Optional.java +++ b/src/java.base/share/classes/java/util/Optional.java @@ -454,7 +454,7 @@ public final class Optional { @Override public String toString() { return value != null - ? String.format("Optional[%s]", value) + ? ("Optional[" + value + "]") : "Optional.empty"; } } diff --git a/src/java.base/share/classes/java/util/OptionalDouble.java b/src/java.base/share/classes/java/util/OptionalDouble.java index 61e54cfec2992c66db501b139c5722ef3f3e0b67..752aaac1e547ed28f69cafa9fbd38106825316b1 100644 --- a/src/java.base/share/classes/java/util/OptionalDouble.java +++ b/src/java.base/share/classes/java/util/OptionalDouble.java @@ -328,7 +328,7 @@ public final class OptionalDouble { @Override public String toString() { return isPresent - ? String.format("OptionalDouble[%s]", value) + ? ("OptionalDouble[" + value + "]") : "OptionalDouble.empty"; } } diff --git a/src/java.base/share/classes/java/util/OptionalInt.java b/src/java.base/share/classes/java/util/OptionalInt.java index d693a3ddba2fd109ef6b8f00377205d8f8babe18..c1e62090c25c5e10bb635dc5066bd81598f37aa5 100644 --- a/src/java.base/share/classes/java/util/OptionalInt.java +++ b/src/java.base/share/classes/java/util/OptionalInt.java @@ -326,7 +326,7 @@ public final class OptionalInt { @Override public String toString() { return isPresent - ? String.format("OptionalInt[%s]", value) + ? ("OptionalInt[" + value + "]") : "OptionalInt.empty"; } } diff --git a/src/java.base/share/classes/java/util/OptionalLong.java b/src/java.base/share/classes/java/util/OptionalLong.java index f92c5bdff175c34402c93523a7b513366ebf73f8..2c1171f86e9b763c7f63186113282b9a139b68d6 100644 --- a/src/java.base/share/classes/java/util/OptionalLong.java +++ b/src/java.base/share/classes/java/util/OptionalLong.java @@ -326,7 +326,7 @@ public final class OptionalLong { @Override public String toString() { return isPresent - ? String.format("OptionalLong[%s]", value) + ? ("OptionalLong[" + value + "]") : "OptionalLong.empty"; } } diff --git a/src/java.base/share/classes/java/util/ResourceBundle.java b/src/java.base/share/classes/java/util/ResourceBundle.java index 8f57d782d474b28276aca502aeb9e8fdc90a0627..052de0555c7bbdb01a6d1f0ac64d74755fc05d53 100644 --- a/src/java.base/share/classes/java/util/ResourceBundle.java +++ b/src/java.base/share/classes/java/util/ResourceBundle.java @@ -3729,7 +3729,7 @@ public abstract class ResourceBundle { } - private static final boolean TRACE_ON = Boolean.valueOf( + private static final boolean TRACE_ON = Boolean.parseBoolean( GetPropertyAction.privilegedGetProperty("resource.bundle.debug", "false")); private static void trace(String format, Object... params) { diff --git a/src/java.base/share/classes/java/util/ServiceLoader.java b/src/java.base/share/classes/java/util/ServiceLoader.java index 64b01c3157e3928b22621615997446d7ca43fbbe..531ffa3f09c785a5b6a8bef9fa1f8f3c14a2f99b 100644 --- a/src/java.base/share/classes/java/util/ServiceLoader.java +++ b/src/java.base/share/classes/java/util/ServiceLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1585,7 +1585,7 @@ public final class ServiceLoader * are located in the order that its module descriptor {@linkplain * java.lang.module.ModuleDescriptor.Provides#providers() lists the * providers}. Providers added dynamically by instrumentation agents (see - * {@link java.lang.instrument.Instrumentation#redefineModule redefineModule}) + * {@link java.instrument/java.lang.instrument.Instrumentation#redefineModule redefineModule}) * are always located after providers declared by the module.

      * *
    • Step 2: Locate providers in unnamed modules.

      @@ -1647,6 +1647,7 @@ public final class ServiceLoader * @revised 9 */ @CallerSensitive + @SuppressWarnings("doclint:reference") // cross-module links public static ServiceLoader load(Class service, ClassLoader loader) { diff --git a/src/java.base/share/classes/java/util/StringTokenizer.java b/src/java.base/share/classes/java/util/StringTokenizer.java index f30f7b863a46b7541e44289a7c6fcdf749e9c4ec..61fbfe8a716e3e1a61f8fe7c0b82cfdd5e5b89c3 100644 --- a/src/java.base/share/classes/java/util/StringTokenizer.java +++ b/src/java.base/share/classes/java/util/StringTokenizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,9 +174,11 @@ public class StringTokenizer implements Enumeration { *

      * If the {@code returnDelims} flag is {@code true}, then * the delimiter characters are also returned as tokens. Each - * delimiter is returned as a string of length one. If the flag is - * {@code false}, the delimiter characters are skipped and only - * serve as separators between tokens. + * delimiter is returned as a string consisting of a single + * Unicode code point + * of the delimiter (which may be one or two {@code char}s). If the + * flag is {@code false}, the delimiter characters are skipped + * and only serve as separators between tokens. *

      * Note that if {@code delim} is {@code null}, this constructor does * not throw an exception. However, trying to invoke other methods on the diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java index 897409053240a119296a73e9bcebf2dfb92976a6..0378df95a79863f16eaf068a6854cec2cde55a6d 100644 --- a/src/java.base/share/classes/java/util/UUID.java +++ b/src/java.base/share/classes/java/util/UUID.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -512,10 +512,7 @@ public final class UUID implements java.io.Serializable, Comparable { public int compareTo(UUID val) { // The ordering is intentionally set up so that the UUIDs // can simply be numerically compared as two numbers - return (this.mostSigBits < val.mostSigBits ? -1 : - (this.mostSigBits > val.mostSigBits ? 1 : - (this.leastSigBits < val.leastSigBits ? -1 : - (this.leastSigBits > val.leastSigBits ? 1 : - 0)))); + int mostSigBits = Long.compare(this.mostSigBits, val.mostSigBits); + return mostSigBits != 0 ? mostSigBits : Long.compare(this.leastSigBits, val.leastSigBits); } } diff --git a/src/java.base/share/classes/java/util/concurrent/Executors.java b/src/java.base/share/classes/java/util/concurrent/Executors.java index a9e7de32a002f60f887ea74c0bc37f545d7a4e99..3345153bd9777e5901519aa58162d24d8566aab9 100644 --- a/src/java.base/share/classes/java/util/concurrent/Executors.java +++ b/src/java.base/share/classes/java/util/concurrent/Executors.java @@ -791,7 +791,7 @@ public class Executors { FinalizableDelegatedExecutorService(ExecutorService executor) { super(executor); } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { super.shutdown(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java index 49d2a29b2624bc078526b284b85c8371d7dbf359..f23e72a8f70c82f2bba7845c54f02f2d9d920de1 100644 --- a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java +++ b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java @@ -1477,8 +1477,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * @implNote Previous versions of this class had a finalize method * that shut down this executor, but in this version, finalize * does nothing. + * + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") protected void finalize() {} /** diff --git a/src/java.base/share/classes/java/util/jar/Attributes.java b/src/java.base/share/classes/java/util/jar/Attributes.java index a33d1086285d792a105d6c19a6779e82c8f65a14..3b59f74275fd6ec901ede9681afc9a84c4490ed4 100644 --- a/src/java.base/share/classes/java/util/jar/Attributes.java +++ b/src/java.base/share/classes/java/util/jar/Attributes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package java.util.jar; +import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Collection; @@ -366,7 +367,7 @@ public class Attributes implements Map, Cloneable { int read(Manifest.FastInputStream is, byte[] lbuf, String filename, int lineNumber) throws IOException { String name = null, value; - byte[] lastline = null; + ByteArrayOutputStream fullLine = new ByteArrayOutputStream(); int len; while ((len = is.readLine(lbuf)) != -1) { @@ -392,15 +393,12 @@ public class Attributes implements Map, Cloneable { + Manifest.getErrorPosition(filename, lineNumber) + ")"); } lineContinued = true; - byte[] buf = new byte[lastline.length + len - 1]; - System.arraycopy(lastline, 0, buf, 0, lastline.length); - System.arraycopy(lbuf, 1, buf, lastline.length, len - 1); + fullLine.write(lbuf, 1, len - 1); if (is.peek() == ' ') { - lastline = buf; continue; } - value = new String(buf, 0, buf.length, UTF_8.INSTANCE); - lastline = null; + value = fullLine.toString(UTF_8.INSTANCE); + fullLine.reset(); } else { while (lbuf[i++] != ':') { if (i >= len) { @@ -414,8 +412,8 @@ public class Attributes implements Map, Cloneable { } name = new String(lbuf, 0, i - 2, UTF_8.INSTANCE); if (is.peek() == ' ') { - lastline = new byte[len - i]; - System.arraycopy(lbuf, i, lastline, 0, len - i); + fullLine.reset(); + fullLine.write(lbuf, i, len - i); continue; } value = new String(lbuf, i, len - i, UTF_8.INSTANCE); diff --git a/src/java.base/share/classes/java/util/jar/JarVerifier.java b/src/java.base/share/classes/java/util/jar/JarVerifier.java index 280d64e9d37a95a0b337b72c1a86d231f78bf368..e6a217b424cc7eff46209bc1fb5ea7f6a04a5131 100644 --- a/src/java.base/share/classes/java/util/jar/JarVerifier.java +++ b/src/java.base/share/classes/java/util/jar/JarVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,6 +96,10 @@ class JarVerifier { /** collect -DIGEST-MANIFEST values for deny list */ private List manifestDigests; + /* A cache mapping code signers to the algorithms used to digest jar + entries, and whether or not the algorithms are permitted. */ + private Map> signersToAlgs; + public JarVerifier(String name, byte[] rawBytes) { manifestName = name; manifestRawBytes = rawBytes; @@ -105,6 +109,7 @@ class JarVerifier { pendingBlocks = new ArrayList<>(); baos = new ByteArrayOutputStream(); manifestDigests = new ArrayList<>(); + signersToAlgs = new HashMap<>(); } /** @@ -244,7 +249,8 @@ class JarVerifier { if (!parsingBlockOrSF) { JarEntry je = mev.getEntry(); if ((je != null) && (je.signers == null)) { - je.signers = mev.verify(verifiedSigners, sigFileSigners); + je.signers = mev.verify(verifiedSigners, sigFileSigners, + signersToAlgs); je.certs = mapSignersToCertArray(je.signers); } } else { diff --git a/src/java.base/share/classes/java/util/regex/Grapheme.java b/src/java.base/share/classes/java/util/regex/Grapheme.java index efc92158dfecb932cbe13f09191654622c669369..9922cab121a91475f7ec63c584f6672c2f150a71 100644 --- a/src/java.base/share/classes/java/util/regex/Grapheme.java +++ b/src/java.base/share/classes/java/util/regex/Grapheme.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,8 @@ final class Grapheme { *

      * See Unicode Standard Annex #29 Unicode Text Segmentation for the specification * for the extended grapheme cluster boundary rules. The following implementation - * is based on version 12.0 of the annex. - * (http://www.unicode.org/reports/tr29/tr29-35.html) + * is based on the annex for Unicode version 14.0. + * (http://www.unicode.org/reports/tr29/tr29-38.html) * * @param src the {@code CharSequence} to be scanned * @param off offset to start looking for the next boundary in the src @@ -97,7 +97,7 @@ final class Grapheme { private static final int FIRST_TYPE = 0; private static final int LAST_TYPE = 14; - private static boolean[][] rules; + private static final boolean[][] rules; static { rules = new boolean[LAST_TYPE + 1][LAST_TYPE + 1]; // GB 999 Any + Any -> default @@ -201,8 +201,9 @@ final class Grapheme { if (cp == 0x200D) return ZWJ; if (cp >= 0x0600 && cp <= 0x0605 || - cp == 0x06DD || cp == 0x070F || cp == 0x08E2 || - cp == 0x110BD || cp == 0x110CD) + cp == 0x06DD || cp == 0x070F || + cp == 0x0890 || cp == 0x0891 || + cp == 0x08E2 || cp == 0x110BD || cp == 0x110CD) return PREPEND; return CONTROL; case Character.NON_SPACING_MARK: diff --git a/src/java.base/share/classes/java/util/regex/Pattern.java b/src/java.base/share/classes/java/util/regex/Pattern.java index d52a2b92af939d49d6da1970a924641fe992aaec..b1e3977d0b2b3125950b88ea94a9e5a201b7374a 100644 --- a/src/java.base/share/classes/java/util/regex/Pattern.java +++ b/src/java.base/share/classes/java/util/regex/Pattern.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1795,6 +1795,8 @@ loop: for(int x=0, offset=0; x= 0 && index < seq.length()); + if (lengthInCodePoints == 1 && index >= 0 && index < seq.length() && + !Character.isHighSurrogate(seq.charAt(index))) { return 1; } int length = seq.length(); diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index 47edf1ffae1403faba3b7ca1a1fda6c6457893e9..1e5e92e4370cbe20159e0c7d1f13bb8ace37578b 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -208,7 +208,7 @@ public class ZipFile implements ZipConstants, Closeable { * * @throws SecurityException * if a security manager exists and its {@code checkRead} - * method doesn't allow read access to the file,or its + * method doesn't allow read access to the file, or its * {@code checkDelete} method doesn't allow deleting the * file when the {@code OPEN_DELETE} flag is set * @@ -1497,6 +1497,9 @@ public class ZipFile implements ZipConstants, Closeable { zerror("invalid END header (bad central directory offset)"); } // read in the CEN and END + if (end.cenlen + ENDHDR >= Integer.MAX_VALUE) { + zerror("invalid END header (central directory size too large)"); + } cen = this.cen = new byte[(int)(end.cenlen + ENDHDR)]; if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) { zerror("read CEN tables failed"); diff --git a/src/java.base/share/classes/javax/crypto/Cipher.java b/src/java.base/share/classes/javax/crypto/Cipher.java index 1517ec984ceaf43121cc9b004118e026113da678..a6751e886bdbcf26d538534b35ae036b12e662db 100644 --- a/src/java.base/share/classes/javax/crypto/Cipher.java +++ b/src/java.base/share/classes/javax/crypto/Cipher.java @@ -340,7 +340,7 @@ public class Cipher { "format:" + transformation); } if ((parts[0] == null) || (parts[0].isEmpty())) { - throw new NoSuchAlgorithmException("Invalid transformation:" + + throw new NoSuchAlgorithmException("Invalid transformation: " + "algorithm not specified-" + transformation); } @@ -2833,7 +2833,7 @@ public class Cipher { break; default: // should never happen - sb.append("error:").append(Integer.toString(opmode)); + sb.append("error:").append(opmode); } sb.append(", algorithm from: ").append(getProviderName()); return sb.toString(); diff --git a/src/java.base/share/classes/javax/crypto/CryptoPolicyParser.java b/src/java.base/share/classes/javax/crypto/CryptoPolicyParser.java index 5ccaa8143152b3b995f453f5203edd7a2f6ecd64..5d53bc112c00256e0474fd3f9a6bae4b1d427830 100644 --- a/src/java.base/share/classes/javax/crypto/CryptoPolicyParser.java +++ b/src/java.base/share/classes/javax/crypto/CryptoPolicyParser.java @@ -395,7 +395,7 @@ final class CryptoPolicyParser { switch (lookahead) { case StreamTokenizer.TT_NUMBER: throw new ParsingException(st.lineno(), expect, - "number "+String.valueOf(st.nval)); + "number " + st.nval); case StreamTokenizer.TT_EOF: throw new ParsingException("expected "+expect+", read end of file"); case StreamTokenizer.TT_WORD: diff --git a/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java b/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java index 59b4a07f3497d5af64eaa6d270f20f288e649671..09c69748d5a8da90b8bce9e73eadb464de53af5f 100644 --- a/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java +++ b/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java @@ -77,15 +77,18 @@ public class EncryptedPrivateKeyInfo { * @exception NullPointerException if the encoded is null. * @exception IOException if error occurs when parsing the ASN.1 encoding. */ - public EncryptedPrivateKeyInfo(byte[] encoded) - throws IOException { + public EncryptedPrivateKeyInfo(byte[] encoded) throws IOException { if (encoded == null) { throw new NullPointerException("the encoded parameter " + - "must be non-null"); + "must be non-null"); } - this.encoded = encoded.clone(); - DerValue val = new DerValue(this.encoded); + DerValue val = new DerValue(encoded); + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("DER header error: no SEQ tag"); + } + + this.encoded = encoded.clone(); DerValue[] seq = new DerValue[2]; seq[0] = val.data.getDerValue(); diff --git a/src/java.base/share/classes/javax/crypto/SealedObject.java b/src/java.base/share/classes/javax/crypto/SealedObject.java index 354bc0e8d738288a37eddcde1259d289a25a7734..a1242213e44811a041dfd60135075b72e101e9d8 100644 --- a/src/java.base/share/classes/javax/crypto/SealedObject.java +++ b/src/java.base/share/classes/javax/crypto/SealedObject.java @@ -292,12 +292,9 @@ public class SealedObject implements Serializable { throws IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException { - ObjectInput a = getExtObjectInputStream(c); - try { + try (ObjectInput a = getExtObjectInputStream(c)) { Object obj = a.readObject(); return obj; - } finally { - a.close(); } } @@ -412,12 +409,9 @@ public class SealedObject implements Serializable { throw new RuntimeException(iape.getMessage()); } - ObjectInput a = getExtObjectInputStream(c); - try { + try (ObjectInput a = getExtObjectInputStream(c)) { Object obj = a.readObject(); return obj; - } finally { - a.close(); } } diff --git a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java index b3007b2a9a13a4bee8d84c55623f9c81303be021..f60ab53f34e2dd2c15951141f4fbce31746d60cb 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -920,9 +920,9 @@ public abstract class SSLEngine { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -946,9 +946,9 @@ public abstract class SSLEngine { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -968,10 +968,10 @@ public abstract class SSLEngine { * Note that the standard list of cipher suite names may be found in the * - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list or might not - * use the recommended name for a certain cipher suite. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list or might not use the recommended name + * for a certain cipher suite. *

      * See {@link #getEnabledCipherSuites()} for more information * on why a specific cipher suite may never be used on a engine. diff --git a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java index b156a8a5dac8d53b7ab9fbf722dd1e1fe4a4f177..83b83c8427040bad4cacf83115c35f62b07cbdc7 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,9 +111,9 @@ public class SSLParameters { * {@code setCipherSuites(cipherSuites);}. Note that the * standard list of cipher suite names may be found in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) */ @@ -131,9 +131,9 @@ public class SSLParameters { * Note that the standard list of cipher suite names may be found in the * - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) * @param protocols the array of protocols (or null) @@ -154,9 +154,9 @@ public class SSLParameters { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher suites + * that the provider supports. * * @return a copy of the array of ciphersuites or null if none * have been set. @@ -171,10 +171,10 @@ public class SSLParameters { * @param cipherSuites the array of ciphersuites (or null). Note that the * standard list of cipher suite names may be found in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list or might not - * use the recommended name for a certain cipher suite. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list or might not use the recommended name + * for a certain cipher suite. */ public void setCipherSuites(String[] cipherSuites) { this.cipherSuites = clone(cipherSuites); @@ -617,7 +617,7 @@ public class SSLParameters { * * @return a non-null, possibly zero-length array of application protocol * {@code String}s. The array is ordered based on protocol - * preference, with {@code protocols[0]} being the most preferred. + * preference, with the first entry being the most preferred. * @see #setApplicationProtocols * @since 9 */ diff --git a/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java b/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java index 00a8bed19f091a40f230cce941e6a1e6e33c547d..20d7e7af676a1b37c47a4047827480333a401232 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -197,9 +197,9 @@ public abstract class SSLServerSocket extends ServerSocket { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suites enabled * @see #getSupportedCipherSuites() @@ -223,10 +223,10 @@ public abstract class SSLServerSocket extends ServerSocket { * Note that the standard list of cipher suite names may be found in the * - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list or might not - * use the recommended name for a certain cipher suite. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list or might not use the recommended name + * for a certain cipher suite. *

      * SSLSockets returned from accept() * inherit this setting. @@ -253,9 +253,9 @@ public abstract class SSLServerSocket extends ServerSocket { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() diff --git a/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java b/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java index e66bd11239d9192a7aae6b38f7c57c1cc40b0fee..68c09c02a6f6c9939a145a415374f4a0a4461dcf 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,9 +87,9 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -108,9 +108,9 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getDefaultCipherSuites() diff --git a/src/java.base/share/classes/javax/net/ssl/SSLSocket.java b/src/java.base/share/classes/javax/net/ssl/SSLSocket.java index 84e5be716feab684ff7852f0f5a2fa3596cefaef..b2c912c3b65bdf2bff1c074ef51d1fdbeaefc969 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLSocket.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -327,9 +327,9 @@ public abstract class SSLSocket extends Socket * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -353,9 +353,9 @@ public abstract class SSLSocket extends Socket * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -375,10 +375,10 @@ public abstract class SSLSocket extends Socket * Note that the standard list of cipher suite names may be found in the * - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list or might not - * use the recommended name for a certain cipher suite. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list or might not use the recommended name + * for a certain cipher suite. *

      * See {@link #getEnabledCipherSuites()} for more information * on why a specific ciphersuite may never be used on a connection. diff --git a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java index 6db6d740750d15eebaa1e8beba7a719f58eefda0..dd10f422f3ece59a19e351ad8ad787868b2b49ab 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,9 +113,9 @@ public abstract class SSLSocketFactory extends SocketFactory { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher suites + * that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -132,9 +132,9 @@ public abstract class SSLSocketFactory extends SocketFactory { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher suites + * that the provider supports. * * @see #getDefaultCipherSuites() * @return an array of cipher suite names diff --git a/src/java.base/share/classes/javax/security/auth/Subject.java b/src/java.base/share/classes/javax/security/auth/Subject.java index 8e30f84ff4467114ded80e4b21792b245eb03770..c1235bffd532f34d9f7dd02faf1c8a8271a9fc6a 100644 --- a/src/java.base/share/classes/javax/security/auth/Subject.java +++ b/src/java.base/share/classes/javax/security/auth/Subject.java @@ -402,6 +402,7 @@ public final class Subject implements java.io.Serializable { */ public static T callAs(final Subject subject, final Callable action) throws CompletionException { + Objects.requireNonNull(action); if (USE_TL) { Subject oldSubject = SUBJECT_THREAD_LOCAL.get(); SUBJECT_THREAD_LOCAL.set(subject); diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java index 4082fae336fe7807017823838698934ebe720789..9e3ce846f02498b58fbc294a64cd4bf612743fd5 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java @@ -102,4 +102,11 @@ public interface JavaLangReflectAccess { /** Returns a new instance created by the given constructor with access check */ public T newInstance(Constructor ctor, Object[] args, Class caller) throws IllegalAccessException, InstantiationException, InvocationTargetException; + + /** Invokes the given default method if the method's declaring interface is + * accessible to the given caller. Otherwise, IllegalAccessException will + * be thrown. If the caller is null, no access check is performed. + */ + public Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable; } diff --git a/src/java.base/share/classes/jdk/internal/access/foreign/MemorySegmentProxy.java b/src/java.base/share/classes/jdk/internal/access/foreign/MemorySegmentProxy.java index a00b6516a55bc13de48658de94fd7cfd34aae17d..068fcfa1a6b50bea45bcfff29c7d70c0c5eb269a 100644 --- a/src/java.base/share/classes/jdk/internal/access/foreign/MemorySegmentProxy.java +++ b/src/java.base/share/classes/jdk/internal/access/foreign/MemorySegmentProxy.java @@ -44,6 +44,7 @@ public abstract class MemorySegmentProxy { public abstract Object unsafeGetBase(); public abstract boolean isSmall(); public abstract ScopedMemoryAccess.Scope scope(); + public abstract long maxAlignMask(); /* Helper functions for offset computations. These are required so that we can avoid issuing long opcodes * (e.g. LMUL, LADD) when we're operating on 'small' segments (segments whose length can be expressed with an int). diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/Punycode.java b/src/java.base/share/classes/jdk/internal/icu/impl/Punycode.java index 52f6e546f3ae379e3744322904e60b01f1a6695c..6fe1ebcc54677d32cf2e6a9f8758c41925f10ec7 100644 --- a/src/java.base/share/classes/jdk/internal/icu/impl/Punycode.java +++ b/src/java.base/share/classes/jdk/internal/icu/impl/Punycode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,9 +76,6 @@ public final class Punycode { // TODO: eliminate the 256 limitation private static final int MAX_CP_COUNT = 256; - private static final int UINT_MAGIC = 0x80000000; - private static final long ULONG_MAGIC = 0x8000000000000000L; - private static int adaptBias(int delta, int length, boolean firstTime){ if(firstTime){ delta /=DAMP; @@ -96,34 +93,25 @@ public final class Punycode { } /** - * basicToDigit[] contains the numeric value of a basic code - * point (for use in representing integers) in the range 0 to - * BASE-1, or -1 if b is does not represent a value. + * @return the numeric value of a basic code point (for use in representing integers) + * in the range 0 to BASE-1, or a negative value if cp is invalid. */ - static final int[] basicToDigit= new int[]{ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, - - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + private static final int decodeDigit(int cp) { + if(cp<='Z') { + if(cp<='9') { + if(cp<'0') { + return -1; + } else { + return cp-'0'+26; // 0..9 -> 26..35 + } + } else { + return cp-'A'; // A-Z -> 0..25 + } + } else if(cp<='z') { + return cp-'a'; // a..z -> 0..25 + } else { + return -1; + } }; private static char asciiCaseMap(char b, boolean uppercase) { @@ -158,6 +146,12 @@ public final class Punycode { return (char)((ZERO-26)+digit); } } + + // ICU-13727: Limit input length for n^2 algorithm + // where well-formed strings are at most 59 characters long. + private static final int ENCODE_MAX_CODE_UNITS = 1000; + private static final int DECODE_MAX_CHARS = 2000; + /** * Converts Unicode to Punycode. * The input string must not contain single, unpaired surrogates. @@ -174,6 +168,10 @@ public final class Punycode { int n, delta, handledCPCount, basicLength, destLength, bias, j, m, q, k, t, srcCPCount; char c, c2; int srcLength = src.length(); + if (srcLength > ENCODE_MAX_CODE_UNITS) { + throw new RuntimeException( + "input too long: " + srcLength + " UTF-16 code units"); + } int destCapacity = MAX_CP_COUNT; char[] dest = new char[destCapacity]; StringBuffer result = new StringBuffer(); @@ -251,7 +249,7 @@ public final class Punycode { * Increase delta enough to advance the decoder's * state to , but guard against overflow: */ - if(m-n>(0x7fffffff-MAX_CP_COUNT-delta)/(handledCPCount+1)) { + if(m-n>(0x7fffffff-handledCPCount-delta)/(handledCPCount+1)) { throw new RuntimeException("Internal program error"); } delta+=(m-n)*(handledCPCount+1); @@ -332,6 +330,9 @@ public final class Punycode { public static StringBuffer decode(StringBuffer src, boolean[] caseFlags) throws ParseException{ int srcLength = src.length(); + if (srcLength > DECODE_MAX_CHARS) { + throw new RuntimeException("input too long: " + srcLength + " characters"); + } StringBuffer result = new StringBuffer(); int n, destLength, i, bias, basicLength, j, in, oldi, w, k, digit, t, destCPCount, firstSupplementaryIndex, cpLength; @@ -395,7 +396,7 @@ public final class Punycode { throw new ParseException("Illegal char found", -1); } - digit=basicToDigit[(byte)src.charAt(in++)]; + digit=decodeDigit(src.charAt(in++)); if(digit<0) { throw new ParseException("Invalid char found", -1); } diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/UnicodeSetStringSpan.java b/src/java.base/share/classes/jdk/internal/icu/impl/UnicodeSetStringSpan.java index ee5e80dd8830f783536f4ba3a16f5ec7aa9f1041..331ab234f5954e3be18be1d7e7ad4704d26fe6ba 100644 --- a/src/java.base/share/classes/jdk/internal/icu/impl/UnicodeSetStringSpan.java +++ b/src/java.base/share/classes/jdk/internal/icu/impl/UnicodeSetStringSpan.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,9 +134,15 @@ public class UnicodeSetStringSpan { int i, spanLength; someRelevant = false; - for (i = 0; i < stringsLength; ++i) { + for (i = 0; i < stringsLength;) { String string = strings.get(i); int length16 = string.length(); + if (length16 == 0) { + // Remove the empty string. + strings.remove(i); + --stringsLength; + continue; + } spanLength = spanSet.span(string, SpanCondition.CONTAINED); if (spanLength < length16) { // Relevant string. someRelevant = true; @@ -144,6 +150,7 @@ public class UnicodeSetStringSpan { if (/* (0 != (which & UTF16)) && */ length16 > maxLength16) { maxLength16 = length16; } + ++i; } if (!someRelevant && (which & WITH_COUNT) == 0) { return; diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/uprops.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/uprops.icu deleted file mode 100644 index ee08ff5b011d49d5866413c5856f37f58b0ab8cc..0000000000000000000000000000000000000000 Binary files a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/uprops.icu and /dev/null differ diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfc.nrm b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/nfc.nrm similarity index 86% rename from src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfc.nrm rename to src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/nfc.nrm index 45c260858f9aea1031520e13b6087be76b6c9301..b42accf8ad174cb046bf609e13179e1b3c2ec70e 100644 Binary files a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfc.nrm and b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/nfc.nrm differ diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfkc.nrm b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/nfkc.nrm similarity index 67% rename from src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfkc.nrm rename to src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/nfkc.nrm index 2c0587b6d455a6221287faf70600adcea6a7ef7b..450b6ed323b8ecd52cffd1f91c59bc284fdeb161 100644 Binary files a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/nfkc.nrm and b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/nfkc.nrm differ diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/ubidi.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/ubidi.icu similarity index 63% rename from src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/ubidi.icu rename to src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/ubidi.icu index bec7b093064530bb5049258a4280cf55a113ec8a..b125866b8e2d907c50bcd715e3174bbf1796c03a 100644 Binary files a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt67b/ubidi.icu and b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/ubidi.icu differ diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/uprops.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/uprops.icu new file mode 100644 index 0000000000000000000000000000000000000000..335caa93cc2803e26e5b34342bb0c9e45074b155 Binary files /dev/null and b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt70b/uprops.icu differ diff --git a/src/java.base/share/classes/jdk/internal/icu/lang/UCharacter.java b/src/java.base/share/classes/jdk/internal/icu/lang/UCharacter.java index 716aa9827900ed8c4384dbbdecc9aa039147e4fd..b703611cf275bd41d0def5ba4e0747daf354d4a1 100644 --- a/src/java.base/share/classes/jdk/internal/icu/lang/UCharacter.java +++ b/src/java.base/share/classes/jdk/internal/icu/lang/UCharacter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,7 @@ import jdk.internal.icu.util.VersionInfo; *

      * Further detail on differences can be determined using the program * + * "https://github.com/unicode-org/icu/blob/main/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterCompare.java"> * com.ibm.icu.dev.test.lang.UCharacterCompare *

      *

      @@ -101,9 +101,9 @@ import jdk.internal.icu.util.VersionInfo; * For more information see * "About the Unicode Character Database" * (http://www.unicode.org/ucd/) - * and the ICU + * and the ICU * User Guide chapter on Properties - * (http://www.icu-project.org/userguide/properties.html). + * (https://unicode-org.github.io/icu/userguide/strings/properties). *

      *

      * There are also functions that provide easy migration from C/POSIX functions diff --git a/src/java.base/share/classes/jdk/internal/icu/lang/UCharacterDirection.java b/src/java.base/share/classes/jdk/internal/icu/lang/UCharacterDirection.java index db9beb0c3acd1b4337d2cf81367f624438243f07..22b878155bb4ba61e2b89d5e25bd569ebc43e8df 100644 --- a/src/java.base/share/classes/jdk/internal/icu/lang/UCharacterDirection.java +++ b/src/java.base/share/classes/jdk/internal/icu/lang/UCharacterDirection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ public final class UCharacterDirection implements UCharacterEnums.ECharacterDire // private constructor ========================================= ///CLOVER:OFF /** - * Private constructor to prevent initialisation + * Private constructor to prevent initialization */ private UCharacterDirection() { diff --git a/src/java.base/share/classes/jdk/internal/icu/lang/UCharacterEnums.java b/src/java.base/share/classes/jdk/internal/icu/lang/UCharacterEnums.java index 9b4809ae411e930f49f4845a439c62481cc7183e..38f8684ea04c1d8fb187236e8c70e2877e7472eb 100644 --- a/src/java.base/share/classes/jdk/internal/icu/lang/UCharacterEnums.java +++ b/src/java.base/share/classes/jdk/internal/icu/lang/UCharacterEnums.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ package jdk.internal.icu.lang; @Deprecated class UCharacterEnums { - /** This is just a namespace, it is not instantiatable. */ + /** This is just a namespace, it is not instantiable. */ private UCharacterEnums() {}; /** diff --git a/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java b/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java index 1714c15143a6b22b160efa792ceeb3ee75e1eb97..1161e9c84649775efc69e3a43751db3565ee9bf1 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ import jdk.internal.icu.impl.UBiDiProps; * * This is an implementation of the Unicode Bidirectional Algorithm. The * algorithm is defined in the - * Unicode Standard Annex #9: + * Unicode Standard Annex #9: * Unicode Bidirectional Algorithm. *

      * @@ -985,7 +985,7 @@ public class BidiBase { /** * Enumerated property Bidi_Paired_Bracket_Type (new in Unicode 6.3). * Used in - * Unicode Standard Annex #9: + * Unicode Standard Annex #9: * Unicode Bidirectional Algorithm. * Returns UCharacter.BidiPairedBracketType values. * @stable ICU 52 @@ -3365,7 +3365,7 @@ public class BidiBase { /** * Perform the Unicode Bidi algorithm. It is defined in the - * Unicode Standard Annex #9: + * Unicode Standard Annex #9: * Unicode Bidirectional Algorithm, version 13, * also described in The Unicode Standard, Version 4.0 .

      * @@ -3450,7 +3450,7 @@ public class BidiBase { /** * Perform the Unicode Bidi algorithm. It is defined in the - * Unicode Standard Annex #9: + * Unicode Standard Annex #9: * Unicode Bidirectional Algorithm, version 13, * also described in The Unicode Standard, Version 4.0 .

      * @@ -3786,7 +3786,7 @@ public class BidiBase { /** * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the - * Unicode Standard Annex #9: + * Unicode Standard Annex #9: * Unicode Bidirectional Algorithm, version 13, * also described in The Unicode Standard, Version 4.0 .

      * diff --git a/src/java.base/share/classes/jdk/internal/icu/text/BidiLine.java b/src/java.base/share/classes/jdk/internal/icu/text/BidiLine.java index 6a358abebd7785c4ecde5affe8a1c0ff6ba2f98e..d8fa4f61fa46afe0bbb53c3c303c46f5d1fbc48b 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/BidiLine.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/BidiLine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ final class BidiLine { * text in a single paragraph or in a line of a single paragraph * which has already been processed according to * the Unicode 3.0 Bidi algorithm as defined in - * Unicode Standard Annex #9: + * Unicode Standard Annex #9: * Unicode Bidirectional Algorithm, version 13, * also described in The Unicode Standard, Version 4.0.1 . * diff --git a/src/java.base/share/classes/jdk/internal/icu/text/Normalizer2.java b/src/java.base/share/classes/jdk/internal/icu/text/Normalizer2.java index f7fc6d294a3566785d1cf3cf3f87ee5c0c161171..db0d1fc20bf9902e3251003c8b75d6d17fc73d7d 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/Normalizer2.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/Normalizer2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ import jdk.internal.icu.impl.Norm2AllModes; * The primary functions are to produce a normalized string and to detect whether * a string is already normalized. * The most commonly used normalization forms are those defined in - * Unicode Standard Annex #15: + * Unicode Standard Annex #15: * Unicode Normalization Forms. * However, this API supports additional normalization forms for specialized purposes. * For example, NFKC_Casefold is provided via getInstance("nfkc_cf", COMPOSE) diff --git a/src/java.base/share/classes/jdk/internal/icu/text/NormalizerBase.java b/src/java.base/share/classes/jdk/internal/icu/text/NormalizerBase.java index ffe065413a532c47c21bfb2b2d958860bccfab93..f2566d9d419b77c597be0a170cd411d21eb939b0 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/NormalizerBase.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/NormalizerBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ import java.text.Normalizer; * normalize transforms Unicode text into an equivalent composed or * decomposed form, allowing for easier sorting and searching of text. * normalize supports the standard normalization forms described in - * + * * Unicode Standard Annex #15 — Unicode Normalization Forms. * * Characters with accents or other adornments can be encoded in diff --git a/src/java.base/share/classes/jdk/internal/icu/text/StringPrep.java b/src/java.base/share/classes/jdk/internal/icu/text/StringPrep.java index 82fe7d3a5a9fab86924b09722a98a1091b0fd189..f05d0403665682063770531583e5c2b08b2fe4d0 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/StringPrep.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/StringPrep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,9 +67,9 @@ import jdk.internal.icu.util.VersionInfo; *

    • Unassigned Table: Contains code points that are unassigned * in the Unicode Version supported by StringPrep. Currently * RFC 3454 supports Unicode 3.2.
    • - *
    • Prohibited Table: Contains code points that are prohibted from + *
    • Prohibited Table: Contains code points that are prohibited from * the output of the StringPrep processing function.
    • - *
    • Mapping Table: Contains code ponts that are deleted from the output or case mapped.
    • + *
    • Mapping Table: Contains code points that are deleted from the output or case mapped.
    • * * * The procedure for preparing Unicode strings: @@ -226,8 +226,8 @@ public final class StringPrep { sprepUniVer = getVersionInfo(reader.getUnicodeVersion()); normCorrVer = getVersionInfo(indexes[NORM_CORRECTNS_LAST_UNI_VERSION]); VersionInfo normUniVer = UCharacter.getUnicodeVersion(); - if(normUniVer.compareTo(sprepUniVer) < 0 && /* the Unicode version of SPREP file must be less than the Unicode Vesion of the normalization data */ - normUniVer.compareTo(normCorrVer) < 0 && /* the Unicode version of the NormalizationCorrections.txt file should be less than the Unicode Vesion of the normalization data */ + if(normUniVer.compareTo(sprepUniVer) < 0 && /* the Unicode version of SPREP file must be less than the Unicode Version of the normalization data */ + normUniVer.compareTo(normCorrVer) < 0 && /* the Unicode version of the NormalizationCorrections.txt file should be less than the Unicode Version of the normalization data */ ((indexes[OPTIONS] & NORMALIZATION_ON) > 0) /* normalization turned on*/ ){ throw new IOException("Normalization Correction version not supported"); @@ -325,7 +325,7 @@ public final class StringPrep { ch -= val.value; } }else if(val.type == DELETE){ - // just consume the codepoint and contine + // just consume the codepoint and continue continue; } //copy the source into destination diff --git a/src/java.base/share/classes/jdk/internal/icu/text/UCharacterIterator.java b/src/java.base/share/classes/jdk/internal/icu/text/UCharacterIterator.java index e85a08c4605e86f0731f752aaa75e06639943aca..93978372c3a03822342b1717a82f8b93ab2b450a 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/UCharacterIterator.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/UCharacterIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -147,9 +147,9 @@ public abstract class UCharacterIterator */ public int nextCodePoint(){ int ch1 = next(); - if(UTF16.isLeadSurrogate((char)ch1)){ + if(UTF16.isLeadSurrogate(ch1)){ int ch2 = next(); - if(UTF16.isTrailSurrogate((char)ch2)){ + if(UTF16.isTrailSurrogate(ch2)){ return UCharacterProperty.getRawSupplementary((char)ch1, (char)ch2); }else if (ch2 != DONE) { @@ -175,7 +175,7 @@ public abstract class UCharacterIterator /** * Retreat to the start of the previous code point in the text, * and return it (pre-decrement semantics). If the index is not - * preceeded by a valid surrogate pair, the behavior is the same + * preceded by a valid surrogate pair, the behavior is the same * as previous(). Otherwise the iterator is * decremented to the start of the surrogate pair, and the code * point represented by the pair is returned. @@ -185,9 +185,9 @@ public abstract class UCharacterIterator */ public int previousCodePoint(){ int ch1 = previous(); - if(UTF16.isTrailSurrogate((char)ch1)){ + if(UTF16.isTrailSurrogate(ch1)){ int ch2 = previous(); - if(UTF16.isLeadSurrogate((char)ch2)){ + if(UTF16.isLeadSurrogate(ch2)){ return UCharacterProperty.getRawSupplementary((char)ch2, (char)ch1); }else if (ch2 != DONE) { diff --git a/src/java.base/share/classes/jdk/internal/icu/text/UTF16.java b/src/java.base/share/classes/jdk/internal/icu/text/UTF16.java index b35d842b0d5c2350556347979ab10d07fd2ed67d..4205487a966fe75ce73bb315d0506f6355885c10 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/UTF16.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/UTF16.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -382,36 +382,39 @@ public final class UTF16 } /** - * Determines whether the code value is a surrogate. - * @param char16 the input character. - * @return true if the input character is a surrogate. - * @stable ICU 2.1 + * Determines whether the code point is a surrogate. + * + * @param codePoint The input character. + * (In ICU 2.1-69 the type of this parameter was char.) + * @return true If the input code point is a surrogate. + * @stable ICU 70 */ - public static boolean isSurrogate(char char16) - { - return (char16 & SURROGATE_BITMASK) == SURROGATE_BITS; + public static boolean isSurrogate(int codePoint) { + return (codePoint & SURROGATE_BITMASK) == SURROGATE_BITS; } /** - * Determines whether the character is a trail surrogate. - * @param char16 the input character. - * @return true if the input character is a trail surrogate. - * @stable ICU 2.1 + * Determines whether the code point is a trail surrogate. + * + * @param codePoint The input character. + * (In ICU 2.1-69 the type of this parameter was char.) + * @return true If the input code point is a trail surrogate. + * @stable ICU 70 */ - public static boolean isTrailSurrogate(char char16) - { - return (char16 & TRAIL_SURROGATE_BITMASK) == TRAIL_SURROGATE_BITS; + public static boolean isTrailSurrogate(int codePoint) { + return (codePoint & TRAIL_SURROGATE_BITMASK) == TRAIL_SURROGATE_BITS; } /** - * Determines whether the character is a lead surrogate. - * @param char16 the input character. - * @return true if the input character is a lead surrogate - * @stable ICU 2.1 + * Determines whether the code point is a lead surrogate. + * + * @param codePoint The input character. + * (In ICU 2.1-69 the type of this parameter was char.) + * @return true If the input code point is a lead surrogate + * @stable ICU 70 */ - public static boolean isLeadSurrogate(char char16) - { - return (char16 & LEAD_SURROGATE_BITMASK) == LEAD_SURROGATE_BITS; + public static boolean isLeadSurrogate(int codePoint) { + return (codePoint & LEAD_SURROGATE_BITMASK) == LEAD_SURROGATE_BITS; } /** diff --git a/src/java.base/share/classes/jdk/internal/icu/text/UnicodeSet.java b/src/java.base/share/classes/jdk/internal/icu/text/UnicodeSet.java index 63188dca460231fb7f6137aac56843335abfbf12..6f5919e016bdc5c3668236bfbe936ea71590f3c8 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/UnicodeSet.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/UnicodeSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -135,8 +135,8 @@ import jdk.internal.icu.util.VersionInfo; * "[:Lu:]" and the Perl-like syntax "\p{Lu}" are recognized. For a * complete list of supported property patterns, see the User's Guide * for UnicodeSet at - * - * http://www.icu-project.org/userguide/unicodeSet.html. + * + * https://unicode-org.github.io/icu/userguide/strings/unicodeset. * Actual determination of property data is defined by the underlying * Unicode database as implemented by UCharacter. * @@ -147,6 +147,13 @@ import jdk.internal.icu.util.VersionInfo; * their delimiters; "[:^foo]" and "\P{foo}". In any other location, * '^' has no special meaning. * + *

      Since ICU 70, "[^...]", "[:^foo]", "\P{foo}", and "[:binaryProperty=No:]" + * perform a "code point complement" (all code points minus the original set), + * removing all multicharacter strings, + * equivalent to .{@link #complement()}.{@link #removeAllStrings()} . + * The {@link #complement()} API function continues to perform a + * symmetric difference with all code points and thus retains all multicharacter strings. + * *

      Ranges are indicated by placing two a '-' between two * characters, as in "a-z". This specifies the range of all * characters from the left to the right, in Unicode order. If the @@ -189,8 +196,6 @@ import jdk.internal.icu.util.VersionInfo; * Unicode property *

    • * - *

      Warning: you cannot add an empty string ("") to a UnicodeSet.

      - * *

      Formal syntax

      * *
      @@ -230,9 +235,8 @@ import jdk.internal.icu.util.VersionInfo; * * * hex :=  - * any character for which - * Character.digit(c, 16) - * returns a non-negative result + * '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
      + *     'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
      * * * property :=  @@ -487,7 +491,7 @@ public class UnicodeSet { else if (i > 0 && c == list[i-1]) { // c is after end of prior range list[i-1]++; - // no need to chcek for collapse here + // no need to check for collapse here } else { @@ -528,7 +532,6 @@ public class UnicodeSet { * present. If this set already contains the multicharacter, * the call leaves this set unchanged. * Thus {@code "ch" => {"ch"}} - *
      Warning: you cannot add an empty string ("") to a UnicodeSet. * @param s the source string * @return this object, for chaining * @stable ICU 2.0 @@ -546,22 +549,19 @@ public class UnicodeSet { /** * Utility for getting code point from single code point CharSequence. - * See the public UTF16.getSingleCodePoint() + * See the public UTF16.getSingleCodePoint() (which returns -1 for null rather than throwing NPE). + * * @return a code point IF the string consists of a single one. * otherwise returns -1. * @param s to test */ private static int getSingleCP(CharSequence s) { - if (s.length() < 1) { - throw new IllegalArgumentException("Can't use zero-length strings in UnicodeSet"); - } - if (s.length() > 2) return -1; if (s.length() == 1) return s.charAt(0); - - // at this point, len = 2 - int cp = UTF16.charAt(s, 0); - if (cp > 0xFFFF) { // is surrogate pair - return cp; + if (s.length() == 2) { + int cp = Character.codePointAt(s, 0); + if (cp > 0xFFFF) { // is surrogate pair + return cp; + } } return -1; } @@ -569,13 +569,11 @@ public class UnicodeSet { /** * Complements the specified range in this set. Any character in * the range will be removed if it is in this set, or will be - * added if it is not in this set. If {@code end > start} + * added if it is not in this set. If start > end * then an empty range is complemented, leaving the set unchanged. * - * @param start first character, inclusive, of range to be removed - * from this set. - * @param end last character, inclusive, of range to be removed - * from this set. + * @param start first character, inclusive, of range + * @param end last character, inclusive, of range * @stable ICU 2.0 */ public UnicodeSet complement(int start, int end) { diff --git a/src/java.base/share/classes/jdk/internal/icu/util/CodePointTrie.java b/src/java.base/share/classes/jdk/internal/icu/util/CodePointTrie.java index 1738696f75ab2a210fc2c54d311f20660753aece..7aaa0be68c8b9c54d45d5b995237c7d0f1c3c816 100644 --- a/src/java.base/share/classes/jdk/internal/icu/util/CodePointTrie.java +++ b/src/java.base/share/classes/jdk/internal/icu/util/CodePointTrie.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ import static jdk.internal.icu.impl.NormalizerImpl.UTF16Plus; /** * Immutable Unicode code point trie. * Fast, reasonably compact, map from Unicode code points (U+0000..U+10FFFF) to integer values. - * For details see http://site.icu-project.org/design/struct/utrie + * For details see https://icu.unicode.org/design/struct/utrie * *

      This class is not intended for public subclassing. * diff --git a/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java b/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java index d79ee84731b3027a9e2c36ba3741ccf6b5124480..799d570e2aa8296bcd9cf84e7b8cda3dc7b0a524 100644 --- a/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java +++ b/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ public final class VersionInfo * @deprecated This API is ICU internal only. */ @Deprecated - public static final String ICU_DATA_VERSION_PATH = "67b"; + public static final String ICU_DATA_VERSION_PATH = "70b"; // public methods ------------------------------------------------------ @@ -148,7 +148,15 @@ public final class VersionInfo */ public int compareTo(VersionInfo other) { - return m_version_ - other.m_version_; + // m_version_ is an int, a signed 32-bit integer. + // When the major version is >=128, then the version int is negative. + // Compare it in two steps to simulate an unsigned-int comparison. + // (Alternatively we could turn each int into a long and reset the upper 32 bits.) + // Compare the upper bits first, using logical shift right (unsigned). + int diff = (m_version_ >>> 1) - (other.m_version_ >>> 1); + if (diff != 0) { return diff; } + // Compare the remaining bits. + return (m_version_ & 1) - (other.m_version_ & 1); } // private data members ---------------------------------------------- diff --git a/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java b/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java index f5773302004030b195109bc4195a0f8453725a03..c4601ef3e6cc62a17683b95c005d0a548fa33b07 100644 --- a/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java +++ b/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java @@ -309,7 +309,7 @@ public class ImageStringsReader implements ImageStrings { return -1; } } - return length; + return current - offset + length; } static int mutf8FromStringLength(String s) { diff --git a/src/java.base/share/classes/jdk/internal/misc/CDS.java b/src/java.base/share/classes/jdk/internal/misc/CDS.java index 43f6128cc0576f5e979b2b9682794c885cd9c9e2..370086612cd83b8ed4cdf23fc129ee31f5970d32 100644 --- a/src/java.base/share/classes/jdk/internal/misc/CDS.java +++ b/src/java.base/share/classes/jdk/internal/misc/CDS.java @@ -66,7 +66,7 @@ public class CDS { } /** - * Is sharing enabled via the UseSharedSpaces flag. + * Is sharing enabled. */ public static boolean isSharingEnabled() { return isSharingEnabled; @@ -232,15 +232,11 @@ public class CDS { private static String[] excludeFlags = { "-XX:DumpLoadedClassList=", - "-XX:+DumpSharedSpaces", - "-XX:+DynamicDumpSharedSpaces", "-XX:+RecordDynamicDumpInfo", "-Xshare:", "-XX:SharedClassListFile=", "-XX:SharedArchiveFile=", - "-XX:ArchiveClassesAtExit=", - "-XX:+UseSharedSpaces", - "-XX:+RequireSharedSpaces"}; + "-XX:ArchiveClassesAtExit="}; private static boolean containsExcludedFlags(String testStr) { for (String e : excludeFlags) { if (testStr.contains(e)) { diff --git a/src/java.base/share/classes/jdk/internal/module/ModulePath.java b/src/java.base/share/classes/jdk/internal/module/ModulePath.java index 47c21ed3b3d26f465c784592af0836564bb31ed2..876050ef8396851544d4ca7a202ef79d6388f606 100644 --- a/src/java.base/share/classes/jdk/internal/module/ModulePath.java +++ b/src/java.base/share/classes/jdk/internal/module/ModulePath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -527,7 +527,6 @@ public class ModulePath implements ModuleFinder { Set packages = classFiles.stream() .map(this::toPackageName) .flatMap(Optional::stream) - .distinct() .collect(Collectors.toSet()); // all packages are exported and open diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java index 17575546518ee5a5b7b1aa007fedaab8e5f25abf..e306e60d45bf209990bd019099ecc8ed605cadcd 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java @@ -222,7 +222,7 @@ public class ClassReader { this.b = classFileBuffer; // Check the class' major_version. This field is after the magic and minor_version fields, which // use 4 and 2 bytes respectively. - if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V18) { + if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V19) { throw new IllegalArgumentException( "Unsupported class file major version " + readShort(classFileOffset + 6)); } diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java index e8be8c1935ccfb1e6f082bd04a4a0e6a2e874bc8..d1b6d52865cca24e5ed7d767f8789e1038b69c39 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java @@ -314,6 +314,7 @@ public interface Opcodes { int V16 = 0 << 16 | 60; int V17 = 0 << 16 | 61; int V18 = 0 << 16 | 62; + int V19 = 0 << 16 | 63; /** * Version flag indicating that the class is using 'preview' features. diff --git a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java index 76a4bf8fa4a643beeb647d193ae2610bc7d4f0fc..23b686041e67f647d5e2dfe2fe268d63d24cc0da 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -379,11 +379,8 @@ public class Reflection { String msg = currentClass + currentSuffix + " cannot access "; if (m2.isExported(memberPackageName, m1)) { - // module access okay so include the modifiers in the message - msg += "a member of " + memberClass + memberSuffix + - " with modifiers \"" + Modifier.toString(modifiers) + "\""; - + msg += "a member of " + memberClass + memberSuffix + msgSuffix(modifiers); } else { // module access failed msg += memberClass + memberSuffix+ " because " @@ -410,11 +407,8 @@ public class Reflection { String msg = "JNI attached native thread (null caller frame) cannot access "; if (m2.isExported(memberPackageName)) { - // module access okay so include the modifiers in the message - msg += "a member of " + memberClass + memberSuffix + - " with modifiers \"" + Modifier.toString(modifiers) + "\""; - + msg += "a member of " + memberClass + memberSuffix + msgSuffix(modifiers); } else { // module access failed msg += memberClass + memberSuffix+ " because " @@ -424,6 +418,16 @@ public class Reflection { return new IllegalAccessException(msg); } + private static String msgSuffix(int modifiers) { + boolean packageAccess = + ((Modifier.PRIVATE | + Modifier.PROTECTED | + Modifier.PUBLIC) & modifiers) == 0; + return packageAccess ? + " with package access" : + " with modifiers \"" + Modifier.toString(modifiers) + "\""; + } + /** * Returns true if {@code currentClass} and {@code memberClass} * are nestmates - that is, if they have the same nesthost as diff --git a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java index d47043b89aa199a5dca72c44e28ca3876e09d7b8..14fe0d3906df27386deb816f58a11341fbe29771 100644 --- a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -645,7 +645,7 @@ public class RandomSupport { if (origin < bound) { r = r * (bound - origin) + origin; if (r >= bound) // may need to correct a rounding problem - r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); + r = Math.nextAfter(bound, origin); } return r; } @@ -677,7 +677,7 @@ public class RandomSupport { double r = rng.nextDouble(); r = r * bound; if (r >= bound) // may need to correct a rounding problem - r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); + r = Math.nextDown(r); return r; } diff --git a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java index 63e007657929b255c160724b8a99bc3f8eae98c8..d175e62abbf2d063d72d02fc47f9fd7b51e8e5b7 100644 --- a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java +++ b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java @@ -114,6 +114,10 @@ public class VectorSupport { public static final int BT_ult = BT_lt | BT_unsigned_compare; public static final int BT_ugt = BT_gt | BT_unsigned_compare; + // Various broadcasting modes. + public static final int MODE_BROADCAST = 0; + public static final int MODE_BITS_COERCED_LONG_TO_MASK = 1; + // BasicType codes, for primitives only: public static final int T_FLOAT = 6, @@ -157,9 +161,9 @@ public class VectorSupport { } /* ============================================================================ */ - public interface BroadcastOperation> { - VM broadcast(long l, S s); + public interface FromBitsCoercedOperation> { + VM fromBits(long l, S s); } @IntrinsicCandidate @@ -167,12 +171,12 @@ public class VectorSupport { , E> - VM broadcastCoerced(Class vmClass, Class eClass, - int length, - long bits, S s, - BroadcastOperation defaultImpl) { + VM fromBitsCoerced(Class vmClass, Class eClass, + int length, + long bits, int mode, S s, + FromBitsCoercedOperation defaultImpl) { assert isNonCapturingLambda(defaultImpl) : defaultImpl; - return defaultImpl.broadcast(bits, s); + return defaultImpl.fromBits(bits, s); } /* ============================================================================ */ diff --git a/src/java.base/share/classes/sun/launcher/resources/launcher.properties b/src/java.base/share/classes/sun/launcher/resources/launcher.properties index efcc4d69969431a35398d81a083ca035d810bb87..4a80f1f685d2596b8e095e0e846bb39eb654765d 100644 --- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties +++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties @@ -194,7 +194,11 @@ java.launcher.X.usage=\n\ \ override or augment a module with classes and resources\n\ \ in JAR files or directories.\n\ \ --source \n\ -\ set the version of the source in source-file mode.\n\n\ +\ set the version of the source in source-file mode.\n\ +\ --finalization=\n\ +\ controls whether the JVM performs finalization of objects,\n\ +\ where is one of "enabled" or "disabled".\n\ +\ Finalization is enabled by default.\n\n\ These extra options are subject to change without notice.\n # Translators please note do not translate the options themselves diff --git a/src/java.base/share/classes/sun/net/NetProperties.java b/src/java.base/share/classes/sun/net/NetProperties.java index 5ff150b105a8a6ea8eaa4487cd62689539437815..d3f0bd4905bdf7113be0bb62fab821ebb2783434 100644 --- a/src/java.base/share/classes/sun/net/NetProperties.java +++ b/src/java.base/share/classes/sun/net/NetProperties.java @@ -68,10 +68,9 @@ public class NetProperties { File f = new File(fname, "conf"); f = new File(f, "net.properties"); fname = f.getCanonicalPath(); - InputStream in = new FileInputStream(fname); - BufferedInputStream bin = new BufferedInputStream(in); - props.load(bin); - bin.close(); + try (FileInputStream in = new FileInputStream(fname)) { + props.load(in); + } } catch (Exception e) { // Do nothing. We couldn't find or access the file // so we won't have default properties... diff --git a/src/java.base/share/classes/sun/net/www/MeteredStream.java b/src/java.base/share/classes/sun/net/www/MeteredStream.java index 049b16c03c6b90828ee8fdcb2e87eb17a81e98c8..fc0579a679e107c9325e4b63326e0f8f0db3b912 100644 --- a/src/java.base/share/classes/sun/net/www/MeteredStream.java +++ b/src/java.base/share/classes/sun/net/www/MeteredStream.java @@ -242,7 +242,7 @@ public class MeteredStream extends FilterInputStream { return readLock.isHeldByCurrentThread(); } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { try { close(); diff --git a/src/java.base/share/classes/sun/net/www/MimeEntry.java b/src/java.base/share/classes/sun/net/www/MimeEntry.java index 48b847cf558d18fb570655254a8a21809ad4064a..3422b58e1bc39cc6bb1eb7db7bca053f6fcaf5fc 100644 --- a/src/java.base/share/classes/sun/net/www/MimeEntry.java +++ b/src/java.base/share/classes/sun/net/www/MimeEntry.java @@ -24,7 +24,6 @@ */ package sun.net.www; -import java.net.URL; import java.io.*; import java.util.StringJoiner; import java.util.StringTokenizer; @@ -63,34 +62,6 @@ public class MimeEntry implements Cloneable { this(type, UNKNOWN, null, null, null); } - // - // The next two constructors are used only by the deprecated - // PlatformMimeTable classes or, in last case, is called by the public - // constructor. They are kept here anticipating putting support for - // mailcap formatted config files back in (so BOTH the properties format - // and the mailcap formats are supported). - // - MimeEntry(String type, String imageFileName, String extensionString) { - typeName = type.toLowerCase(); - action = UNKNOWN; - command = null; - this.imageFileName = imageFileName; - setExtensions(extensionString); - starred = isStarred(typeName); - } - - // For use with MimeTable::parseMailCap - MimeEntry(String typeName, int action, String command, - String tempFileNameTemplate) { - this.typeName = typeName.toLowerCase(); - this.action = action; - this.command = command; - this.imageFileName = null; - this.fileExtensions = null; - - this.tempFileNameTemplate = tempFileNameTemplate; - } - // This is the one called by the public constructor. MimeEntry(String typeName, int action, String command, String imageFileName, String fileExtensions[]) { diff --git a/src/java.base/share/classes/sun/net/www/MimeTable.java b/src/java.base/share/classes/sun/net/www/MimeTable.java index fd8c5565dfafcdddd8192e0f20ab69c055246711..accbe8b1c199945fd5969a13cb782f24330b9e8e 100644 --- a/src/java.base/share/classes/sun/net/www/MimeTable.java +++ b/src/java.base/share/classes/sun/net/www/MimeTable.java @@ -37,11 +37,11 @@ import java.util.StringTokenizer; public class MimeTable implements FileNameMap { /** Keyed by content type, returns MimeEntries */ private Hashtable entries - = new Hashtable(); + = new Hashtable<>(); /** Keyed by file extension (with the .), returns MimeEntries */ private Hashtable extensionMap - = new Hashtable(); + = new Hashtable<>(); // Will be reset if in the platform-specific data file @SuppressWarnings("removal") @@ -55,7 +55,6 @@ public class MimeTable implements FileNameMap { }); private static final String filePreamble = "sun.net.www MIME content-types table"; - private static final String fileMagic = "#" + filePreamble; MimeTable() { load(); @@ -67,7 +66,7 @@ public class MimeTable implements FileNameMap { @SuppressWarnings("removal") static MimeTable getDefaultInstance() { return java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public MimeTable run() { MimeTable instance = new MimeTable(); URLConnection.setFileNameMap(instance); @@ -244,8 +243,8 @@ public class MimeTable implements FileNameMap { throw new InternalError("default mime table not found"); } - try (BufferedInputStream bin = new BufferedInputStream(in)) { - entries.load(bin); + try (in) { + entries.load(in); } catch (IOException e) { System.err.println("Warning: " + e.getMessage()); } @@ -349,17 +348,6 @@ public class MimeTable implements FileNameMap { // else illegal name exception } - String[] getExtensions(String list) { - StringTokenizer tokenizer = new StringTokenizer(list, ","); - int n = tokenizer.countTokens(); - String[] extensions = new String[n]; - for (int i = 0; i < n; i++) { - extensions[i] = tokenizer.nextToken(); - } - - return extensions; - } - int getActionCode(String action) { for (int i = 0; i < MimeEntry.actionKeywords.length; i++) { if (action.equalsIgnoreCase(MimeEntry.actionKeywords[i])) { @@ -382,9 +370,7 @@ public class MimeTable implements FileNameMap { } protected boolean saveAsProperties(File file) { - FileOutputStream os = null; - try { - os = new FileOutputStream(file); + try (FileOutputStream os = new FileOutputStream(file)) { Properties properties = getAsProperties(); properties.put("temp.file.template", tempFileTemplate); String tag; @@ -407,11 +393,6 @@ public class MimeTable implements FileNameMap { e.printStackTrace(); return false; } - finally { - if (os != null) { - try { os.close(); } catch (IOException e) {} - } - } return true; } diff --git a/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/src/java.base/share/classes/sun/net/www/http/HttpClient.java index 4b3c40b4fc01f7ed30f680409a2e1e725a48b716..8993f0c2a0af42317bf3b35054e4c8edd69c2edc 100644 --- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java +++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java @@ -144,12 +144,27 @@ public class HttpClient extends NetworkClient { // Traffic capture tool, if configured. See HttpCapture class for info private HttpCapture capture = null; + /* "jdk.https.negotiate.cbt" property can be set to "always" (always sent), "never" (never sent) or + * "domain:a,c.d,*.e.f" (sent to host a, or c.d or to the domain e.f and any of its subdomains). This is + * a comma separated list of arbitrary length with no white-space allowed. + * If enabled (for a particular destination) then Negotiate/SPNEGO authentication requests will include + * a channel binding token for the destination server. The default behavior and setting for the + * property is "never" + */ + private static final String spnegoCBT; + private static final PlatformLogger logger = HttpURLConnection.getHttpLogger(); + private static void logFinest(String msg) { if (logger.isLoggable(PlatformLogger.Level.FINEST)) { logger.finest(msg); } } + private static void logError(String msg) { + if (logger.isLoggable(PlatformLogger.Level.SEVERE)) { + logger.severe(msg); + } + } protected volatile String authenticatorKey; @@ -165,6 +180,18 @@ public class HttpClient extends NetworkClient { return keepAliveTimeout; } + static String normalizeCBT(String s) { + if (s == null || s.equals("never")) { + return "never"; + } + if (s.equals("always") || s.startsWith("domain:")) { + return s; + } else { + logError("Unexpected value for \"jdk.https.negotiate.cbt\" system property"); + return "never"; + } + } + static { Properties props = GetPropertyAction.privilegedGetProperties(); String keepAlive = props.getProperty("http.keepAlive"); @@ -172,6 +199,9 @@ public class HttpClient extends NetworkClient { String cacheNTLM = props.getProperty("jdk.ntlm.cache"); String cacheSPNEGO = props.getProperty("jdk.spnego.cache"); + String s = props.getProperty("jdk.https.negotiate.cbt"); + spnegoCBT = normalizeCBT(s); + if (keepAlive != null) { keepAliveProp = Boolean.parseBoolean(keepAlive); } else { @@ -206,6 +236,10 @@ public class HttpClient extends NetworkClient { } + public String getSpnegoCBT() { + return spnegoCBT; + } + protected HttpClient() { } diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java index 038f7adfe905880754fe68a93b4f543f1df3cf2a..5afed084c7f35603b048b2a6530afee2228b0f9c 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java @@ -29,6 +29,7 @@ import java.net.Authenticator; import java.net.Authenticator.RequestorType; import java.net.InetAddress; import java.net.URL; +import java.security.cert.X509Certificate; /** * Used in HTTP/Negotiate, to feed HTTP request info into JGSS as a HttpCaller, @@ -51,6 +52,9 @@ public final class HttpCallerInfo { public final InetAddress addr; public final RequestorType authType; public final Authenticator authenticator; + // Used to obtain server cert for SPNEGO CBT. + // May be null in which case CBT is not set + public final X509Certificate serverCert; /** * Create a schemed object based on an un-schemed one. @@ -65,13 +69,19 @@ public final class HttpCallerInfo { this.authType = old.authType; this.scheme = scheme; this.authenticator = old.authenticator; + this.serverCert = old.serverCert; } /** * Constructor an un-schemed object for site access. */ public HttpCallerInfo(URL url, Authenticator a) { + this(url, null, a); + } + + public HttpCallerInfo(URL url, X509Certificate serverCert, Authenticator a) { this.url= url; + this.serverCert= serverCert; prompt = ""; host = url.getHost(); @@ -100,9 +110,14 @@ public final class HttpCallerInfo { * Constructor an un-schemed object for proxy access. */ public HttpCallerInfo(URL url, String host, int port, Authenticator a) { + this(url, host, port, null, a); + } + + public HttpCallerInfo(URL url, String host, int port, X509Certificate serverCert, Authenticator a) { this.url= url; this.host = host; this.port = port; + this.serverCert = serverCert; prompt = ""; addr = null; protocol = url.getProtocol(); diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index cba385f04fa2a2621ad853b7817576f794d6f191..0ce0d29ee675e18ec1cccfd6249cf5506ea0f91e 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -288,8 +288,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } static final String httpVersion = "HTTP/1.1"; - static final String acceptString = - "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"; + static final String acceptString = "*/*"; // the following http request headers should NOT have their values // returned for security reasons. @@ -1740,7 +1739,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { AuthenticationHeader authhdr = new AuthenticationHeader ( "Proxy-Authenticate", responses, - new HttpCallerInfo(url, + getHttpCallerInfo(url, http.getProxyHostUsed(), http.getProxyPortUsed(), authenticator), @@ -1815,7 +1814,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { srvHdr = new AuthenticationHeader ( "WWW-Authenticate", responses, - new HttpCallerInfo(url, authenticator), + getHttpCallerInfo(url, authenticator), dontUseNegotiate ); @@ -2211,7 +2210,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { AuthenticationHeader authhdr = new AuthenticationHeader( "Proxy-Authenticate", responses, - new HttpCallerInfo(url, + getHttpCallerInfo(url, http.getProxyHostUsed(), http.getProxyPortUsed(), authenticator), @@ -2280,6 +2279,21 @@ public class HttpURLConnection extends java.net.HttpURLConnection { responses.reset(); } + /** + * Overridden in https to also include the server certificate + */ + protected HttpCallerInfo getHttpCallerInfo(URL url, String proxy, int port, + Authenticator authenticator) { + return new HttpCallerInfo(url, proxy, port, authenticator); + } + + /** + * Overridden in https to also include the server certificate + */ + protected HttpCallerInfo getHttpCallerInfo(URL url, Authenticator authenticator) { + return new HttpCallerInfo(url, authenticator); + } + static String connectRequestURI(URL url) { String host = url.getHost(); int port = url.getPort(); diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java index 3828eb3cd29a38cad87f9c6b7428fa7287e0f3f5..7ed4381dda6e6c231fb2542a7694beacbf8ab120 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,10 +25,13 @@ package sun.net.www.protocol.https; +import java.net.Authenticator; import java.net.URL; import java.net.Proxy; import java.net.SecureCacheResponse; import java.security.Principal; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; import java.io.IOException; import java.util.List; import java.util.Optional; @@ -36,6 +39,7 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.SSLPeerUnverifiedException; import sun.net.www.http.*; import sun.net.www.protocol.http.HttpURLConnection; +import sun.net.www.protocol.http.HttpCallerInfo; /** * HTTPS URL connection support. @@ -309,4 +313,71 @@ public abstract class AbstractDelegateHttpsURLConnection extends return ((HttpsClient)http).getSSLSession(); } + + /* + * If no SSL Session available or if the system config does not allow it + * don't use the extended caller info (the server cert). + * Otherwise return true to include the server cert + */ + private boolean useExtendedCallerInfo(URL url) { + HttpsClient https = (HttpsClient)http; + if (https.getSSLSession() == null) { + return false; + } + String prop = http.getSpnegoCBT(); + if (prop.equals("never")) { + return false; + } + String target = url.getHost(); + if (prop.startsWith("domain:")) { + String[] domains = prop.substring(7).split(","); + for (String domain : domains) { + if (target.equals(domain)) { + return true; + } + if (domain.startsWith("*.") && target.endsWith(domain.substring(1))) { + return true; + } + } + return false; + } + return true; + } + + @Override + protected HttpCallerInfo getHttpCallerInfo(URL url, String proxy, int port, + Authenticator authenticator) + { + if (!useExtendedCallerInfo(url)) { + return super.getHttpCallerInfo(url, proxy, port, authenticator); + } + HttpsClient https = (HttpsClient)http; + try { + Certificate[] certs = https.getServerCertificates(); + if (certs[0] instanceof X509Certificate x509Cert) { + return new HttpCallerInfo(url, proxy, port, x509Cert, authenticator); + } + } catch (SSLPeerUnverifiedException e) { + // ignore + } + return super.getHttpCallerInfo(url, proxy, port, authenticator); + } + + @Override + protected HttpCallerInfo getHttpCallerInfo(URL url, Authenticator authenticator) + { + if (!useExtendedCallerInfo(url)) { + return super.getHttpCallerInfo(url, authenticator); + } + HttpsClient https = (HttpsClient)http; + try { + Certificate[] certs = https.getServerCertificates(); + if (certs[0] instanceof X509Certificate x509Cert) { + return new HttpCallerInfo(url, x509Cert, authenticator); + } + } catch (SSLPeerUnverifiedException e) { + // ignore + } + return super.getHttpCallerInfo(url, authenticator); + } } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java index 4ccf7819914400104a3b0cf9c94c7a6bab73f2eb..234827fb76f2ef2fd45ead6d3520852a2baf31cf 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java @@ -25,21 +25,17 @@ package sun.net.www.protocol.jar; -import java.io.InputStream; -import java.io.IOException; -import java.io.FileNotFoundException; import java.io.BufferedInputStream; -import java.net.URL; -import java.net.URLConnection; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; -import java.net.UnknownServiceException; -import java.util.Enumeration; -import java.util.Map; +import java.net.URL; +import java.security.Permission; import java.util.List; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.security.Permission; /** * @author Benjamin Renaud @@ -47,26 +43,10 @@ import java.security.Permission; */ public class JarURLConnection extends java.net.JarURLConnection { - private static final boolean debug = false; - /* the Jar file factory. It handles both retrieval and caching. */ private static final JarFileFactory factory = JarFileFactory.getInstance(); - /* the url for the Jar file */ - private URL jarFileURL; - - /* the permission to get this JAR file. This is the actual, ultimate, - * permission, returned by the jar file factory. - */ - private Permission permission; - - /* the url connection for the JAR file */ - private URLConnection jarFileURLConnection; - - /* the entry name, if any */ - private String entryName; - /* the JarEntry */ private JarEntry jarEntry; @@ -80,12 +60,10 @@ public class JarURLConnection extends java.net.JarURLConnection { throws MalformedURLException, IOException { super(url); - jarFileURL = getJarFileURL(); - jarFileURLConnection = jarFileURL.openConnection(); + jarFileURLConnection = getJarFileURL().openConnection(); // whether, or not, the embedded URL should use the cache will depend // on this instance's cache value jarFileURLConnection.setUseCaches(useCaches); - entryName = getEntryName(); } public JarFile getJarFile() throws IOException { @@ -120,7 +98,7 @@ public class JarURLConnection extends java.net.JarURLConnection { public void connect() throws IOException { if (!connected) { boolean useCaches = getUseCaches(); - String entryName = this.entryName; + String entryName = getEntryName(); /* the factory call will do the security checks */ URL url = getJarFileURL(); @@ -176,6 +154,7 @@ public class JarURLConnection extends java.net.JarURLConnection { InputStream result = null; + String entryName = getEntryName(); if (entryName == null) { throw new IOException("no entry name specified"); } else { @@ -216,7 +195,7 @@ public class JarURLConnection extends java.net.JarURLConnection { Object result = null; connect(); - if (entryName == null) { + if (getEntryName() == null) { result = jarFile; } else { result = super.getContent(); @@ -226,6 +205,7 @@ public class JarURLConnection extends java.net.JarURLConnection { public String getContentType() { if (contentType == null) { + String entryName = getEntryName(); if (entryName == null) { contentType = "x-java/jar"; } else { diff --git a/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java index e9052397483abdeb6c17274ffb88100947b387ea..cb8e490995e5f467d6f75ac87f4a590e3c9e8b25 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. * 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,10 +32,6 @@ package sun.net.www.protocol.mailto; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; -import java.io.*; -import sun.net.www.*; -//import sun.net.www.protocol.news.ArticlePoster; -import sun.net.smtp.SmtpClient; /** open an nntp input stream given a URL */ public class Handler extends URLStreamHandler { @@ -99,7 +95,7 @@ public class Handler extends URLStreamHandler { // } */ - public synchronized URLConnection openConnection(URL u) { + public URLConnection openConnection(URL u) { return new MailToURLConnection(u); } @@ -126,33 +122,16 @@ public class Handler extends URLStreamHandler { /* * Let's just make sure we DO have an Email address in the URL. */ - boolean nogood = false; - if (file == null || file.isEmpty()) - nogood = true; - else { - boolean allwhites = true; - for (int i = 0; i < file.length(); i++) - if (!Character.isWhitespace(file.charAt(i))) - allwhites = false; - if (allwhites) - nogood = true; - } - if (nogood) + if (file.isBlank()) throw new RuntimeException("No email address"); - setURLHandler(u, protocol, host, port, file, null); + setURLHandler(u, protocol, host, port, file); } /** * This method is used to suppress the deprecated warning - * - * @param u the URL to receive the result of parsing the spec - * @param spec the URL string to parse - * @param start the character position to start parsing at. This is - * just past the ':'. - * @param limit the character position to stop parsing at. */ @SuppressWarnings("deprecation") - private void setURLHandler(URL u, String protocol, String host, int port, String file, String ref) { - setURL(u,protocol,host,port,file,null); + private void setURLHandler(URL u, String protocol, String host, int port, String file) { + setURL(u, protocol, host, port, file, null); } } diff --git a/src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java b/src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java index 4ddd30485af4a992dc5d9f2b91df638110b088f9..6397eda0c936722dcf34b3f442239c1fb2263e2c 100644 --- a/src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java +++ b/src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,58 +40,52 @@ import java.util.Objects; import jdk.internal.util.ArraysSupport; /** - * This class is defined here rather than in java.nio.channels.Channels - * so that code can be shared with SocketAdaptor. + * An InputStream that reads bytes from a channel. * * @author Mike McCloskey * @author Mark Reinhold - * @since 1.4 */ - -public class ChannelInputStream - extends InputStream -{ +class ChannelInputStream extends InputStream { private static final int DEFAULT_BUFFER_SIZE = 8192; - public static int read(ReadableByteChannel ch, ByteBuffer bb, - boolean block) - throws IOException - { + private final ReadableByteChannel ch; + private ByteBuffer bb; + private byte[] bs; // Invoker's previous array + private byte[] b1; + + /** + * Initialize a ChannelInputStream that reads from the given channel. + */ + ChannelInputStream(ReadableByteChannel ch) { + this.ch = ch; + } + + /** + * Reads a sequence of bytes from the channel into the given buffer. + */ + private int read(ByteBuffer bb) throws IOException { if (ch instanceof SelectableChannel sc) { synchronized (sc.blockingLock()) { - boolean bm = sc.isBlocking(); - if (!bm) + if (!sc.isBlocking()) throw new IllegalBlockingModeException(); - if (bm != block) - sc.configureBlocking(block); - int n = ch.read(bb); - if (bm != block) - sc.configureBlocking(bm); - return n; + return ch.read(bb); } } else { return ch.read(bb); } } - protected final ReadableByteChannel ch; - private ByteBuffer bb = null; - private byte[] bs = null; // Invoker's previous array - private byte[] b1 = null; - - public ChannelInputStream(ReadableByteChannel ch) { - this.ch = ch; - } - + @Override public synchronized int read() throws IOException { if (b1 == null) b1 = new byte[1]; - int n = this.read(b1); + int n = read(b1); if (n == 1) return b1[0] & 0xff; return -1; } + @Override public synchronized int read(byte[] bs, int off, int len) throws IOException { @@ -109,12 +103,6 @@ public class ChannelInputStream return read(bb); } - protected int read(ByteBuffer bb) - throws IOException - { - return ChannelInputStream.read(ch, bb, true); - } - @Override public byte[] readAllBytes() throws IOException { if (!(ch instanceof SeekableByteChannel sbc)) @@ -201,6 +189,7 @@ public class ChannelInputStream return (capacity == nread) ? buf : Arrays.copyOf(buf, nread); } + @Override public int available() throws IOException { // special case where the channel is to a file if (ch instanceof SeekableByteChannel sbc) { @@ -210,6 +199,7 @@ public class ChannelInputStream return 0; } + @Override public synchronized long skip(long n) throws IOException { // special case where the channel is to a file if (ch instanceof SeekableByteChannel sbc) { @@ -230,46 +220,62 @@ public class ChannelInputStream return super.skip(n); } - public void close() throws IOException { - ch.close(); - } - @Override public long transferTo(OutputStream out) throws IOException { Objects.requireNonNull(out, "out"); - if (out instanceof ChannelOutputStream cos - && ch instanceof FileChannel fc) { - WritableByteChannel wbc = cos.channel(); - - if (wbc instanceof FileChannel dst) { - return transfer(fc, dst); - } - - if (wbc instanceof SelectableChannel sc) { + if (ch instanceof FileChannel fc) { + // FileChannel -> SocketChannel + if (out instanceof SocketOutputStream sos) { + SocketChannelImpl sc = sos.channel(); synchronized (sc.blockingLock()) { if (!sc.isBlocking()) throw new IllegalBlockingModeException(); - return transfer(fc, wbc); + return transfer(fc, sc); } } - return transfer(fc, wbc); + // FileChannel -> WritableByteChannel + if (out instanceof ChannelOutputStream cos) { + WritableByteChannel wbc = cos.channel(); + + if (wbc instanceof SelectableChannel sc) { + synchronized (sc.blockingLock()) { + if (!sc.isBlocking()) + throw new IllegalBlockingModeException(); + return transfer(fc, wbc); + } + } + + return transfer(fc, wbc); + } } return super.transferTo(out); } - private static long transfer(FileChannel src, WritableByteChannel dst) throws IOException { - long initialPos = src.position(); + /** + * Transfers all bytes from a channel's file to a target writeable byte channel. + * If the writeable byte channel is a selectable channel then it must be in + * blocking mode. + */ + private static long transfer(FileChannel fc, WritableByteChannel target) + throws IOException + { + long initialPos = fc.position(); long pos = initialPos; try { - while (pos < src.size()) { - pos += src.transferTo(pos, Long.MAX_VALUE, dst); + while (pos < fc.size()) { + pos += fc.transferTo(pos, Long.MAX_VALUE, target); } } finally { - src.position(pos); + fc.position(pos); } return pos - initialPos; } + + @Override + public void close() throws IOException { + ch.close(); + } } diff --git a/src/java.base/share/classes/sun/nio/ch/ChannelOutputStream.java b/src/java.base/share/classes/sun/nio/ch/ChannelOutputStream.java index a1e838efab460c191949770c35662fe347db4fbb..dff8af9ebafc14c4e1629d12a15e93b655b3e454 100644 --- a/src/java.base/share/classes/sun/nio/ch/ChannelOutputStream.java +++ b/src/java.base/share/classes/sun/nio/ch/ChannelOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,68 +25,30 @@ package sun.nio.ch; -import java.io.*; -import java.nio.*; -import java.nio.channels.*; -import java.nio.channels.spi.*; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.WritableByteChannel; import java.util.Objects; /** - * This class is defined here rather than in java.nio.channels.Channels - * so that it will be accessible from java.nio.channels.Channels and - * sun.nio.ch.ChannelInputStream. - * + * An OutputStream that writes bytes to a channel. * * @author Mark Reinhold * @author Mike McCloskey - * @author JSR-51 Expert Group - * @since 18 */ -public class ChannelOutputStream extends OutputStream { - +class ChannelOutputStream extends OutputStream { private final WritableByteChannel ch; private ByteBuffer bb; private byte[] bs; // Invoker's previous array private byte[] b1; /** - * Write all remaining bytes in buffer to the given channel. - * If the channel is selectable then it must be configured blocking. - */ - private static void writeFullyImpl(WritableByteChannel ch, ByteBuffer bb) - throws IOException - { - while (bb.remaining() > 0) { - int n = ch.write(bb); - if (n <= 0) - throw new RuntimeException("no bytes written"); - } - } - - /** - * Write all remaining bytes in buffer to the given channel. - * - * @throws IllegalBlockingModeException - * If the channel is selectable and configured non-blocking. - */ - private static void writeFully(WritableByteChannel ch, ByteBuffer bb) - throws IOException - { - if (ch instanceof SelectableChannel sc) { - synchronized (sc.blockingLock()) { - if (!sc.isBlocking()) - throw new IllegalBlockingModeException(); - writeFullyImpl(ch, bb); - } - } else { - writeFullyImpl(ch, bb); - } - } - - /** - * @param ch The channel wrapped by this stream. + * Initialize a ChannelOutputStream that writes to the given channel. */ - public ChannelOutputStream(WritableByteChannel ch) { + ChannelOutputStream(WritableByteChannel ch) { this.ch = ch; } @@ -97,17 +59,30 @@ public class ChannelOutputStream extends OutputStream { return ch; } + /** + * Write all remaining bytes in buffer to the channel. + * If the channel is selectable then it must be configured blocking. + */ + private void writeFully(ByteBuffer bb) throws IOException { + while (bb.remaining() > 0) { + int n = ch.write(bb); + if (n <= 0) + throw new RuntimeException("no bytes written"); + } + } + @Override public synchronized void write(int b) throws IOException { if (b1 == null) b1 = new byte[1]; b1[0] = (byte) b; - this.write(b1); + write(b1); } @Override public synchronized void write(byte[] bs, int off, int len) - throws IOException { + throws IOException + { Objects.checkFromIndexSize(off, len, bs.length); if (len == 0) { return; @@ -119,12 +94,20 @@ public class ChannelOutputStream extends OutputStream { bb.position(off); this.bb = bb; this.bs = bs; - writeFully(ch, bb); + + if (ch instanceof SelectableChannel sc) { + synchronized (sc.blockingLock()) { + if (!sc.isBlocking()) + throw new IllegalBlockingModeException(); + writeFully(bb); + } + } else { + writeFully(bb); + } } @Override public void close() throws IOException { ch.close(); } - } diff --git a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java index bcab4b67a75754414a3c9c89ecbd6966cda40d79..745d8d7f1f8a0674cbd5f8eca4fefa37d5838461 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -177,32 +177,7 @@ class SocketAdaptor throw new SocketException("Socket is not connected"); if (!sc.isInputOpen()) throw new SocketException("Socket input is shutdown"); - return new InputStream() { - @Override - public int read() throws IOException { - byte[] a = new byte[1]; - int n = read(a, 0, 1); - return (n > 0) ? (a[0] & 0xff) : -1; - } - @Override - public int read(byte[] b, int off, int len) throws IOException { - int timeout = SocketAdaptor.this.timeout; - if (timeout > 0) { - long nanos = MILLISECONDS.toNanos(timeout); - return sc.blockingRead(b, off, len, nanos); - } else { - return sc.blockingRead(b, off, len, 0); - } - } - @Override - public int available() throws IOException { - return sc.available(); - } - @Override - public void close() throws IOException { - sc.close(); - } - }; + return new SocketInputStream(sc, () -> timeout); } @Override @@ -213,21 +188,7 @@ class SocketAdaptor throw new SocketException("Socket is not connected"); if (!sc.isOutputOpen()) throw new SocketException("Socket output is shutdown"); - return new OutputStream() { - @Override - public void write(int b) throws IOException { - byte[] a = new byte[]{(byte) b}; - write(a, 0, 1); - } - @Override - public void write(byte[] b, int off, int len) throws IOException { - sc.blockingWriteFully(b, off, len); - } - @Override - public void close() throws IOException { - sc.close(); - } - }; + return new SocketOutputStream(sc); } private void setBooleanOption(SocketOption name, boolean value) diff --git a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java index 477fa1afca2384391734437f2d1d326a3c66ddf5..117c14d5711e55c45eaed7593587d75249367e7e 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java @@ -700,11 +700,11 @@ class SocketChannelImpl private SocketAddress unixBind(SocketAddress local) throws IOException { UnixDomainSockets.checkPermission(); if (local == null) { - return UnixDomainSockets.UNNAMED; + return UnixDomainSockets.unnamed(); } else { Path path = UnixDomainSockets.checkAddress(local).getPath(); if (path.toString().isEmpty()) { - return UnixDomainSockets.UNNAMED; + return UnixDomainSockets.unnamed(); } else { // bind to non-empty path UnixDomainSockets.bind(fd, path); diff --git a/src/java.base/share/classes/sun/nio/ch/SocketInputStream.java b/src/java.base/share/classes/sun/nio/ch/SocketInputStream.java new file mode 100644 index 0000000000000000000000000000000000000000..6c69eaf5214c74822eab09419d9acf409b0484b9 --- /dev/null +++ b/src/java.base/share/classes/sun/nio/ch/SocketInputStream.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.nio.ch; + +import java.io.IOException; +import java.io.InputStream; +import java.util.function.IntSupplier; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +/** + * An InputStream that reads bytes from a socket channel. + */ +class SocketInputStream extends InputStream { + private final SocketChannelImpl sc; + private final IntSupplier timeoutSupplier; + + /** + * Initialize a SocketInputStream that reads from the given socket channel. + * @param sc the socket channel + * @param timeoutSupplier supplies the read timeout, in milliseconds + */ + SocketInputStream(SocketChannelImpl sc, IntSupplier timeoutSupplier) { + this.sc = sc; + this.timeoutSupplier = timeoutSupplier; + } + + /** + * Initialize a SocketInputStream that reads from the given socket channel. + */ + SocketInputStream(SocketChannelImpl sc) { + this(sc, () -> 0); + } + + @Override + public int read() throws IOException { + byte[] a = new byte[1]; + int n = read(a, 0, 1); + return (n > 0) ? (a[0] & 0xff) : -1; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int timeout = timeoutSupplier.getAsInt(); + if (timeout > 0) { + long nanos = MILLISECONDS.toNanos(timeout); + return sc.blockingRead(b, off, len, nanos); + } else { + return sc.blockingRead(b, off, len, 0); + } + } + + @Override + public int available() throws IOException { + return sc.available(); + } + + @Override + public void close() throws IOException { + sc.close(); + } +} diff --git a/src/java.base/share/classes/sun/nio/ch/SocketOutputStream.java b/src/java.base/share/classes/sun/nio/ch/SocketOutputStream.java new file mode 100644 index 0000000000000000000000000000000000000000..78d0dce46fa1e4fc726c544701b5049ae38217b3 --- /dev/null +++ b/src/java.base/share/classes/sun/nio/ch/SocketOutputStream.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.nio.ch; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * An OutputStream that writes bytes to a socket channel. + */ +class SocketOutputStream extends OutputStream { + private final SocketChannelImpl sc; + + /** + * Initialize a SocketOutputStream that writes to the given socket channel. + */ + SocketOutputStream(SocketChannelImpl sc) { + this.sc = sc; + } + + /** + * Returns the socket channel. + */ + SocketChannelImpl channel() { + return sc; + } + + @Override + public void write(int b) throws IOException { + byte[] a = new byte[]{(byte) b}; + write(a, 0, 1); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + sc.blockingWriteFully(b, off, len); + } + + @Override + public void close() throws IOException { + sc.close(); + } +} diff --git a/src/java.base/share/classes/sun/nio/ch/Streams.java b/src/java.base/share/classes/sun/nio/ch/Streams.java new file mode 100644 index 0000000000000000000000000000000000000000..4326c9e2e0b911711fb2190798c7fd4cd6f77326 --- /dev/null +++ b/src/java.base/share/classes/sun/nio/ch/Streams.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.nio.ch; + +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; + +/** + * Factory methods for input/output streams based on channels. + */ +public class Streams { + private Streams() { } + + /** + * Return an input stream that reads bytes from the given channel. + */ + public static InputStream of(ReadableByteChannel ch) { + if (ch instanceof SocketChannelImpl sc) { + return new SocketInputStream(sc); + } else { + return new ChannelInputStream(ch); + } + } + + /** + * Return an output stream that writes bytes to the given channel. + */ + public static OutputStream of(WritableByteChannel ch) { + if (ch instanceof SocketChannelImpl sc) { + return new SocketOutputStream(sc); + } else { + return new ChannelOutputStream(ch); + } + } +} diff --git a/src/java.base/share/classes/sun/nio/ch/UnixDomainSockets.java b/src/java.base/share/classes/sun/nio/ch/UnixDomainSockets.java index ee7e1d9d51ab92801a89f9c64588c3908eccf752..251e79c6ecc694ad45f1a27865230486d38c42bf 100644 --- a/src/java.base/share/classes/sun/nio/ch/UnixDomainSockets.java +++ b/src/java.base/share/classes/sun/nio/ch/UnixDomainSockets.java @@ -44,7 +44,9 @@ import sun.nio.fs.AbstractFileSystemProvider; class UnixDomainSockets { private UnixDomainSockets() { } - static final UnixDomainSocketAddress UNNAMED = UnixDomainSocketAddress.of(""); + private static class UnnamedHolder { + static final UnixDomainSocketAddress UNNAMED = UnixDomainSocketAddress.of(""); + } private static final boolean supported; @@ -71,7 +73,7 @@ class UnixDomainSockets { // Security check passed } catch (SecurityException e) { // Return unnamed address only if security check fails - addr = UNNAMED; + addr = unnamed(); } return addr; } @@ -133,7 +135,11 @@ class UnixDomainSockets { throw new BindException("Could not locate temporary directory for sockets"); int rnd = random.nextInt(Integer.MAX_VALUE); try { - Path path = Path.of(dir, "socket_" + rnd); + final Path path = Path.of(dir, "socket_" + rnd); + if (path.getFileSystem().provider() != sun.nio.fs.DefaultFileSystemProvider.instance()) { + throw new UnsupportedOperationException( + "Unix Domain Sockets not supported on non-default file system"); + } return UnixDomainSocketAddress.of(path); } catch (InvalidPathException e) { throw new BindException("Invalid temporary directory"); @@ -160,6 +166,10 @@ class UnixDomainSockets { return n; } + static UnixDomainSocketAddress unnamed() { + return UnnamedHolder.UNNAMED; + } + private static native boolean init(); private static native int socket0() throws IOException; diff --git a/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java index 5c7356fca81a11113e2bbcbd64d3280ed43bdbae..fc51faad6fce86c3b1cbf8c46a1ba4eb0b27bc11 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java +++ b/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java @@ -132,7 +132,8 @@ public final class TypeAnnotationParser { Class declaringClass = ctor.getDeclaringClass(); if (!declaringClass.isEnum() && (declaringClass.isMemberClass() && - (declaringClass.getModifiers() & Modifier.STATIC) == 0) ) { + (declaringClass.getModifiers() & Modifier.STATIC) == 0) && + filter == TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER) { offset = true; } } diff --git a/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java b/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java index 125da2c9e2c58901af3f0a0998e6e9c44c7ff711..fbc6a46fc00ac9e71a6428819d023ea2f11a1131 100644 --- a/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java +++ b/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -127,7 +127,9 @@ public class ContentInfo { if (oldStyle) { // JDK1.1.x-style encoding - content = typeAndContent[1]; + if (typeAndContent.length > 1) { // content is OPTIONAL + content = typeAndContent[1]; + } } else { // This is the correct, standards-compliant encoding. // Parse the content (OPTIONAL field). diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java index 79eaee18862c6c09bfcdb81895a4c9300afcdb3b..6083cb18afcb702fb02e918e82a435d3ca71f8fa 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java @@ -481,12 +481,12 @@ public class PKCS9Attribute implements DerEncoder { "attribute not supported."); // break unnecessary case 10: // issuerAndserialNumber attribute -- not supported - throw new IOException("PKCS9 IssuerAndSerialNumber" + + throw new IOException("PKCS9 IssuerAndSerialNumber " + "attribute not supported."); // break unnecessary case 11: // RSA DSI proprietary case 12: // RSA DSI proprietary - throw new IOException("PKCS9 RSA DSI attributes" + + throw new IOException("PKCS9 RSA DSI attributes " + "11 and 12, not supported."); // break unnecessary case 13: // S/MIME unused attribute @@ -604,12 +604,12 @@ public class PKCS9Attribute implements DerEncoder { "attribute not supported."); // break unnecessary case 10: // issuerAndserialNumber attribute -- not supported - throw new IOException("PKCS9 IssuerAndSerialNumber" + + throw new IOException("PKCS9 IssuerAndSerialNumber " + "attribute not supported."); // break unnecessary case 11: // RSA DSI proprietary case 12: // RSA DSI proprietary - throw new IOException("PKCS9 RSA DSI attributes" + + throw new IOException("PKCS9 RSA DSI attributes " + "11 and 12, not supported."); // break unnecessary case 13: // S/MIME unused attribute diff --git a/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java b/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java index 868babb2b44231f72a4522ca32b89d5379e025b4..af466e6615683fa2dc6d5d99b906d6a878bc20ef 100644 --- a/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java +++ b/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java @@ -383,8 +383,15 @@ public class SignerInfo implements DerEncoder { if (digestAlgName.equals("SHAKE256") || digestAlgName.equals("SHAKE256-LEN")) { if (digestAlgName.equals("SHAKE256-LEN")) { - int v = new DerValue(digestAlgorithmId - .getEncodedParams()).getInteger(); + // RFC8419: for EdDSA in CMS, the id-shake256-len + // algorithm id must contain parameter value 512 + // encoded as a positive integer value + byte[] params = digestAlgorithmId.getEncodedParams(); + if (params == null) { + throw new SignatureException( + "id-shake256-len oid missing length"); + } + int v = new DerValue(params).getInteger(); if (v != 512) { throw new SignatureException( "Unsupported id-shake256-" + v); @@ -527,6 +534,7 @@ public class SignerInfo implements DerEncoder { if (spec == null) { throw new NoSuchAlgorithmException("Missing PSSParameterSpec for RSASSA-PSS algorithm"); } + if (!AlgorithmId.get(spec.getDigestAlgorithm()).equals(digAlgId)) { throw new NoSuchAlgorithmException("Incompatible digest algorithm"); } diff --git a/src/java.base/share/classes/sun/security/pkcs10/PKCS10.java b/src/java.base/share/classes/sun/security/pkcs10/PKCS10.java index 2a28f809888fedde59886c2cacd284235f70af23..05bb19fe1c10032330c0700667c725d1ee1b75af 100644 --- a/src/java.base/share/classes/sun/security/pkcs10/PKCS10.java +++ b/src/java.base/share/classes/sun/security/pkcs10/PKCS10.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,7 +141,6 @@ public class PKCS10 { // Inner sequence: version, name, key, attributes // BigInteger serial; - DerValue val; serial = seq[0].data.getBigInteger(); if (!serial.equals(BigInteger.ZERO)) diff --git a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java index 74bdedeae9ed852f488b0b7edb04be6a98c965f2..b7bc494a04a491c5b7e24acf72002d15d77c7a7e 100644 --- a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java +++ b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java @@ -635,7 +635,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { } } } else { - throw new KeyStoreException("Private key is not encoded" + + throw new KeyStoreException("Private key is not encoded " + "as PKCS#8"); } @@ -1313,7 +1313,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { return super.engineGetAttributes(alias); } Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH)); - return getAttributes(entry); + return Collections.unmodifiableSet(new HashSet<>(getAttributes(entry))); } /** @@ -2265,11 +2265,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi { /* Update existing KeyEntry in entries table */ if (chain.size() > 0) { entry.chain = chain.toArray(new Certificate[chain.size()]); - } else { - // Remove private key entries where there is no associated - // certs. Most likely the keystore is loaded with a null - // password. - entries.remove(entry); } } } diff --git a/src/java.base/share/classes/sun/security/provider/DSAParameters.java b/src/java.base/share/classes/sun/security/provider/DSAParameters.java index 9a71ae1df860b787f7ed16c4008e1711f020efa2..9b8486894623a857544959283b064fa86764e180 100644 --- a/src/java.base/share/classes/sun/security/provider/DSAParameters.java +++ b/src/java.base/share/classes/sun/security/provider/DSAParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,7 +101,7 @@ public class DSAParameters extends AlgorithmParametersSpi { try { Class dsaParamSpec = Class.forName ("java.security.spec.DSAParameterSpec"); - if (dsaParamSpec.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(dsaParamSpec)) { return paramSpec.cast( new DSAParameterSpec(this.p, this.q, this.g)); } else { diff --git a/src/java.base/share/classes/sun/security/provider/PolicyParser.java b/src/java.base/share/classes/sun/security/provider/PolicyParser.java index cc6a304cb77e6148d2d5c11d61f1a376d0dc10d9..347bc8f9b564323053a61125e899e918659dfe53 100644 --- a/src/java.base/share/classes/sun/security/provider/PolicyParser.java +++ b/src/java.base/share/classes/sun/security/provider/PolicyParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -733,8 +733,7 @@ public class PolicyParser { switch (lookahead) { case StreamTokenizer.TT_NUMBER: throw new ParsingException(st.lineno(), expect, - LocalizedMessage.getNonlocalized("number.") + - String.valueOf(st.nval)); + LocalizedMessage.getNonlocalized("number.") + st.nval); case StreamTokenizer.TT_EOF: LocalizedMessage localizedMsg = new LocalizedMessage ("expected.expect.read.end.of.file."); @@ -826,8 +825,7 @@ public class PolicyParser { switch (lookahead) { case StreamTokenizer.TT_NUMBER: throw new ParsingException(st.lineno(), ";", - LocalizedMessage.getNonlocalized("number.") + - String.valueOf(st.nval)); + LocalizedMessage.getNonlocalized("number.") + st.nval); case StreamTokenizer.TT_EOF: throw new ParsingException(LocalizedMessage.getNonlocalized ("expected.read.end.of.file.")); diff --git a/src/java.base/share/classes/sun/security/provider/SHA3.java b/src/java.base/share/classes/sun/security/provider/SHA3.java index fb21e3ceb6e0ee85ffb5d34d9c7fce0711ae2bb6..f8fdf8790a819832daa39fdcc7f472750f42de4b 100644 --- a/src/java.base/share/classes/sun/security/provider/SHA3.java +++ b/src/java.base/share/classes/sun/security/provider/SHA3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,99 +158,6 @@ abstract class SHA3 extends DigestBase { } } - /** - * Step mapping Theta as defined in section 3.2.1 . - */ - private static long[] smTheta(long[] a) { - long c0 = a[0]^a[5]^a[10]^a[15]^a[20]; - long c1 = a[1]^a[6]^a[11]^a[16]^a[21]; - long c2 = a[2]^a[7]^a[12]^a[17]^a[22]; - long c3 = a[3]^a[8]^a[13]^a[18]^a[23]; - long c4 = a[4]^a[9]^a[14]^a[19]^a[24]; - long d0 = c4 ^ Long.rotateLeft(c1, 1); - long d1 = c0 ^ Long.rotateLeft(c2, 1); - long d2 = c1 ^ Long.rotateLeft(c3, 1); - long d3 = c2 ^ Long.rotateLeft(c4, 1); - long d4 = c3 ^ Long.rotateLeft(c0, 1); - for (int y = 0; y < a.length; y += DM) { - a[y] ^= d0; - a[y+1] ^= d1; - a[y+2] ^= d2; - a[y+3] ^= d3; - a[y+4] ^= d4; - } - return a; - } - - /** - * Merged Step mapping Rho (section 3.2.2) and Pi (section 3.2.3). - * for performance. Optimization is achieved by precalculating - * shift constants for the following loop - * int xNext, yNext; - * for (int t = 0, x = 1, y = 0; t <= 23; t++, x = xNext, y = yNext) { - * int numberOfShift = ((t + 1)*(t + 2)/2) % 64; - * a[y][x] = Long.rotateLeft(a[y][x], numberOfShift); - * xNext = y; - * yNext = (2 * x + 3 * y) % DM; - * } - * and with inplace permutation. - */ - private static long[] smPiRho(long[] a) { - long tmp = Long.rotateLeft(a[10], 3); - a[10] = Long.rotateLeft(a[1], 1); - a[1] = Long.rotateLeft(a[6], 44); - a[6] = Long.rotateLeft(a[9], 20); - a[9] = Long.rotateLeft(a[22], 61); - a[22] = Long.rotateLeft(a[14], 39); - a[14] = Long.rotateLeft(a[20], 18); - a[20] = Long.rotateLeft(a[2], 62); - a[2] = Long.rotateLeft(a[12], 43); - a[12] = Long.rotateLeft(a[13], 25); - a[13] = Long.rotateLeft(a[19], 8); - a[19] = Long.rotateLeft(a[23], 56); - a[23] = Long.rotateLeft(a[15], 41); - a[15] = Long.rotateLeft(a[4], 27); - a[4] = Long.rotateLeft(a[24], 14); - a[24] = Long.rotateLeft(a[21], 2); - a[21] = Long.rotateLeft(a[8], 55); - a[8] = Long.rotateLeft(a[16], 45); - a[16] = Long.rotateLeft(a[5], 36); - a[5] = Long.rotateLeft(a[3], 28); - a[3] = Long.rotateLeft(a[18], 21); - a[18] = Long.rotateLeft(a[17], 15); - a[17] = Long.rotateLeft(a[11], 10); - a[11] = Long.rotateLeft(a[7], 6); - a[7] = tmp; - return a; - } - - /** - * Step mapping Chi as defined in section 3.2.4. - */ - private static long[] smChi(long[] a) { - for (int y = 0; y < a.length; y+=DM) { - long ay0 = a[y]; - long ay1 = a[y+1]; - long ay2 = a[y+2]; - long ay3 = a[y+3]; - long ay4 = a[y+4]; - a[y] = ay0 ^ ((~ay1) & ay2); - a[y+1] = ay1 ^ ((~ay2) & ay3); - a[y+2] = ay2 ^ ((~ay3) & ay4); - a[y+3] = ay3 ^ ((~ay4) & ay0); - a[y+4] = ay4 ^ ((~ay0) & ay1); - } - return a; - } - - /** - * Step mapping Iota as defined in section 3.2.5. - */ - private static long[] smIota(long[] a, int rndIndex) { - a[0] ^= RC_CONSTANTS[rndIndex]; - return a; - } - /** * The function Keccak as defined in section 5.2 with * rate r = 1600 and capacity c = (digest length x 2). @@ -258,10 +165,124 @@ abstract class SHA3 extends DigestBase { private void keccak() { // convert the 200-byte state into 25 lanes bytes2Lanes(state, lanes); + + long a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12; + long a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24; + // move data into local variables + a0 = lanes[0]; a1 = lanes[1]; a2 = lanes[2]; a3 = lanes[3]; a4 = lanes[4]; + a5 = lanes[5]; a6 = lanes[6]; a7 = lanes[7]; a8 = lanes[8]; a9 = lanes[9]; + a10 = lanes[10]; a11 = lanes[11]; a12 = lanes[12]; a13 = lanes[13]; a14 = lanes[14]; + a15 = lanes[15]; a16 = lanes[16]; a17 = lanes[17]; a18 = lanes[18]; a19 = lanes[19]; + a20 = lanes[20]; a21 = lanes[21]; a22 = lanes[22]; a23 = lanes[23]; a24 = lanes[24]; + // process the lanes through step mappings for (int ir = 0; ir < NR; ir++) { - smIota(smChi(smPiRho(smTheta(lanes))), ir); + // Step mapping Theta as defined in section 3.2.1. + long c0 = a0^a5^a10^a15^a20; + long c1 = a1^a6^a11^a16^a21; + long c2 = a2^a7^a12^a17^a22; + long c3 = a3^a8^a13^a18^a23; + long c4 = a4^a9^a14^a19^a24; + long d0 = c4 ^ Long.rotateLeft(c1, 1); + long d1 = c0 ^ Long.rotateLeft(c2, 1); + long d2 = c1 ^ Long.rotateLeft(c3, 1); + long d3 = c2 ^ Long.rotateLeft(c4, 1); + long d4 = c3 ^ Long.rotateLeft(c0, 1); + a0 ^= d0; a1 ^= d1; a2 ^= d2; a3 ^= d3; a4 ^= d4; + a5 ^= d0; a6 ^= d1; a7 ^= d2; a8 ^= d3; a9 ^= d4; + a10 ^= d0; a11 ^= d1; a12 ^= d2; a13 ^= d3; a14 ^= d4; + a15 ^= d0; a16 ^= d1; a17 ^= d2; a18 ^= d3; a19 ^= d4; + a20 ^= d0; a21 ^= d1; a22 ^= d2; a23 ^= d3; a24 ^= d4; + + /** + * Merged Step mapping Rho (section 3.2.2) and Pi (section 3.2.3). + * for performance. Optimization is achieved by precalculating + * shift constants for the following loop + * int xNext, yNext; + * for (int t = 0, x = 1, y = 0; t <= 23; t++, x = xNext, y = yNext) { + * int numberOfShift = ((t + 1)*(t + 2)/2) % 64; + * a[y][x] = Long.rotateLeft(a[y][x], numberOfShift); + * xNext = y; + * yNext = (2 * x + 3 * y) % DM; + * } + * and with inplace permutation. + */ + long ay = Long.rotateLeft(a10, 3); + a10 = Long.rotateLeft(a1, 1); + a1 = Long.rotateLeft(a6, 44); + a6 = Long.rotateLeft(a9, 20); + a9 = Long.rotateLeft(a22, 61); + a22 = Long.rotateLeft(a14, 39); + a14 = Long.rotateLeft(a20, 18); + a20 = Long.rotateLeft(a2, 62); + a2 = Long.rotateLeft(a12, 43); + a12 = Long.rotateLeft(a13, 25); + a13 = Long.rotateLeft(a19, 8); + a19 = Long.rotateLeft(a23, 56); + a23 = Long.rotateLeft(a15, 41); + a15 = Long.rotateLeft(a4, 27); + a4 = Long.rotateLeft(a24, 14); + a24 = Long.rotateLeft(a21, 2); + a21 = Long.rotateLeft(a8, 55); + a8 = Long.rotateLeft(a16, 45); + a16 = Long.rotateLeft(a5, 36); + a5 = Long.rotateLeft(a3, 28); + a3 = Long.rotateLeft(a18, 21); + a18 = Long.rotateLeft(a17, 15); + a17 = Long.rotateLeft(a11, 10); + a11 = Long.rotateLeft(a7, 6); + a7 = ay; + + // Step mapping Chi as defined in section 3.2.4. + long tmp0 = a0; + long tmp1 = a1; + long tmp2 = a2; + long tmp3 = a3; + long tmp4 = a4; + a0 = tmp0 ^ ((~tmp1) & tmp2); + a1 = tmp1 ^ ((~tmp2) & tmp3); + a2 = tmp2 ^ ((~tmp3) & tmp4); + a3 = tmp3 ^ ((~tmp4) & tmp0); + a4 = tmp4 ^ ((~tmp0) & tmp1); + + tmp0 = a5; tmp1 = a6; tmp2 = a7; tmp3 = a8; tmp4 = a9; + a5 = tmp0 ^ ((~tmp1) & tmp2); + a6 = tmp1 ^ ((~tmp2) & tmp3); + a7 = tmp2 ^ ((~tmp3) & tmp4); + a8 = tmp3 ^ ((~tmp4) & tmp0); + a9 = tmp4 ^ ((~tmp0) & tmp1); + + tmp0 = a10; tmp1 = a11; tmp2 = a12; tmp3 = a13; tmp4 = a14; + a10 = tmp0 ^ ((~tmp1) & tmp2); + a11 = tmp1 ^ ((~tmp2) & tmp3); + a12 = tmp2 ^ ((~tmp3) & tmp4); + a13 = tmp3 ^ ((~tmp4) & tmp0); + a14 = tmp4 ^ ((~tmp0) & tmp1); + + tmp0 = a15; tmp1 = a16; tmp2 = a17; tmp3 = a18; tmp4 = a19; + a15 = tmp0 ^ ((~tmp1) & tmp2); + a16 = tmp1 ^ ((~tmp2) & tmp3); + a17 = tmp2 ^ ((~tmp3) & tmp4); + a18 = tmp3 ^ ((~tmp4) & tmp0); + a19 = tmp4 ^ ((~tmp0) & tmp1); + + tmp0 = a20; tmp1 = a21; tmp2 = a22; tmp3 = a23; tmp4 = a24; + a20 = tmp0 ^ ((~tmp1) & tmp2); + a21 = tmp1 ^ ((~tmp2) & tmp3); + a22 = tmp2 ^ ((~tmp3) & tmp4); + a23 = tmp3 ^ ((~tmp4) & tmp0); + a24 = tmp4 ^ ((~tmp0) & tmp1); + + // Step mapping Iota as defined in section 3.2.5. + a0 ^= RC_CONSTANTS[ir]; } + + lanes[0] = a0; lanes[1] = a1; lanes[2] = a2; lanes[3] = a3; lanes[4] = a4; + lanes[5] = a5; lanes[6] = a6; lanes[7] = a7; lanes[8] = a8; lanes[9] = a9; + lanes[10] = a10; lanes[11] = a11; lanes[12] = a12; lanes[13] = a13; lanes[14] = a14; + lanes[15] = a15; lanes[16] = a16; lanes[17] = a17; lanes[18] = a18; lanes[19] = a19; + lanes[20] = a20; lanes[21] = a21; lanes[22] = a22; lanes[23] = a23; lanes[24] = a24; + // convert the resulting 25 lanes back into 200-byte state lanes2Bytes(lanes, state); } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/Builder.java b/src/java.base/share/classes/sun/security/provider/certpath/Builder.java index 186d1269de315888ab83563c7b20f2987e39a983..b5cf0c5e44287e00fb94405344c61d782f24c05e 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/Builder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/Builder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ package sun.security.provider.certpath; import java.io.IOException; -import java.security.AccessController; import java.security.GeneralSecurityException; import java.security.cert.*; import java.util.*; @@ -337,7 +336,7 @@ public abstract class Builder { if (debug != null) { debug.println("Builder.targetDistance() merged constraints: " - + String.valueOf(constraints)); + + constraints); } /* reduce permitted by excluded */ GeneralSubtrees permitted = diff --git a/src/java.base/share/classes/sun/security/provider/certpath/ConstraintsChecker.java b/src/java.base/share/classes/sun/security/provider/certpath/ConstraintsChecker.java index 28fb322ddc4d8385089a65730427cf84cc928ddd..00d67de5a079d5e18f7cfe2b7165678bdf2101fb 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/ConstraintsChecker.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/ConstraintsChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -185,14 +185,14 @@ class ConstraintsChecker extends PKIXCertPathChecker { if (debug != null) { debug.println("prevNC = " + prevNC + - ", newNC = " + String.valueOf(newConstraints)); + ", newNC = " + newConstraints); } // if there are no previous name constraints, we just return the // new name constraints. if (prevNC == null) { if (debug != null) { - debug.println("mergedNC = " + String.valueOf(newConstraints)); + debug.println("mergedNC = " + newConstraints); } if (newConstraints == null) { return newConstraints; diff --git a/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java index 6122fdaa97077ae8f1266f882cd81ebd99dc495e..19dd5dd8d751fe8fc6fd123ae65c99f6517d2a27 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,6 @@ import java.security.cert.CertPathValidatorException; import java.security.cert.PKIXReason; import java.security.cert.CertStore; import java.security.cert.CertStoreException; -import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXCertPathChecker; import java.security.cert.TrustAnchor; import java.security.cert.X509Certificate; @@ -598,8 +597,8 @@ class ForwardBuilder extends Builder { X500Name tAo1 = tSubjectName.commonAncestor(cIssuer1Name); X500Name tAo2 = tSubjectName.commonAncestor(cIssuer2Name); if (debug != null) { - debug.println(METHOD_NME +" tAo1: " + String.valueOf(tAo1)); - debug.println(METHOD_NME +" tAo2: " + String.valueOf(tAo2)); + debug.println(METHOD_NME +" tAo1: " + tAo1); + debug.println(METHOD_NME +" tAo2: " + tAo2); } if (tAo1 != null || tAo2 != null) { if (tAo1 != null && tAo2 != null) { diff --git a/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java b/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java index 2dc9e208e924f212b4b9d6a26fbac752e599967d..5cbd0d7f404d83cca7d61faca68357cc1a56b64a 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,9 +117,8 @@ class ForwardState implements State { sb.append("State ["); sb.append("\n issuerDN of last cert: ").append(issuerDN); sb.append("\n traversedCACerts: ").append(traversedCACerts); - sb.append("\n init: ").append(String.valueOf(init)); - sb.append("\n keyParamsNeeded: ").append - (String.valueOf(keyParamsNeededFlag)); + sb.append("\n init: ").append(init); + sb.append("\n keyParamsNeeded: ").append(keyParamsNeededFlag); sb.append("\n subjectNamesTraversed: \n").append (subjectNamesTraversed); sb.append("]\n"); diff --git a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java index fef496ed50c88360e3ef9e319c95577178ccee66..5a1584b0a9ea1244820d800597329c995cf5663c 100644 --- a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java +++ b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,8 +102,13 @@ public final class PSSParameters extends AlgorithmParametersSpi { if (!val.getOID().equals(AlgorithmId.MGF1_oid)) { throw new IOException("Only MGF1 mgf is supported"); } + + byte[] encodedParams = val.getEncodedParams(); + if (encodedParams == null) { + throw new IOException("Missing MGF1 parameters"); + } AlgorithmId params = AlgorithmId.parse( - new DerValue(val.getEncodedParams())); + new DerValue(encodedParams)); String mgfDigestName = params.getName(); switch (mgfDigestName) { case "SHA-1": @@ -180,7 +185,7 @@ public final class PSSParameters extends AlgorithmParametersSpi { protected T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (PSSParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(PSSParameterSpec.class)) { return paramSpec.cast(spec); } else { throw new InvalidParameterSpecException diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java b/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java index d523e0b8be125f11669734e9ed852d0069d3be9a..15c143127fb24bb8c150596ea7e714b467170c3f 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java +++ b/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java @@ -255,7 +255,6 @@ public class RSAPSSSignature extends SignatureSpi { * internal signature parameters. */ private void isValid(RSAKey rsaKey) throws InvalidKeyException { - AlgorithmParameterSpec keyParams = rsaKey.getParams(); // validate key parameters if (!isCompatible(rsaKey.getParams(), this.sigParams)) { throw new InvalidKeyException diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPadding.java b/src/java.base/share/classes/sun/security/rsa/RSAPadding.java index c54dbdb8d43847fa1afab10b7d95c53b6c6811fc..3fe86cfea09840c503766f5dad2f74d6f89f8bf6 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSAPadding.java +++ b/src/java.base/share/classes/sun/security/rsa/RSAPadding.java @@ -270,7 +270,7 @@ public final class RSAPadding { */ public byte[] unpad(byte[] padded) throws BadPaddingException { if (padded.length != paddedSize) { - throw new BadPaddingException("Decryption error." + + throw new BadPaddingException("Decryption error. " + "The padded array length (" + padded.length + ") is not the specified padded size (" + paddedSize + ")"); } diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java b/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java index fbc9fda05faf23ca9594ec51310309ba00bb6a32..8ca5135fe85be196d9b85cb18af3946911b6e1ac 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java +++ b/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java @@ -141,7 +141,7 @@ public final class RSAPrivateCrtKeyImpl BigInteger n, BigInteger e, BigInteger d, BigInteger p, BigInteger q, BigInteger pe, BigInteger qe, BigInteger coeff) throws InvalidKeyException { - RSAPrivateKey key; + if ((e.signum() == 0) || (p.signum() == 0) || (q.signum() == 0) || (pe.signum() == 0) || (qe.signum() == 0) || (coeff.signum() == 0)) { diff --git a/src/java.base/share/classes/sun/security/ssl/BaseSSLSocketImpl.java b/src/java.base/share/classes/sun/security/ssl/BaseSSLSocketImpl.java index ba58741d759279b642c044745d36baafe29a1dd9..8923dee25c98a01a6c6a17d6bc8224f69a3b6169 100644 --- a/src/java.base/share/classes/sun/security/ssl/BaseSSLSocketImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/BaseSSLSocketImpl.java @@ -270,7 +270,7 @@ abstract class BaseSSLSocketImpl extends SSLSocket { * the penalty of prematurly killing SSL sessions. */ @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected final void finalize() throws Throwable { try { close(); diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateAuthoritiesExtension.java b/src/java.base/share/classes/sun/security/ssl/CertificateAuthoritiesExtension.java index 760daf4b3a15259741bd9bb50d8ad85771c97905..6315c7fdd9f985b0be9f606305d55f405997a70c 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateAuthoritiesExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateAuthoritiesExtension.java @@ -211,7 +211,7 @@ final class CertificateAuthoritiesExtension { if (encodedCAs.isEmpty()) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.warning( - "The number of CAs exceeds the maximum size" + + "The number of CAs exceeds the maximum size " + "of the certificate_authorities extension"); } diff --git a/src/java.base/share/classes/sun/security/ssl/ClientHello.java b/src/java.base/share/classes/sun/security/ssl/ClientHello.java index 1197802842d056bfcd971fe75ba11ac46a3c67c6..b75491def4cf775ad66123ee310a0e98e0025a77 100644 --- a/src/java.base/share/classes/sun/security/ssl/ClientHello.java +++ b/src/java.base/share/classes/sun/security/ssl/ClientHello.java @@ -568,15 +568,15 @@ final class ClientHello { "No new session is allowed and " + "no existing session can be resumed"); } - - if (chc.maximumActiveProtocol.useTLS13PlusSpec() && - SSLConfiguration.useCompatibilityMode) { - // In compatibility mode, the TLS 1.3 legacy_session_id - // field MUST be non-empty, so a client not offering a - // pre-TLS 1.3 session MUST generate a new 32-byte value. - sessionId = + } + if (sessionId.length() == 0 && + chc.maximumActiveProtocol.useTLS13PlusSpec() && + SSLConfiguration.useCompatibilityMode) { + // In compatibility mode, the TLS 1.3 legacy_session_id + // field MUST be non-empty, so a client not offering a + // pre-TLS 1.3 session MUST generate a new 32-byte value. + sessionId = new SessionId(true, chc.sslContext.getSecureRandom()); - } } ProtocolVersion minimumVersion = ProtocolVersion.NONE; diff --git a/src/java.base/share/classes/sun/security/ssl/DHServerKeyExchange.java b/src/java.base/share/classes/sun/security/ssl/DHServerKeyExchange.java index af64383457a8b8d8b15e48d81cefeca5498ccdc9..38e97073eb1fb8abd0bc1dcfc308e926ab20b652 100644 --- a/src/java.base/share/classes/sun/security/ssl/DHServerKeyExchange.java +++ b/src/java.base/share/classes/sun/security/ssl/DHServerKeyExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -444,7 +444,6 @@ final class DHServerKeyExchange { */ private void updateSignature(Signature sig, byte[] clntNonce, byte[] svrNonce) throws SignatureException { - int tmp; sig.update(clntNonce); sig.update(svrNonce); diff --git a/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java b/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java index 04ebefa6364403cd31d5b5f332b86ce9f91f31d5..d267c2e6b467cd30109262928cceff5146c03ab9 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java @@ -97,7 +97,7 @@ final class SSLConfiguration implements Cloneable { static final boolean allowLegacyMasterSecret = Utilities.getBooleanProperty("jdk.tls.allowLegacyMasterSecret", true); - // Allow full handshake without Extended Master Secret extension. + // Use TLS1.3 middlebox compatibility mode. static final boolean useCompatibilityMode = Utilities.getBooleanProperty( "jdk.tls.client.useCompatibilityMode", true); diff --git a/src/java.base/share/classes/sun/security/ssl/SSLEngineInputRecord.java b/src/java.base/share/classes/sun/security/ssl/SSLEngineInputRecord.java index 31abe94e9a1122a9ae71a53e6da9aa7960e28d85..938768aaf76bb26fd53b9342e9c5f5497b87bcb4 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLEngineInputRecord.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLEngineInputRecord.java @@ -358,7 +358,6 @@ final class SSLEngineInputRecord extends InputRecord implements SSLRecord { // The packet should be a complete record. // int srcPos = packet.position(); - int srcLim = packet.limit(); byte firstByte = packet.get(srcPos); byte thirdByte = packet.get(srcPos + 2); diff --git a/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java b/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java index 94ff8801fab184d207cc50890a28171281ae1c0f..3cf357254aa7a5a30b4f009eaeb2f664d9ae02bc 100644 --- a/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,7 @@ final class SupportedGroupsExtension { @Override public String toString() { MessageFormat messageFormat = new MessageFormat( - "\"versions\": '['{0}']'", Locale.ENGLISH); + "\"named groups\": '['{0}']'", Locale.ENGLISH); if (namedGroupsIds == null || namedGroupsIds.length == 0) { Object[] messageFields = { diff --git a/src/java.base/share/classes/sun/security/ssl/Utilities.java b/src/java.base/share/classes/sun/security/ssl/Utilities.java index 19fe784e0cae05d207030dd46d98c6729385d455..8317d9ae3cbc1baa4badc931ab37c3e3ef64e8df 100644 --- a/src/java.base/share/classes/sun/security/ssl/Utilities.java +++ b/src/java.base/share/classes/sun/security/ssl/Utilities.java @@ -101,14 +101,19 @@ final class Utilities { * not look like a FQDN */ private static SNIHostName rawToSNIHostName(String hostname) { - SNIHostName sniHostName = null; + // Is it a Fully-Qualified Domain Names (FQDN) ending with a dot? + if (hostname != null && hostname.endsWith(".")) { + // Remove the ending dot, which is not allowed in SNIHostName. + hostname = hostname.substring(0, hostname.length() - 1); + } + if (hostname != null && hostname.indexOf('.') > 0 && !hostname.endsWith(".") && !IPAddressUtil.isIPv4LiteralAddress(hostname) && !IPAddressUtil.isIPv6LiteralAddress(hostname)) { try { - sniHostName = new SNIHostName(hostname); + return new SNIHostName(hostname); } catch (IllegalArgumentException iae) { // don't bother to handle illegal host_name if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { @@ -118,7 +123,7 @@ final class Utilities { } } - return sniHostName; + return null; } /** diff --git a/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java b/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java index c5bc20521255066acb7592d37b2e8dc6d645e26a..120f6b9938ce4627208ad25e333b77fc2016e897 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java @@ -382,15 +382,13 @@ final class X509KeyManagerImpl extends X509ExtendedKeyManager issuerSet, false, checkType, constraints, requestedServerNames, idAlgorithm); if (results != null) { - // the results will either be a single perfect match - // or 1 or more imperfect matches - // if it's a perfect match, return immediately - EntryStatus status = results.get(0); - if (status.checkResult == CheckResult.OK) { - if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) { - SSLLogger.fine("KeyMgr: choosing key: " + status); + for (EntryStatus status : results) { + if (status.checkResult == CheckResult.OK) { + if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) { + SSLLogger.fine("KeyMgr: choosing key: " + status); + } + return makeAlias(status); } - return makeAlias(status); } if (allResults == null) { allResults = new ArrayList(); diff --git a/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java b/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java index 63651db53c36bbb7df7adf4b7f83c9daffc1a6b1..5b18641b3adc49477357952f348c19b54c93b0cb 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java @@ -404,6 +404,12 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager boolean identifiable = false; String peerHost = session.getPeerHost(); + // Is it a Fully-Qualified Domain Names (FQDN) ending with a dot? + if (peerHost != null && peerHost.endsWith(".")) { + // Remove the ending dot, which is not allowed in SNIHostName. + peerHost = peerHost.substring(0, peerHost.length() - 1); + } + if (!checkClientTrusted) { List sniNames = getRequestedServerNames(session); String sniHostName = getHostNameInSNI(sniNames); diff --git a/src/java.base/share/classes/sun/security/timestamp/HttpTimestamper.java b/src/java.base/share/classes/sun/security/timestamp/HttpTimestamper.java index cba296c6b97e64e8bfc8b2e9cbcdd818615c0909..03070fab053b7c0b3f574992dfbb5b8fbb52f9b0 100644 --- a/src/java.base/share/classes/sun/security/timestamp/HttpTimestamper.java +++ b/src/java.base/share/classes/sun/security/timestamp/HttpTimestamper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.URI; -import java.net.URL; import java.net.HttpURLConnection; import java.util.*; @@ -112,9 +111,7 @@ public class HttpTimestamper implements Timestamper { connection.connect(); // No HTTP authentication is performed // Send the request - DataOutputStream output = null; - try { - output = new DataOutputStream(connection.getOutputStream()); + try (var output = new DataOutputStream(connection.getOutputStream())) { byte[] request = tsQuery.encode(); output.write(request, 0, request.length); output.flush(); @@ -122,17 +119,11 @@ public class HttpTimestamper implements Timestamper { debug.println("sent timestamp query (length=" + request.length + ")"); } - } finally { - if (output != null) { - output.close(); - } } // Receive the reply - BufferedInputStream input = null; byte[] replyBuffer = null; - try { - input = new BufferedInputStream(connection.getInputStream()); + try (var input = new BufferedInputStream(connection.getInputStream())) { if (debug != null) { String header = connection.getHeaderField(0); debug.println(header); @@ -157,10 +148,6 @@ public class HttpTimestamper implements Timestamper { debug.println("received timestamp response (length=" + replyBuffer.length + ")"); } - } finally { - if (input != null) { - input.close(); - } } return new TSResponse(replyBuffer); } diff --git a/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java b/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java index 6c7cc402bf71da645597a3e1e3165f4a6b1eb34f..6095bb914721b435fcdc9cde46299c0fc7e5fd65 100644 --- a/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java +++ b/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -225,7 +225,9 @@ public class KeyStoreUtil { List result = new ArrayList<>(); Properties p = new Properties(); - p.load(new FileInputStream(file)); + try (FileInputStream is = new FileInputStream(file)) { + p.load(is); + } String s = p.getProperty(tool + ".all"); if (s != null) { diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 74f0bd5c25507ee13fb1a0bb5d63221ddb6adeaa..de13f75aea918cbbc97a04a5371af04a8c3de710 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,10 +31,14 @@ import java.nio.file.Path; import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.CertStoreException; import java.security.cert.CRL; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateParsingException; +import java.security.cert.TrustAnchor; import java.security.cert.URICertStoreParameters; @@ -43,6 +47,8 @@ import java.security.interfaces.EdECKey; import java.security.spec.ECParameterSpec; import java.text.Collator; import java.text.MessageFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.*; import java.util.function.BiFunction; import java.util.jar.JarEntry; @@ -60,6 +66,7 @@ import javax.security.auth.x500.X500Principal; import java.util.Base64; import sun.security.pkcs12.PKCS12KeyStore; +import sun.security.provider.certpath.CertPathConstraintsParameters; import sun.security.util.ECKeySizeParameterSpec; import sun.security.util.KeyUtil; import sun.security.util.NamedCurve; @@ -83,6 +90,7 @@ import sun.security.tools.KeyStoreUtil; import sun.security.tools.PathList; import sun.security.util.DerValue; import sun.security.util.Pem; +import sun.security.validator.Validator; import sun.security.x509.*; import static java.security.KeyStore.*; @@ -178,6 +186,8 @@ public final class Main { // Warnings on weak algorithms etc private List weakWarnings = new ArrayList<>(); + private Set trustedCerts = new HashSet<>(); + private static final DisabledAlgorithmConstraints DISABLED_CHECK = new DisabledAlgorithmConstraints( DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); @@ -1118,6 +1128,7 @@ public final class Main { } } + KeyStore cakstore = buildTrustedCerts(); // -trustcacerts can be specified on -importcert, -printcert or -printcrl. // Reset it so that warnings on CA cert will remain for other command. if (command != IMPORTCERT && command != PRINTCERT @@ -1126,7 +1137,13 @@ public final class Main { } if (trustcacerts) { - caks = KeyStoreUtil.getCacertsKeyStore(); + if (cakstore != null) { + caks = cakstore; + } else { + // try to load cacerts again, and let exception propagate + // if it cannot be loaded + caks = KeyStoreUtil.getCacertsKeyStore(); + } } // Perform the specified command @@ -1485,7 +1502,9 @@ public final class Main { byte[] rawReq = Pem.decode(new String(sb)); PKCS10 req = new PKCS10(rawReq); - checkWeak(rb.getString("the.certificate.request"), req); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + req.getSubjectPublicKeyInfo(), null, null, null); + checkWeakConstraint(rb.getString("the.certificate.request"), req, cpcp); info.set(X509CertInfo.KEY, new CertificateX509Key(req.getSubjectPublicKeyInfo())); info.set(X509CertInfo.SUBJECT, @@ -1542,8 +1561,11 @@ public final class Main { } } - checkWeak(rb.getString("the.issuer"), keyStore.getCertificateChain(alias)); - checkWeak(rb.getString("the.generated.certificate"), cert); + checkWeakConstraint(rb.getString("the.issuer"), + keyStore.getCertificateChain(alias)); + cpcp = buildCertPathConstraint(cert, null); + checkWeakConstraint(rb.getString("the.generated.certificate"), + cert, cpcp); } private void doGenCRL(PrintStream out) @@ -1592,7 +1614,10 @@ public final class Main { } else { out.write(crl.getEncodedInternal()); } - checkWeak(rb.getString("the.generated.crl"), crl, privateKey); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + privateKey, null, null, null); + checkWeakConstraint(rb.getString("the.generated.crl"), crl, privateKey, + cpcp); } /** @@ -1638,7 +1663,10 @@ public final class Main { request.encodeAndSign(subject, privKey, sigAlgName); request.print(out); - checkWeak(rb.getString("the.generated.certificate.request"), request); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + request.getSubjectPublicKeyInfo(), null, null, null); + checkWeakConstraint(rb.getString("the.generated.certificate.request"), + request, cpcp); } /** @@ -1683,7 +1711,9 @@ public final class Main { throw new Exception(form.format(source)); } dumpCert(cert, out); - checkWeak(rb.getString("the.certificate"), cert); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); + checkWeakConstraint(rb.getString("the.certificate"), cert, cpcp); } /** @@ -2021,7 +2051,8 @@ public final class Main { } else { finalChain = new Certificate[] { newCert }; } - checkWeak(rb.getString("the.generated.certificate"), finalChain); + checkWeakConstraint(rb.getString("the.generated.certificate"), + finalChain); keyStore.setKeyEntry(alias, privKey, keyPass, finalChain); } @@ -2114,6 +2145,7 @@ public final class Main { private void doPrintEntry(String label, String alias, PrintStream out) throws Exception { + CertPathConstraintsParameters cpcp; if (keyStore.containsAlias(alias) == false) { MessageFormat form = new MessageFormat (rb.getString("Alias.alias.does.not.exist")); @@ -2170,6 +2202,10 @@ public final class Main { if (verbose || rfc || debug) { out.println(rb.getString ("Certificate.chain.length.") + chain.length); + + X509Certificate[] xcerts = convertCerts(chain); + List certs = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(certs); for (int i = 0; i < chain.length; i ++) { MessageFormat form = new MessageFormat (rb.getString("Certificate.i.1.")); @@ -2182,14 +2218,26 @@ public final class Main { } else { dumpCert(chain[i], out); } - checkWeak(label, chain[i]); + + if (i == 0 && + ((X509Certificate)chain[0]). + getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint((X509Certificate) chain[i], anchor); + } else { + cpcp = new CertPathConstraintsParameters( + (X509Certificate)chain[i], null, anchor, + null); + } + + checkWeakConstraint(label, chain[i], cpcp); } } else { // Print the digest of the user cert only out.println (rb.getString("Certificate.fingerprint.SHA.256.") + getCertFingerPrint("SHA-256", chain[0])); - checkWeak(label, chain); + checkWeakConstraint(label, chain); } } else { out.println(rb.getString @@ -2215,7 +2263,8 @@ public final class Main { out.println(rb.getString("Certificate.fingerprint.SHA.256.") + getCertFingerPrint("SHA-256", cert)); } - checkWeak(label, cert); + cpcp = buildCertPathConstraint((X509Certificate)cert, null); + checkWeakConstraint(label, cert, cpcp); } else { out.println(rb.getString("Unknown.Entry.Type")); } @@ -2442,7 +2491,9 @@ public final class Main { try { Certificate c = srckeystore.getCertificate(alias); if (c != null) { - checkWeak("<" + newAlias + ">", c); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)c, null); + checkWeakConstraint("<" + newAlias + ">", c, cpcp); } keyStore.setEntry(newAlias, entry, pp); // Place the check so that only successful imports are blocked. @@ -2639,11 +2690,14 @@ public final class Main { issuer = verifyCRL(caks, crl); if (issuer != null) { signer = caks.getCertificate(issuer); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, + null); out.printf(rb.getString( "verified.by.s.in.s.weak"), issuer, "cacerts", - withWeak(signer.getPublicKey())); + withWeakConstraint(signer.getPublicKey(), cpcp)); out.println(); } } @@ -2651,11 +2705,14 @@ public final class Main { issuer = verifyCRL(keyStore, crl); if (issuer != null) { signer = keyStore.getCertificate(issuer); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, + null); out.printf(rb.getString( "verified.by.s.in.s.weak"), issuer, "keystore", - withWeak(signer.getPublicKey())); + withWeakConstraint(signer.getPublicKey(), cpcp)); out.println(); } } @@ -2672,7 +2729,15 @@ public final class Main { out.println(rb.getString ("STARNN")); } - checkWeak(rb.getString("the.crl"), crl, signer == null ? null : signer.getPublicKey()); + + if (signer != null) { + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, null); + checkWeakConstraint(rb.getString("the.crl"), crl, + signer.getPublicKey(), cpcp); + } else { + checkWeak(rb.getString("the.crl"), crl, null); + } } } @@ -2718,10 +2783,12 @@ public final class Main { PKCS10 req = new PKCS10(Pem.decode(new String(sb))); PublicKey pkey = req.getSubjectPublicKeyInfo(); + CertPathConstraintsParameters cpcp = + new CertPathConstraintsParameters(pkey, null, null, null); out.printf(rb.getString("PKCS.10.with.weak"), req.getSubjectName(), pkey.getFormat(), - withWeak(pkey), + withWeakConstraint(pkey, cpcp), withWeak(req.getSigAlg())); for (PKCS10Attribute attr: req.getAttributes().getAttributes()) { ObjectIdentifier oid = attr.getAttributeId(); @@ -2745,7 +2812,12 @@ public final class Main { if (debug) { out.println(req); // Just to see more, say, public key length... } - checkWeak(rb.getString("the.certificate.request"), req); + + CertPathConstraintsParameters cpcp1 = + new CertPathConstraintsParameters( + req.getSubjectPublicKeyInfo(), null, null, null); + checkWeakConstraint(rb.getString("the.certificate.request"), req, + cpcp1); } /** @@ -2765,6 +2837,9 @@ public final class Main { throw new Exception(rb.getString("Empty.input")); } Certificate[] certs = c.toArray(new Certificate[c.size()]); + X509Certificate[] xcerts = convertCerts(certs); + List chain = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(chain); for (int i=0; i certs = signer.getSignerCertPath().getCertificates(); + @SuppressWarnings("unchecked") + List chain = + (List)certs; + TrustAnchor anchor = findTrustAnchor(chain); + CertPathConstraintsParameters cpcp; int cc = 0; for (Certificate cert: certs) { out.printf(rb.getString("Certificate.d."), ++cc); @@ -2913,16 +3003,27 @@ public final class Main { printX509Cert(x, out); } out.println(); - checkWeak(oneInManys(rb.getString( + if (cc == 0 && x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInManys(rb.getString( "the.certificate"), cc, certs.size(), pos, - ss.size()), x); + ss.size()), x, cpcp); } Timestamp ts = signer.getTimestamp(); if (ts != null) { out.println(rb.getString("Timestamp.")); out.println(); certs = ts.getSignerCertPath().getCertificates(); + @SuppressWarnings("unchecked") + List tschain = + (List)certs; + anchor = findTrustAnchor(tschain); cc = 0; for (Certificate cert: certs) { out.printf(rb.getString("Certificate.d."), ++cc); @@ -2935,10 +3036,18 @@ public final class Main { printX509Cert(x, out); } out.println(); - checkWeak(oneInManys(rb.getString( + if (cc == 0 && + x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInManys(rb.getString( "the.tsa.certificate"), cc, certs.size(), pos, - ss.size()), x); + ss.size()), x, cpcp); } } } @@ -2968,6 +3077,9 @@ public final class Main { } int i = 0; + @SuppressWarnings("unchecked") + List xcerts = (List)chain; + TrustAnchor anchor = findTrustAnchor(xcerts); for (Certificate cert : chain) { try { if (rfc) { @@ -2978,7 +3090,17 @@ public final class Main { printX509Cert((X509Certificate)cert, out); out.println(); } - checkWeak(oneInMany(rb.getString("the.certificate"), i++, chain.size()), cert); + X509Certificate x = (X509Certificate)cert; + CertPathConstraintsParameters cpcp; + if (i == 0 && x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInMany(rb.getString( + "the.certificate"), i++, chain.size()), x, cpcp); } catch (Exception e) { if (debug) { e.printStackTrace(); @@ -3202,8 +3324,11 @@ public final class Main { throw new Exception(rb.getString("Input.not.an.X.509.certificate")); } + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); + if (noprompt) { - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); keyStore.setCertificateEntry(alias, cert); return true; } @@ -3223,7 +3348,7 @@ public final class Main { ("Certificate.already.exists.in.keystore.under.alias.trustalias.")); Object[] source = {trustalias}; System.err.println(form.format(source)); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Do.you.still.want.to.add.it.no.")); @@ -3234,7 +3359,7 @@ public final class Main { ("Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias.")); Object[] source = {trustalias}; System.err.println(form.format(source)); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Do.you.still.want.to.add.it.to.your.own.keystore.no.")); @@ -3243,7 +3368,7 @@ public final class Main { // Print the cert and ask user if they really want to add // it to their keystore printX509Cert(cert, System.out); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Trust.this.certificate.no.")); @@ -3270,7 +3395,7 @@ public final class Main { // Print the cert and ask user if they really want to add it to // their keystore printX509Cert(cert, System.out); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Trust.this.certificate.no.")); @@ -3410,6 +3535,21 @@ public final class Main { return keyPass; } + private String withWeakConstraint(String alg, + CertPathConstraintsParameters cpcp) { + try { + DISABLED_CHECK.permits(alg, cpcp, false); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("with.disabled"), alg); + } + try { + LEGACY_CHECK.permits(alg, cpcp, false); + return alg; + } catch (CertPathValidatorException e) { + return String.format(rb.getString("with.weak"), alg); + } + } + private String withWeak(String alg) { if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) { if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) { @@ -3436,21 +3576,24 @@ public final class Main { return result; } - private String withWeak(Key key) { + private String withWeakConstraint(Key key, + CertPathConstraintsParameters cpcp) { int kLen = KeyUtil.getKeySize(key); String displayAlg = fullDisplayAlgName(key); - if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (kLen >= 0) { - return String.format(rb.getString("key.bit"), kLen, displayAlg); - } else { - return String.format(rb.getString("unknown.size.1"), displayAlg); - } + try { + DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg); + } + try { + LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), kLen, displayAlg); } else { - return String.format(rb.getString("key.bit.weak"), kLen, displayAlg); + return String.format(rb.getString("unknown.size.1"), displayAlg); } - } else { - return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("key.bit.weak"), kLen, displayAlg); } } @@ -3465,9 +3608,11 @@ public final class Main { (rb.getString(".PATTERN.printX509Cert.with.weak")); PublicKey pkey = cert.getPublicKey(); String sigName = cert.getSigAlgName(); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); // No need to warn about sigalg of a trust anchor if (!isTrustedCert(cert)) { - sigName = withWeak(sigName); + sigName = withWeakConstraint(sigName, cpcp); } Object[] source = {cert.getSubjectX500Principal().toString(), cert.getIssuerX500Principal().toString(), @@ -3477,7 +3622,7 @@ public final class Main { getCertFingerPrint("SHA-1", cert), getCertFingerPrint("SHA-256", cert), sigName, - withWeak(pkey), + withWeakConstraint(pkey, cpcp), cert.getVersion() }; out.println(form.format(source)); @@ -3801,7 +3946,7 @@ public final class Main { throws Exception { - checkWeak(rb.getString("reply"), replyCerts); + checkWeakConstraint(rb.getString("reply"), replyCerts); // order the certs in the reply (bottom-up). // we know that all certs in the reply are of type X.509, because @@ -3883,11 +4028,14 @@ public final class Main { replyCerts.length); tmpCerts[tmpCerts.length-1] = root.snd; replyCerts = tmpCerts; - checkWeak(String.format(fromKeyStore + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)root.snd, + null); + checkWeakConstraint(String.format(fromKeyStore ? rb.getString("alias.in.keystore") : rb.getString("alias.in.cacerts"), root.fst), - root.snd); + root.snd, cpcp); } } return replyCerts; @@ -3952,7 +4100,9 @@ public final class Main { (X509Certificate) certToVerify), chain, certs)) { for (Pair p : chain) { - checkWeak(p.fst, p.snd); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(p.snd, null); + checkWeakConstraint(p.fst, p.snd, cpcp); } Certificate[] newChain = new Certificate[chain.size()]; @@ -4161,18 +4311,18 @@ public final class Main { } if (date != null) { if (date.matches("\\d\\d\\d\\d\\/\\d\\d\\/\\d\\d")) { - c.set(Integer.valueOf(date.substring(0, 4)), - Integer.valueOf(date.substring(5, 7))-1, - Integer.valueOf(date.substring(8, 10))); + c.set(Integer.parseInt(date.substring(0, 4)), + Integer.parseInt(date.substring(5, 7))-1, + Integer.parseInt(date.substring(8, 10))); } else { throw ioe; } } if (time != null) { if (time.matches("\\d\\d:\\d\\d:\\d\\d")) { - c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(time.substring(0, 2))); - c.set(Calendar.MINUTE, Integer.valueOf(time.substring(3, 5))); - c.set(Calendar.SECOND, Integer.valueOf(time.substring(6, 8))); + c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time.substring(0, 2))); + c.set(Calendar.MINUTE, Integer.parseInt(time.substring(3, 5))); + c.set(Calendar.SECOND, Integer.parseInt(time.substring(6, 8))); c.set(Calendar.MILLISECOND, 0); } else { throw ioe; @@ -4748,6 +4898,78 @@ public final class Main { } } + private void checkWeakConstraint(String label, String sigAlg, Key key, + CertPathConstraintsParameters cpcp) throws Exception { + if (sigAlg != null) { + try { + DISABLED_CHECK.permits(sigAlg, cpcp, false); + try { + LEGACY_CHECK.permits(sigAlg, cpcp, false); + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.sigalg.weak"), label, sigAlg)); + } + } catch (CertPathValidatorException e) { + String eMessage = e.getMessage(); + if (eMessage.contains("denyAfter constraint check failed") && + e.getReason() == BasicReason.ALGORITHM_CONSTRAINED) { + String startSeparator = "Constraint date: "; + int startSepPos = eMessage.indexOf(startSeparator); + String endSeparator = "; params date"; + int endSepPos = eMessage.indexOf(endSeparator); + String denyAfterDate = null; + try { + denyAfterDate = eMessage.substring(startSepPos + startSeparator.length(), + endSepPos); + } catch (IndexOutOfBoundsException e1) { + throw new Exception(rb.getString( + "Unable.to.parse.denyAfter.string.in.exception.message")); + } + + SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy"); + Date dateObj = null; + try { + dateObj = formatter.parse(denyAfterDate); + } catch (ParseException e2) { + throw new Exception(rb.getString( + "Unable.to.parse.denyAfter.string.in.exception.message")); + } + formatter = new SimpleDateFormat("yyyy-MM-dd"); + denyAfterDate = formatter.format(dateObj); + + weakWarnings.add(String.format( + rb.getString("whose.sigalg.usagesignedjar"), label, sigAlg, + denyAfterDate)); + } else { + weakWarnings.add(String.format( + rb.getString("whose.sigalg.disabled"), label, sigAlg)); + } + if (debug) { + e.printStackTrace(); + } + } + } + + if (key != null) { + try { + DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true); + try { + LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true); + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.key.weak"), label, + String.format(rb.getString("key.bit"), + KeyUtil.getKeySize(key), fullDisplayAlgName(key)))); + } + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.key.disabled"), label, + String.format(rb.getString("key.bit"), + KeyUtil.getKeySize(key), fullDisplayAlgName(key)))); + } + } + } + private void checkWeak(String label, String sigAlg, Key key) { if (sigAlg != null) { if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, sigAlg, null)) { @@ -4774,8 +4996,11 @@ public final class Main { } } - private void checkWeak(String label, Certificate[] certs) - throws KeyStoreException { + private void checkWeakConstraint(String label, Certificate[] certs) + throws KeyStoreException, Exception { + X509Certificate[] xcerts = convertCerts(certs); + List chain = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(chain); for (int i = 0; i < certs.length; i++) { Certificate cert = certs[i]; if (cert instanceof X509Certificate) { @@ -4784,23 +5009,43 @@ public final class Main { if (certs.length > 1) { fullLabel = oneInMany(label, i, certs.length); } - checkWeak(fullLabel, xc); + + CertPathConstraintsParameters cpcp = null; + if (i == 0 && xc.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(xc, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + xc, null, anchor, null); + } + checkWeakConstraint(fullLabel, xc, cpcp); } } } - private void checkWeak(String label, Certificate cert) - throws KeyStoreException { + private void checkWeakConstraint(String label, Certificate cert, + CertPathConstraintsParameters cpcp) + throws KeyStoreException, Exception { if (cert instanceof X509Certificate) { X509Certificate xc = (X509Certificate)cert; // No need to check the sigalg of a trust anchor String sigAlg = isTrustedCert(cert) ? null : xc.getSigAlgName(); - checkWeak(label, sigAlg, xc.getPublicKey()); + checkWeakConstraint(label, sigAlg, xc.getPublicKey(), cpcp); } } - private void checkWeak(String label, PKCS10 p10) { - checkWeak(label, p10.getSigAlg(), p10.getSubjectPublicKeyInfo()); + private void checkWeakConstraint(String label, PKCS10 p10, + CertPathConstraintsParameters cpcp) throws Exception { + checkWeakConstraint(label, p10.getSigAlg(), + p10.getSubjectPublicKeyInfo(), cpcp); + } + + private void checkWeakConstraint(String label, CRL crl, Key key, + CertPathConstraintsParameters cpcp) throws Exception { + if (crl instanceof X509CRLImpl) { + X509CRLImpl impl = (X509CRLImpl)crl; + checkWeakConstraint(label, impl.getSigAlgName(), key, cpcp); + } } private void checkWeak(String label, CRL crl, Key key) { @@ -4810,6 +5055,76 @@ public final class Main { } } + private KeyStore buildTrustedCerts() { + KeyStore caks = null; + try { + caks = KeyStoreUtil.getCacertsKeyStore(); + if (caks != null) { + Enumeration aliases = caks.aliases(); + while (aliases.hasMoreElements()) { + String a = aliases.nextElement(); + try { + trustedCerts.add((X509Certificate)caks.getCertificate(a)); + } catch (Exception e2) { + // ignore, if the keystore has not been loaded/initialized properly + } + } + } + } catch (Exception e) { + // Ignore, if cacerts cannot be loaded + } + return caks; + } + + private TrustAnchor findTrustAnchor(List chain) { + if (chain.isEmpty()) { + return null; + } + + X509Certificate last = chain.get(chain.size() - 1); + Optional trusted = + trustedCerts.stream() + .filter(c -> c.getSubjectX500Principal().equals(last.getIssuerX500Principal())) + .findFirst(); + return trusted.isPresent() ? new TrustAnchor(trusted.get(), null) : null; + } + + private X509Certificate[] convertCerts(Certificate[] certs) { + X509Certificate[] xcerts = new X509Certificate[certs.length]; + + for (int i = 0; i < certs.length; i++) { + if (certs[i] instanceof X509Certificate) { + xcerts[i] = (X509Certificate) certs[i]; + } + } + return xcerts; + } + + private CertPathConstraintsParameters buildCertPathConstraint( + X509Certificate xcert, TrustAnchor anchor) throws Exception{ + List eku = xcert.getExtendedKeyUsage(); + if (eku == null) { + return new CertPathConstraintsParameters(xcert, null, + anchor, null); + } + + if (eku.contains(KnownOIDs.codeSigning.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_CODE_SIGNING, anchor, null); + } else if (eku.contains(KnownOIDs.clientAuth.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TLS_CLIENT, anchor, null); + } else if (eku.contains(KnownOIDs.serverAuth.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TLS_SERVER, anchor, null); + } else if (eku.contains(KnownOIDs.KP_TimeStamping.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TSA_SERVER, anchor, null); + } + return new CertPathConstraintsParameters(xcert, Validator.VAR_GENERIC, + anchor, null); + } + private void printWeakWarnings(boolean newLine) { if (!weakWarnings.isEmpty() && !nowarn) { System.err.println("\nWarning:"); diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Resources.java b/src/java.base/share/classes/sun/security/tools/keytool/Resources.java index df0147e529ded693a1a82999fa077aed65198d3f..f26b2a13bd8324ffc2eea394237b983a3cb6fa0e 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Resources.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Resources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -483,6 +483,8 @@ public class Resources extends java.util.ListResourceBundle { "Subject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignature algorithm: %4$s\n"}, {"verified.by.s.in.s.weak", "Verified by %1$s in %2$s with a %3$s"}, {"whose.sigalg.disabled", "%1$s uses the %2$s signature algorithm which is considered a security risk and is disabled."}, + {"whose.sigalg.usagesignedjar", "%1$s uses the %2$s signature algorithm which is considered a security risk and cannot be used to sign JARs after %3$s."}, + {"Unable.to.parse.denyAfter.string.in.exception.message", "Unable to parse denyAfter date string in exception message"}, {"whose.sigalg.weak", "%1$s uses the %2$s signature algorithm which is considered a security risk. This algorithm will be disabled in a future update."}, {"whose.key.disabled", "%1$s uses a %2$s which is considered a security risk and is disabled."}, {"whose.key.weak", "%1$s uses a %2$s which is considered a security risk. This key size will be disabled in a future update."}, diff --git a/src/java.base/share/classes/sun/security/util/ChannelBindingException.java b/src/java.base/share/classes/sun/security/util/ChannelBindingException.java new file mode 100644 index 0000000000000000000000000000000000000000..847cd0741a0d2a14171c82ec78fcf1590a0f1d00 --- /dev/null +++ b/src/java.base/share/classes/sun/security/util/ChannelBindingException.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.util; + +import java.security.GeneralSecurityException; + +/** + * Thrown by TlsChannelBinding if an error occurs + */ +public class ChannelBindingException extends GeneralSecurityException { + + @java.io.Serial + private static final long serialVersionUID = -5021387249782788460L; + + /** + * Constructs a ChannelBindingException with no detail message. A detail + * message is a String that describes this particular exception. + */ + public ChannelBindingException() { + super(); + } + + /** + * Constructs a ChannelBindingException with a detail message and + * specified cause. + */ + public ChannelBindingException(String msg, Exception e) { + super(msg, e); + } + + /** + * Constructs a ChannelBindingException with a detail message + */ + public ChannelBindingException(String msg) { + super(msg); + } +} diff --git a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java index 7be36c1a6cbf249728312adcb0274219c3408cee..8a2650ff580a8266c1f21d8dd2c1c8af752cb399 100644 --- a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java +++ b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java @@ -451,7 +451,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { for (Constraint constraint : list) { if (!constraint.permits(key)) { if (debug != null) { - debug.println("Constraints: failed key size" + + debug.println("Constraints: failed key size " + "constraint check " + KeyUtil.getKeySize(key)); } return false; diff --git a/src/java.base/share/classes/sun/security/util/GCMParameters.java b/src/java.base/share/classes/sun/security/util/GCMParameters.java index 02390777a039dd919a0d6ff7457247d8cdd589eb..d54965f975dfe7c46f82d21f125b81be5395eae6 100644 --- a/src/java.base/share/classes/sun/security/util/GCMParameters.java +++ b/src/java.base/share/classes/sun/security/util/GCMParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,7 @@ public final class GCMParameters extends AlgorithmParametersSpi { T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { - if (GCMParameterSpec.class.isAssignableFrom(paramSpec)) { + if (paramSpec.isAssignableFrom(GCMParameterSpec.class)) { return paramSpec.cast(new GCMParameterSpec(tLen * 8, iv)); } else { throw new InvalidParameterSpecException diff --git a/src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java b/src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java index 14a56e33f38d643098e89f8a74dc55207034526c..187922cc8f294722f77c032530ecdbb25a0446e1 100644 --- a/src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java +++ b/src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -192,7 +192,8 @@ public class ManifestEntryVerifier { * */ public CodeSigner[] verify(Hashtable verifiedSigners, - Hashtable sigFileSigners) + Hashtable sigFileSigners, + Map> signersToAlgs) throws JarException { if (skip) { @@ -207,38 +208,60 @@ public class ManifestEntryVerifier { return signers; } - JarConstraintsParameters params = - getParams(verifiedSigners, sigFileSigners); + CodeSigner[] entrySigners = sigFileSigners.get(name); + Map algsPermittedStatus = + algsPermittedStatusForSigners(signersToAlgs, entrySigners); + // Flag that indicates if only disabled algorithms are used and jar + // entry should be treated as unsigned. + boolean disabledAlgs = true; + JarConstraintsParameters params = null; for (int i=0; i < digests.size(); i++) { MessageDigest digest = digests.get(i); - if (params != null) { - try { - params.setExtendedExceptionMsg(JarFile.MANIFEST_NAME, - name + " entry"); - DisabledAlgorithmConstraints.jarConstraints() - .permits(digest.getAlgorithm(), params, false); - } catch (GeneralSecurityException e) { - if (debug != null) { - debug.println("Digest algorithm is restricted: " + e); + String digestAlg = digest.getAlgorithm(); + + // Check if this algorithm is permitted, skip if false. + if (algsPermittedStatus != null) { + Boolean permitted = algsPermittedStatus.get(digestAlg); + if (permitted == null) { + if (params == null) { + params = new JarConstraintsParameters(entrySigners); } - return null; + if (!checkConstraints(digestAlg, params)) { + algsPermittedStatus.put(digestAlg, Boolean.FALSE); + continue; + } else { + algsPermittedStatus.put(digestAlg, Boolean.TRUE); + } + } else if (!permitted) { + continue; } } + + // A non-disabled algorithm was used. + disabledAlgs = false; + byte [] manHash = manifestHashes.get(i); byte [] theHash = digest.digest(); if (debug != null) { debug.println("Manifest Entry: " + - name + " digest=" + digest.getAlgorithm()); + name + " digest=" + digestAlg); debug.println(" manifest " + HexFormat.of().formatHex(manHash)); debug.println(" computed " + HexFormat.of().formatHex(theHash)); debug.println(); } - if (!MessageDigest.isEqual(theHash, manHash)) - throw new SecurityException(digest.getAlgorithm()+ + if (!MessageDigest.isEqual(theHash, manHash)) { + throw new SecurityException(digestAlg + " digest error for "+name); + } + } + + // If there were only disabled algorithms used, return null and jar + // entry will be treated as unsigned. + if (disabledAlgs) { + return null; } // take it out of sigFileSigners and put it in verifiedSigners... @@ -249,40 +272,36 @@ public class ManifestEntryVerifier { return signers; } - /** - * Get constraints parameters for JAR. The constraints should be - * checked against all code signers. Returns the parameters, - * or null if the signers for this entry have already been checked - * or there are no signers for this entry. - */ - private JarConstraintsParameters getParams( - Map verifiedSigners, - Map sigFileSigners) { - - // verifiedSigners is usually preloaded with the Manifest's signers. - // If verifiedSigners contains the Manifest, then it will have all of - // the signers of the JAR. But if it doesn't then we need to fallback - // and check verifiedSigners to see if the signers of this entry have - // been checked already. - if (verifiedSigners.containsKey(manifestFileName)) { - if (verifiedSigners.size() > 1) { - // this means we already checked it previously - return null; - } else { - return new JarConstraintsParameters( - verifiedSigners.get(manifestFileName)); + // Gets the algorithms permitted status for the signers of this entry. + private static Map algsPermittedStatusForSigners( + Map> signersToAlgs, + CodeSigner[] signers) { + if (signers != null) { + Map algs = signersToAlgs.get(signers); + // create new HashMap if absent + if (algs == null) { + algs = new HashMap<>(); + signersToAlgs.put(signers, algs); } - } else { + return algs; + } + return null; + } + + // Checks the algorithm constraints against the signers of this entry. + private boolean checkConstraints(String algorithm, + JarConstraintsParameters params) { + try { + params.setExtendedExceptionMsg(JarFile.MANIFEST_NAME, + name + " entry"); + DisabledAlgorithmConstraints.jarConstraints() + .permits(algorithm, params, false); + return true; + } catch (GeneralSecurityException e) { if (debug != null) { - debug.println(manifestFileName + " not present in verifiedSigners"); - } - CodeSigner[] signers = sigFileSigners.get(name); - if (signers == null || verifiedSigners.containsValue(signers)) { - return null; - } else { - return new JarConstraintsParameters(signers); + debug.println("Digest algorithm is restricted: " + e); } + return false; } } } - diff --git a/src/java.base/share/classes/sun/security/util/PolicyUtil.java b/src/java.base/share/classes/sun/security/util/PolicyUtil.java index 3bea048f539004969afe5512b8918abeed42ef4c..b0ce1c496027e26c598640aa13b5a17c8c9e0025 100644 --- a/src/java.base/share/classes/sun/security/util/PolicyUtil.java +++ b/src/java.base/share/classes/sun/security/util/PolicyUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,14 +124,8 @@ public class PolicyUtil { debug.println("reading password"+passURL); } - InputStream in = null; - try { - in = passURL.openStream(); + try (InputStream in = passURL.openStream()) { keyStorePassword = Password.readPassword(in); - } finally { - if (in != null) { - in.close(); - } } } @@ -159,13 +153,9 @@ public class PolicyUtil { debug.println("reading keystore"+keyStoreUrl); } - InputStream inStream = null; - try { - inStream = - new BufferedInputStream(getInputStream(keyStoreUrl)); + try (InputStream inStream = + new BufferedInputStream(getInputStream(keyStoreUrl))) { ks.load(inStream, keyStorePassword); - } finally { - inStream.close(); } return ks; } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/TlsChannelBinding.java b/src/java.base/share/classes/sun/security/util/TlsChannelBinding.java similarity index 82% rename from src/java.naming/share/classes/com/sun/jndi/ldap/sasl/TlsChannelBinding.java rename to src/java.base/share/classes/sun/security/util/TlsChannelBinding.java index 922fa18028ce345464d02be8e1f2d239a6925655..8f7ac50bb5e761087bf609b2010aa5d5b5c1b3cd 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/TlsChannelBinding.java +++ b/src/java.base/share/classes/sun/security/util/TlsChannelBinding.java @@ -22,10 +22,9 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.sun.jndi.ldap.sasl; -import javax.naming.NamingException; -import javax.security.sasl.SaslException; +package sun.security.util; + import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; @@ -47,14 +46,6 @@ import java.util.Hashtable; public class TlsChannelBinding { - // TLS channel binding type property - public static final String CHANNEL_BINDING_TYPE = - "com.sun.jndi.ldap.tls.cbtype"; - - // internal TLS channel binding property - public static final String CHANNEL_BINDING = - "jdk.internal.sasl.tlschannelbinding"; - public enum TlsChannelBindingType { /** @@ -80,19 +71,18 @@ public class TlsChannelBinding { } /** - * Parse value of "com.sun.jndi.ldap.tls.cbtype" property + * Parse given value to see if it is a recognized and supported channel binding type + * * @param cbType - * @return TLS Channel Binding type or null if - * "com.sun.jndi.ldap.tls.cbtype" property has not been set. - * @throws NamingException + * @return TLS Channel Binding type or null if given string is null + * @throws ChannelBindingException */ - public static TlsChannelBindingType parseType(String cbType) throws NamingException { + public static TlsChannelBindingType parseType(String cbType) throws ChannelBindingException { if (cbType != null) { if (cbType.equals(TlsChannelBindingType.TLS_SERVER_END_POINT.getName())) { return TlsChannelBindingType.TLS_SERVER_END_POINT; } else { - throw new NamingException("Illegal value for " + - CHANNEL_BINDING_TYPE + " property."); + throw new ChannelBindingException("Illegal value for channel binding type: " + cbType); } } return null; @@ -104,9 +94,9 @@ public class TlsChannelBinding { /** * Construct tls-server-end-point Channel Binding data * @param serverCertificate - * @throws SaslException + * @throws ChannelBindingException */ - public static TlsChannelBinding create(X509Certificate serverCertificate) throws SaslException { + public static TlsChannelBinding create(X509Certificate serverCertificate) throws ChannelBindingException { try { final byte[] prefix = TlsChannelBindingType.TLS_SERVER_END_POINT.getName().concat(":").getBytes(); @@ -127,7 +117,7 @@ public class TlsChannelBinding { System.arraycopy(hash, 0, cbData, prefix.length, hash.length); return new TlsChannelBinding(TlsChannelBindingType.TLS_SERVER_END_POINT, cbData); } catch (NoSuchAlgorithmException | CertificateEncodingException e) { - throw new SaslException("Cannot create TLS channel binding data", e); + throw new ChannelBindingException("Cannot create TLS channel binding data", e); } } diff --git a/src/java.base/share/classes/sun/security/x509/CRLNumberExtension.java b/src/java.base/share/classes/sun/security/x509/CRLNumberExtension.java index 9434e613441ac1aede6b75eea4d6fc54fb9bf2ba..244e9d5df9be125162130bef9355f819d3e3d4f2 100644 --- a/src/java.base/share/classes/sun/security/x509/CRLNumberExtension.java +++ b/src/java.base/share/classes/sun/security/x509/CRLNumberExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -199,7 +199,6 @@ implements CertAttrSet { * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); encode(out, PKIXExtensions.CRLNumber_Id, true); } diff --git a/src/java.base/share/classes/sun/security/x509/CertificateIssuerExtension.java b/src/java.base/share/classes/sun/security/x509/CertificateIssuerExtension.java index 0dd8f39642a3bb87c7234992df95a9e5cd6fb693..40eba681244e979b22bc79cf0698e3ba1d2a3af9 100644 --- a/src/java.base/share/classes/sun/security/x509/CertificateIssuerExtension.java +++ b/src/java.base/share/classes/sun/security/x509/CertificateIssuerExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -170,7 +170,7 @@ public class CertificateIssuerExtension extends Extension */ public String toString() { return super.toString() + "Certificate Issuer [\n" + - String.valueOf(names) + "]\n"; + names + "]\n"; } /** diff --git a/src/java.base/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java b/src/java.base/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java index 10b5a9dc09e9528a4cfc1e3cd961dc11b1f8a886..5933758874a79123ddbf9a51f116b92f96c3e16c 100644 --- a/src/java.base/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java +++ b/src/java.base/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,6 @@ package sun.security.x509; import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; -import java.util.Enumeration; - -import sun.security.util.*; /** * Represents the Delta CRL Indicator Extension. @@ -80,7 +77,7 @@ public class DeltaCRLIndicatorExtension extends CRLNumberExtension { } /** - * Creates a delta CRL indictor extension with the BigInteger value . + * Creates a delta CRL indicator extension with the BigInteger value . * The criticality is set to true. * * @param crlNum the value to be set for the extension. @@ -110,7 +107,6 @@ public class DeltaCRLIndicatorExtension extends CRLNumberExtension { * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { - DerOutputStream tmp = new DerOutputStream(); super.encode(out, PKIXExtensions.DeltaCRLIndicator_Id, true); } } diff --git a/src/java.base/share/classes/sun/security/x509/GeneralSubtrees.java b/src/java.base/share/classes/sun/security/x509/GeneralSubtrees.java index 8adafe203444d94fc37ffc17554178718a0f8c9b..c47fc0c8245c8eec481eb0e8b8c3dffb5d029428 100644 --- a/src/java.base/share/classes/sun/security/x509/GeneralSubtrees.java +++ b/src/java.base/share/classes/sun/security/x509/GeneralSubtrees.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,7 +130,7 @@ public class GeneralSubtrees implements Cloneable { /** * Encode the GeneralSubtrees. * - * @param out the DerOutputStrean to encode this object to. + * @param out the DerOutputStream to encode this object to. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream seq = new DerOutputStream(); @@ -346,7 +346,6 @@ public class GeneralSubtrees implements Cloneable { // same type in this. for (int i = 0; i < size(); i++) { GeneralNameInterface thisEntry = getGeneralNameInterface(i); - boolean removeThisEntry = false; // Step 3a: If the widest name of this type in other narrows // thisEntry, remove thisEntry and add widest other to newThis. diff --git a/src/java.base/share/classes/sun/security/x509/InvalidityDateExtension.java b/src/java.base/share/classes/sun/security/x509/InvalidityDateExtension.java index 7fac65f3ee592c28fe608e27a01c212433bb86f9..b731cba41027477e05da0991e1a142bbae5334cb 100644 --- a/src/java.base/share/classes/sun/security/x509/InvalidityDateExtension.java +++ b/src/java.base/share/classes/sun/security/x509/InvalidityDateExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -168,7 +168,7 @@ public class InvalidityDateExtension extends Extension * Returns a printable representation of the Invalidity Date. */ public String toString() { - return super.toString() + " Invalidity Date: " + String.valueOf(date); + return super.toString() + " Invalidity Date: " + date; } /** diff --git a/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java b/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java index eca45828aa638fed2c3a7ecf16c4874399b7e0cf..eda195ba60b95ae2325b22055970c37d9d8de9ce 100644 --- a/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java +++ b/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java @@ -154,7 +154,7 @@ implements CertAttrSet { if (next.isContextSpecific(TAG_REQUIRE) && !next.isConstructed()) { if (this.require != -1) - throw new IOException("Duplicate requireExplicitPolicy" + + throw new IOException("Duplicate requireExplicitPolicy " + "found in the PolicyConstraintsExtension"); next.resetTag(DerValue.tag_Integer); this.require = next.getInteger(); @@ -162,7 +162,7 @@ implements CertAttrSet { } else if (next.isContextSpecific(TAG_INHIBIT) && !next.isConstructed()) { if (this.inhibit != -1) - throw new IOException("Duplicate inhibitPolicyMapping" + + throw new IOException("Duplicate inhibitPolicyMapping " + "found in the PolicyConstraintsExtension"); next.resetTag(DerValue.tag_Integer); this.inhibit = next.getInteger(); diff --git a/src/java.base/share/classes/sun/security/x509/PolicyInformation.java b/src/java.base/share/classes/sun/security/x509/PolicyInformation.java index bf92d2694e94c344467e5150d68efe308895dc9d..0fc8d71c8d60cc8817171bb15457cb8d59769048 100644 --- a/src/java.base/share/classes/sun/security/x509/PolicyInformation.java +++ b/src/java.base/share/classes/sun/security/x509/PolicyInformation.java @@ -202,7 +202,7 @@ public class PolicyInformation { if (obj instanceof Set) { for (Object obj1 : (Set) obj) { if (!(obj1 instanceof PolicyQualifierInfo)) { - throw new IOException("Attribute value must be a" + + throw new IOException("Attribute value must be a " + "Set of PolicyQualifierInfo objects."); } } diff --git a/src/java.base/share/classes/sun/security/x509/X509CertInfo.java b/src/java.base/share/classes/sun/security/x509/X509CertInfo.java index 5fbc9a08f54fed80b3dea514cdec633d29aaf398..09a9ed2932078f50f445b60546ab36c44a03f248 100644 --- a/src/java.base/share/classes/sun/security/x509/X509CertInfo.java +++ b/src/java.base/share/classes/sun/security/x509/X509CertInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -729,7 +729,6 @@ public class X509CertInfo implements CertAttrSet { "has no extensions"); } SubjectAlternativeNameExtension subjectAltNameExt = null; - SubjectAlternativeNameExtension extValue = null; GeneralNames names = null; try { subjectAltNameExt = (SubjectAlternativeNameExtension) diff --git a/src/java.base/share/classes/sun/security/x509/X509Key.java b/src/java.base/share/classes/sun/security/x509/X509Key.java index faf7cfb927febb12ea9960f27af764c4369d7085..19979cb8e7e1509cbe3a6d8a5e691d669b5a41d7 100644 --- a/src/java.base/share/classes/sun/security/x509/X509Key.java +++ b/src/java.base/share/classes/sun/security/x509/X509Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ package sun.security.x509; import java.io.*; import java.util.Arrays; -import java.util.Properties; import java.security.Key; import java.security.PublicKey; import java.security.KeyFactory; @@ -150,10 +149,10 @@ public class X509Key implements PublicKey { * this kind of key, a subclass is returned. Otherwise, a generic * X509Key object is returned. * - *

      This mechanism gurantees that keys (and algorithms) may be + *

      This mechanism guarantees that keys (and algorithms) may be * freely manipulated and transferred, without risk of losing * information. Also, when a key (or algorithm) needs some special - * handling, that specific need can be accomodated. + * handling, that specific need can be accommodated. * * @param in the DER-encoded SubjectPublicKeyInfo value * @exception IOException on data format errors @@ -233,8 +232,6 @@ public class X509Key implements PublicKey { */ String classname = ""; try { - Properties props; - String keytype; Provider sunProvider; sunProvider = Security.getProvider("SUN"); diff --git a/src/java.base/share/classes/sun/text/RuleBasedBreakIterator.java b/src/java.base/share/classes/sun/text/RuleBasedBreakIterator.java index b3abf812f29dad922ba187e88b5d3baf9750a390..4d46cbd1c9c1b50912e0f8a4158a4c5562fc1e6a 100644 --- a/src/java.base/share/classes/sun/text/RuleBasedBreakIterator.java +++ b/src/java.base/share/classes/sun/text/RuleBasedBreakIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,7 +70,7 @@ import sun.text.SupplementaryCharacterData; * expression defines a set of characters (the "ignore characters") that * will be transparent to the BreakIterator.  A sequence of characters will break the * same way it would if any ignore characters it contains are taken out.  Break - * positions never occur befoer ignore characters.

      + * positions never occur before ignore characters.

      * *

      A regular expression uses a subset of the normal Unix regular-expression syntax, and * defines a sequence of characters to be kept together. With one significant exception, the @@ -151,7 +151,7 @@ import sun.text.SupplementaryCharacterData; * If ! appears at the beginning of a regular expression, it tells the regexp * parser that this expression specifies the backwards-iteration behavior of the iterator, * and not its normal iteration behavior.  This is generally only used in situations - * where the automatically-generated backwards-iteration brhavior doesn't produce + * where the automatically-generated backwards-iteration behavior doesn't produce * satisfactory results and must be supplemented with extra client-specified rules. * * diff --git a/src/java.base/share/classes/sun/text/spi/JavaTimeDateTimePatternProvider.java b/src/java.base/share/classes/sun/text/spi/JavaTimeDateTimePatternProvider.java index c8fd888e2b2699f253a97735c6263c6f4e831f89..a3835c6ac82e1a93214a4785eb438a241768fbed 100644 --- a/src/java.base/share/classes/sun/text/spi/JavaTimeDateTimePatternProvider.java +++ b/src/java.base/share/classes/sun/text/spi/JavaTimeDateTimePatternProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,12 +46,12 @@ public abstract class JavaTimeDateTimePatternProvider extends LocaleServiceProvi * Concrete implementation of this method will retrieve * a java.time specific dateTime Pattern from selected Locale Provider. * - * @param timeStyle an {@code int} value representing FormatStyle constant, -1 + * @param timeStyle an {@code int} value, representing FormatStyle constant, -1 * for date-only pattern - * @param dateStyle an {@code int} value,representing FormatStyle constant, -1 + * @param dateStyle an {@code int} value, representing FormatStyle constant, -1 * for time-only pattern * @param locale {@code locale}, non-null - * @param calType a {@code String},non-null representing CalendarType such as "japanese", + * @param calType a {@code String}, non-null representing CalendarType such as "japanese", * "iso8601" * @return formatting pattern {@code String} * @see java.time.format.DateTimeFormatterBuilder#convertStyle(java.time.format.FormatStyle) diff --git a/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java b/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java index 6d78d77f64d1d5669727318a92b05a5cfb70c57f..f97888a697783cfd5508dac07759419c4b1d49d8 100644 --- a/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java +++ b/src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ public class CLDRTimeZoneNameProviderImpl extends TimeZoneNameProviderImpl { } if (namesSuper != null) { - // CLDR's resource bundle has an translated entry for this id. + // CLDR's resource bundle has a translated entry for this id. // Fix up names if needed, either missing or no-inheritance namesSuper[INDEX_TZID] = id; @@ -91,7 +91,7 @@ public class CLDRTimeZoneNameProviderImpl extends TimeZoneNameProviderImpl { case "": // Fill in empty elements deriveFallbackName(namesSuper, i, locale, - !TimeZone.getTimeZone(id).useDaylightTime()); + TimeZone.getTimeZone(id).toZoneId().getRules().isFixedOffset()); break; case NO_INHERITANCE_MARKER: // CLDR's "no inheritance marker" @@ -129,7 +129,7 @@ public class CLDRTimeZoneNameProviderImpl extends TimeZoneNameProviderImpl { // Derive fallback time zone name according to LDML's logic private void deriveFallbackNames(String[] names, Locale locale) { - boolean noDST = !TimeZone.getTimeZone(names[0]).useDaylightTime(); + boolean noDST = TimeZone.getTimeZone(names[0]).toZoneId().getRules().isFixedOffset(); for (int i = INDEX_STD_LONG; i <= INDEX_GEN_SHORT; i++) { deriveFallbackName(names, i, locale, noDST); @@ -149,13 +149,12 @@ public class CLDRTimeZoneNameProviderImpl extends TimeZoneNameProviderImpl { return; } - // Check parent locale first + // Check parent locales first if (!exists(names, index)) { - CLDRLocaleProviderAdapter clpa = (CLDRLocaleProviderAdapter)LocaleProviderAdapter.forType(Type.CLDR); - var cands = clpa.getCandidateLocales("", locale); - if (cands.size() > 1) { - var parentLoc = cands.get(1); // immediate parent locale - String[] parentNames = super.getDisplayNameArray(id, parentLoc); + var cands = ((CLDRLocaleProviderAdapter)LocaleProviderAdapter.forType(Type.CLDR)) + .getCandidateLocales("", locale); + for (int i = 1; i < cands.size() ; i++) { + String[] parentNames = super.getDisplayNameArray(id, cands.get(i)); if (parentNames != null && !parentNames[index].isEmpty()) { names[index] = parentNames[index]; return; @@ -163,18 +162,20 @@ public class CLDRTimeZoneNameProviderImpl extends TimeZoneNameProviderImpl { } } + // Type Fallback + if (noDST && typeFallback(names, index)) { + return; + } + // Check if COMPAT can substitute the name - if (LocaleProviderAdapter.getAdapterPreference().contains(Type.JRE)) { + if (!exists(names, index) && + LocaleProviderAdapter.getAdapterPreference().contains(Type.JRE)) { String[] compatNames = (String[])LocaleProviderAdapter.forJRE() - .getLocaleResources(mapChineseLocale(locale)) - .getTimeZoneNames(id); + .getLocaleResources(mapChineseLocale(locale)) + .getTimeZoneNames(id); if (compatNames != null) { - for (int i = INDEX_STD_LONG; i <= INDEX_GEN_SHORT; i++) { - // Assumes COMPAT has no empty slots - if (i == index || !exists(names, i)) { - names[i] = compatNames[i]; - } - } + // Assumes COMPAT has no empty slots + names[index] = compatNames[index]; return; } } @@ -184,11 +185,6 @@ public class CLDRTimeZoneNameProviderImpl extends TimeZoneNameProviderImpl { return; } - // Type Fallback - if (noDST && typeFallback(names, index)) { - return; - } - // last resort names[index] = toGMTFormat(id, index == INDEX_DST_LONG || index == INDEX_DST_SHORT, @@ -234,6 +230,11 @@ public class CLDRTimeZoneNameProviderImpl extends TimeZoneNameProviderImpl { } private boolean regionFormatFallback(String[] names, int index, Locale l) { + if (index % 2 == 0) { + // ignore short names + return false; + } + String id = names[INDEX_TZID]; LocaleResources lr = LocaleProviderAdapter.forType(Type.CLDR).getLocaleResources(l); ResourceBundle fd = lr.getJavaTimeFormatData(); diff --git a/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java b/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java index 07d4252f0e0f0449b869dfaae6456ba6a7586502..72844b966d032c90566024927a2c800b564d92b7 100644 --- a/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java +++ b/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java @@ -124,8 +124,18 @@ public final class LocaleMatcher { for (LanguageRange lr : nonZeroRanges) { String range = lr.getRange(); if (range.equals("*")) { - tags = removeTagsMatchingBasicZeroRange(zeroRanges, tags); - return new ArrayList(tags); + for (String tag : tags) { + // change to lowercase for case-insensitive matching + String lowerCaseTag = tag.toLowerCase(Locale.ROOT); + + if (!caseInsensitiveMatch(list, lowerCaseTag) + && !shouldIgnoreFilterBasicMatch(zeroRanges, lowerCaseTag)) { + // preserving the case of the input tag + list.add(tag); + } + } + + break; } else { for (String tag : tags) { // change to lowercase for case-insensitive matching @@ -148,44 +158,6 @@ public final class LocaleMatcher { return list; } - /** - * Removes the tag(s) which are falling in the basic exclusion range(s) i.e - * range(s) with q=0 and returns the updated collection. If the basic - * language ranges contains '*' as one of its non zero range then instead of - * returning all the tags, remove those which are matching the range with - * quality weight q=0. - */ - private static Collection removeTagsMatchingBasicZeroRange( - List zeroRange, Collection tags) { - if (zeroRange.isEmpty()) { - tags = removeDuplicates(tags); - return tags; - } - - List matchingTags = new ArrayList<>(); - for (String tag : tags) { - // change to lowercase for case-insensitive matching - String lowerCaseTag = tag.toLowerCase(Locale.ROOT); - if (!shouldIgnoreFilterBasicMatch(zeroRange, lowerCaseTag) - && !caseInsensitiveMatch(matchingTags, lowerCaseTag)) { - matchingTags.add(tag); // preserving the case of the input tag - } - } - - return matchingTags; - } - - /** - * Remove duplicate tags from the given {@code tags} by - * ignoring case considerations. - */ - private static Collection removeDuplicates( - Collection tags) { - Set distinctTags = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - return tags.stream().filter(x -> distinctTags.add(x)) - .toList(); - } - /** * Returns true if the given {@code list} contains an element which matches * with the given {@code tag} ignoring case considerations. @@ -240,8 +212,18 @@ public final class LocaleMatcher { for (LanguageRange lr : nonZeroRanges) { String range = lr.getRange(); if (range.equals("*")) { - tags = removeTagsMatchingExtendedZeroRange(zeroRanges, tags); - return new ArrayList(tags); + for (String tag : tags) { + // change to lowercase for case-insensitive matching + String lowerCaseTag = tag.toLowerCase(Locale.ROOT); + + if (!caseInsensitiveMatch(list, lowerCaseTag) + && !shouldIgnoreFilterExtendedMatch(zeroRanges, lowerCaseTag)) { + // preserving the case of the input tag + list.add(tag); + } + } + + break; } String[] rangeSubtags = range.split("-"); for (String tag : tags) { @@ -267,33 +249,6 @@ public final class LocaleMatcher { return list; } - /** - * Removes the tag(s) which are falling in the extended exclusion range(s) - * i.e range(s) with q=0 and returns the updated collection. If the extended - * language ranges contains '*' as one of its non zero range then instead of - * returning all the tags, remove those which are matching the range with - * quality weight q=0. - */ - private static Collection removeTagsMatchingExtendedZeroRange( - List zeroRange, Collection tags) { - if (zeroRange.isEmpty()) { - tags = removeDuplicates(tags); - return tags; - } - - List matchingTags = new ArrayList<>(); - for (String tag : tags) { - // change to lowercase for case-insensitive matching - String lowerCaseTag = tag.toLowerCase(Locale.ROOT); - if (!shouldIgnoreFilterExtendedMatch(zeroRange, lowerCaseTag) - && !caseInsensitiveMatch(matchingTags, lowerCaseTag)) { - matchingTags.add(tag); // preserve the case of the input tag - } - } - - return matchingTags; - } - /** * The tag which is falling in the extended exclusion range(s) should * not be considered as the matching tag. Ignores the tag matching with the diff --git a/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java b/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java index b6351cf1aca9a2702324dd9ddbbde34ba881d57d..fe84b66b167c75666126102714eb197c82677c86 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java +++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -605,7 +605,7 @@ public class LocaleResources { } } - private static final boolean TRACE_ON = Boolean.valueOf( + private static final boolean TRACE_ON = Boolean.parseBoolean( GetPropertyAction.privilegedGetProperty("locale.resources.debug", "false")); public static void trace(String format, Object... params) { diff --git a/src/java.base/share/legal/icu.md b/src/java.base/share/legal/icu.md index ab850bf143edf5f4febfbc82c7b65f47b0e2bd8e..35a54e61112aaac3257c9ea0b255baa3fd58effb 100644 --- a/src/java.base/share/legal/icu.md +++ b/src/java.base/share/legal/icu.md @@ -1,4 +1,4 @@ -## International Components for Unicode (ICU4J) v67.1 +## International Components for Unicode (ICU4J) v70.1 ### ICU4J License ``` @@ -80,61 +80,439 @@ of the copyright holder. All trademarks and registered trademarks mentioned herein are the property of their respective owners. +2. Chinese/Japanese Word Break Dictionary Data (cjdict.txt) -—————————————————————————————————————————————————————————————————————— - - -From: https://www.unicode.org/copyright.html: - - Unicode® Copyright and Terms of Use - - For the general privacy policy governing access to this site, see the Unicode Privacy Policy. - - Unicode Copyright - Copyright © 1991-2020 Unicode, Inc. All rights reserved. - Definitions - - Unicode Data Files ("DATA FILES") include all data files under the directories: - https://www.unicode.org/Public/ - https://www.unicode.org/reports/ - https://www.unicode.org/ivd/data/ - - Unicode Data Files do not include PDF online code charts under the directory: - https://www.unicode.org/Public/ - - Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard - or any source code or compiled code under the directories: - https://www.unicode.org/Public/PROGRAMS/ - https://www.unicode.org/Public/cldr/ - http://site.icu-project.org/download/ - - Terms of Use - Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. - Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. - Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. - Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. - The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. - All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. - No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. - Modification is not permitted with respect to this document. All copies of this document must be verbatim. - Restricted Rights Legend - Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. - Warranties and Disclaimers - This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. - If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. - EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. - Waiver of Damages - In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. - Trademarks & Logos - The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. - The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. - All third party trademarks referenced herein are the property of their respective owners. - Miscellaneous - Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. - Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. - Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. - Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. - Entire Agreement. This Agreement constitutes the entire agreement between the parties. + # The Google Chrome software developed by Google is licensed under + # the BSD license. Other software included in this distribution is + # provided under other licenses, as set forth below. + # + # The BSD License + # http://opensource.org/licenses/bsd-license.php + # Copyright (C) 2006-2008, Google Inc. + # + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are met: + # + # Redistributions of source code must retain the above copyright notice, + # this list of conditions and the following disclaimer. + # Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following + # disclaimer in the documentation and/or other materials provided with + # the distribution. + # Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # + # + # The word list in cjdict.txt are generated by combining three word lists + # listed below with further processing for compound word breaking. The + # frequency is generated with an iterative training against Google web + # corpora. + # + # * Libtabe (Chinese) + # - https://sourceforge.net/project/?group_id=1519 + # - Its license terms and conditions are shown below. + # + # * IPADIC (Japanese) + # - http://chasen.aist-nara.ac.jp/chasen/distribution.html + # - Its license terms and conditions are shown below. + # + # ---------COPYING.libtabe ---- BEGIN-------------------- + # + # /* + # * Copyright (c) 1999 TaBE Project. + # * Copyright (c) 1999 Pai-Hsiang Hsiao. + # * All rights reserved. + # * + # * Redistribution and use in source and binary forms, with or without + # * modification, are permitted provided that the following conditions + # * are met: + # * + # * . Redistributions of source code must retain the above copyright + # * notice, this list of conditions and the following disclaimer. + # * . Redistributions in binary form must reproduce the above copyright + # * notice, this list of conditions and the following disclaimer in + # * the documentation and/or other materials provided with the + # * distribution. + # * . Neither the name of the TaBE Project nor the names of its + # * contributors may be used to endorse or promote products derived + # * from this software without specific prior written permission. + # * + # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # * OF THE POSSIBILITY OF SUCH DAMAGE. + # */ + # + # /* + # * Copyright (c) 1999 Computer Systems and Communication Lab, + # * Institute of Information Science, Academia + # * Sinica. All rights reserved. + # * + # * Redistribution and use in source and binary forms, with or without + # * modification, are permitted provided that the following conditions + # * are met: + # * + # * . Redistributions of source code must retain the above copyright + # * notice, this list of conditions and the following disclaimer. + # * . Redistributions in binary form must reproduce the above copyright + # * notice, this list of conditions and the following disclaimer in + # * the documentation and/or other materials provided with the + # * distribution. + # * . Neither the name of the Computer Systems and Communication Lab + # * nor the names of its contributors may be used to endorse or + # * promote products derived from this software without specific + # * prior written permission. + # * + # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # * OF THE POSSIBILITY OF SUCH DAMAGE. + # */ + # + # Copyright 1996 Chih-Hao Tsai @ Beckman Institute, + # University of Illinois + # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 + # + # ---------------COPYING.libtabe-----END-------------------------------- + # + # + # ---------------COPYING.ipadic-----BEGIN------------------------------- + # + # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science + # and Technology. All Rights Reserved. + # + # Use, reproduction, and distribution of this software is permitted. + # Any copy of this software, whether in its original form or modified, + # must include both the above copyright notice and the following + # paragraphs. + # + # Nara Institute of Science and Technology (NAIST), + # the copyright holders, disclaims all warranties with regard to this + # software, including all implied warranties of merchantability and + # fitness, in no event shall NAIST be liable for + # any special, indirect or consequential damages or any damages + # whatsoever resulting from loss of use, data or profits, whether in an + # action of contract, negligence or other tortuous action, arising out + # of or in connection with the use or performance of this software. + # + # A large portion of the dictionary entries + # originate from ICOT Free Software. The following conditions for ICOT + # Free Software applies to the current dictionary as well. + # + # Each User may also freely distribute the Program, whether in its + # original form or modified, to any third party or parties, PROVIDED + # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear + # on, or be attached to, the Program, which is distributed substantially + # in the same form as set out herein and that such intended + # distribution, if actually made, will neither violate or otherwise + # contravene any of the laws and regulations of the countries having + # jurisdiction over the User or the intended distribution itself. + # + # NO WARRANTY + # + # The program was produced on an experimental basis in the course of the + # research and development conducted during the project and is provided + # to users as so produced on an experimental basis. Accordingly, the + # program is provided without any warranty whatsoever, whether express, + # implied, statutory or otherwise. The term "warranty" used herein + # includes, but is not limited to, any warranty of the quality, + # performance, merchantability and fitness for a particular purpose of + # the program and the nonexistence of any infringement or violation of + # any right of any third party. + # + # Each user of the program will agree and understand, and be deemed to + # have agreed and understood, that there is no warranty whatsoever for + # the program and, accordingly, the entire risk arising from or + # otherwise connected with the program is assumed by the user. + # + # Therefore, neither ICOT, the copyright holder, or any other + # organization that participated in or was otherwise related to the + # development of the program and their respective officials, directors, + # officers and other employees shall be held liable for any and all + # damages, including, without limitation, general, special, incidental + # and consequential damages, arising out of or otherwise in connection + # with the use or inability to use the program or any product, material + # or result produced or otherwise obtained by using the program, + # regardless of whether they have been advised of, or otherwise had + # knowledge of, the possibility of such damages at any time during the + # project or thereafter. Each user will be deemed to have agreed to the + # foregoing by his or her commencement of use of the program. The term + # "use" as used herein includes, but is not limited to, the use, + # modification, copying and distribution of the program and the + # production of secondary products from the program. + # + # In the case where the program, whether in its original form or + # modified, was distributed or delivered to or received by a user from + # any person, organization or entity other than ICOT, unless it makes or + # grants independently of ICOT any specific warranty to the user in + # writing, such person, organization or entity, will also be exempted + # from and not be held liable to the user for any such damages as noted + # above as far as the program is concerned. + # + # ---------------COPYING.ipadic-----END---------------------------------- + +3. Lao Word Break Dictionary Data (laodict.txt) + + # Copyright (C) 2016 and later: Unicode, Inc. and others. + # License & terms of use: http://www.unicode.org/copyright.html + # Copyright (c) 2015 International Business Machines Corporation + # and others. All Rights Reserved. + # + # Project: https://github.com/rober42539/lao-dictionary + # Dictionary: https://github.com/rober42539/lao-dictionary/laodict.txt + # License: https://github.com/rober42539/lao-dictionary/LICENSE.txt + # (copied below) + # + # This file is derived from the above dictionary version of Nov 22, 2020 + # ---------------------------------------------------------------------- + # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are met: + # + # Redistributions of source code must retain the above copyright notice, this + # list of conditions and the following disclaimer. Redistributions in binary + # form must reproduce the above copyright notice, this list of conditions and + # the following disclaimer in the documentation and/or ther materials + # provided with the distribution. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # OF THE POSSIBILITY OF SUCH DAMAGE. + # -------------------------------------------------------------------------- + +4. Burmese Word Break Dictionary Data (burmesedict.txt) + + # Copyright (c) 2014 International Business Machines Corporation + # and others. All Rights Reserved. + # + # This list is part of a project hosted at: + # github.com/kanyawtech/myanmar-karen-word-lists + # + # -------------------------------------------------------------------------- + # Copyright (c) 2013, LeRoy Benjamin Sharon + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: Redistributions of source code must retain the above + # copyright notice, this list of conditions and the following + # disclaimer. Redistributions in binary form must reproduce the + # above copyright notice, this list of conditions and the following + # disclaimer in the documentation and/or other materials provided + # with the distribution. + # + # Neither the name Myanmar Karen Word Lists, nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + # SUCH DAMAGE. + # -------------------------------------------------------------------------- + +5. Time Zone Database + + ICU uses the public domain data and code derived from Time Zone +Database for its time zone support. The ownership of the TZ database +is explained in BCP 175: Procedure for Maintaining the Time Zone +Database section 7. + + # 7. Database Ownership + # + # The TZ database itself is not an IETF Contribution or an IETF + # document. Rather it is a pre-existing and regularly updated work + # that is in the public domain, and is intended to remain in the + # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do + # not apply to the TZ Database or contributions that individuals make + # to it. Should any claims be made and substantiated against the TZ + # Database, the organization that is providing the IANA + # Considerations defined in this RFC, under the memorandum of + # understanding with the IETF, currently ICANN, may act in accordance + # with all competent court orders. No ownership claims will be made + # by ICANN or the IETF Trust on the database or the code. Any person + # making a contribution to the database or code waives all rights to + # future claims in that contribution or in the TZ Database. + +6. Google double-conversion + +Copyright 2006-2011, the V8 project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +==================================================== + +Unicode® Copyright and Terms of Use +For the general privacy policy governing access to this site, see the Unicode Privacy Policy. + +Unicode Copyright +Copyright © 1991-2021 Unicode, Inc. All rights reserved. +Definitions +Unicode Data Files ("DATA FILES") include all data files under the directories: +https://www.unicode.org/Public/ +https://www.unicode.org/reports/ +https://www.unicode.org/ivd/data/ + +Unicode Data Files do not include PDF online code charts under the directory: +https://www.unicode.org/Public/ + +Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard +or any source code or compiled code under the directories: +https://www.unicode.org/Public/PROGRAMS/ +https://www.unicode.org/Public/cldr/ +http://site.icu-project.org/download/ +Terms of Use +Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. +Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. +Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. +Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. +The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. +All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. +No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. +Modification is not permitted with respect to this document. All copies of this document must be verbatim. +Restricted Rights Legend +Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. +Warranties and Disclaimers +This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. +If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. +EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. +Waiver of Damages +In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. +Trademarks & Logos +The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. +The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. +All third party trademarks referenced herein are the property of their respective owners. +Miscellaneous +Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. +Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. +Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. +Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. +Entire Agreement. This Agreement constitutes the entire agreement between the parties. + +======================================================= + +UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE + +See Terms of Use +for definitions of Unicode Inc.’s Data Files and Software. + +NOTICE TO USER: Carefully read the following legal agreement. +BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. +IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +THE DATA FILES OR SOFTWARE. + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 1991-2021 Unicode, Inc. All rights reserved. +Distributed under the Terms of Use in https://www.unicode.org/copyright.html. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Unicode data files and any associated documentation +(the "Data Files") or Unicode software and any associated documentation +(the "Software") to deal in the Data Files or Software +without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, and/or sell copies of +the Data Files or Software, and to permit persons to whom the Data Files +or Software are furnished to do so, provided that either +(a) this copyright and permission notice appear with all copies +of the Data Files or Software, or +(b) this copyright and permission notice appear in associated +Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT OF THIRD PARTY RIGHTS. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THE DATA FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in these Data Files or Software without prior +written authorization of the copyright holder. ``` diff --git a/src/java.base/share/legal/unicode.md b/src/java.base/share/legal/unicode.md index cff0c82a873dd86974430c7b506303b313dfed04..fbb82346769fa04caf4186bfa53e01df02238d4a 100644 --- a/src/java.base/share/legal/unicode.md +++ b/src/java.base/share/legal/unicode.md @@ -1,5 +1,5 @@ -## The Unicode Standard, Unicode Character Database, Version 13.0.0 - +## The Unicode Standard, Unicode Character Database, Version 14.0.0 + ### Unicode Character Database ``` @@ -18,7 +18,7 @@ THE DATA FILES OR SOFTWARE. COPYRIGHT AND PERMISSION NOTICE -Copyright © 1991-2020 Unicode, Inc. All rights reserved. +Copyright © 1991-2021 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining @@ -50,5 +50,54 @@ shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. +=== http://www.unicode.org/copyright.html content === +Unicode (R) Copyright and Terms of Use +For the general privacy policy governing access to this site, see the Unicode Privacy Policy. + +Unicode Copyright +Copyright (C) 1991-2021 Unicode, Inc. All rights reserved. +Definitions +Unicode Data Files ("DATA FILES") include all data files under the directories: +https://www.unicode.org/Public/ +https://www.unicode.org/reports/ +https://www.unicode.org/ivd/data/ + +Unicode Data Files do not include PDF online code charts under the directory: +https://www.unicode.org/Public/ + +Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard +or any source code or compiled code under the directories: +https://www.unicode.org/Public/PROGRAMS/ +https://www.unicode.org/Public/cldr/ +http://site.icu-project.org/download/ +Terms of Use +Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. +Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. +Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. +Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. +The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. +All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. +No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. +Modification is not permitted with respect to this document. All copies of this document must be verbatim. +Restricted Rights Legend +Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. +Warranties and Disclaimers +This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. +If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. +EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. +Waiver of Damages +In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. +Trademarks & Logos +The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. +The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. +All third party trademarks referenced herein are the property of their respective owners. +Miscellaneous +Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. +Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. +Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. +Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. +Entire Agreement. This Agreement constitutes the entire agreement between the parties. + + ``` diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1 index b9ce956462c2b72d543b2587effbdcfe9d1a1e00..6a1532a8981ba93481fdd1542d55e9511537efa0 100644 --- a/src/java.base/share/man/java.1 +++ b/src/java.base/share/man/java.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. .\" 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,7 +22,7 @@ .\"t .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVA" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JAVA" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP @@ -181,7 +181,7 @@ with new values added and old values removed. You\[aq]ll get an error message if you use a value of \f[I]N\f[R] that is no longer supported. The supported values of \f[I]N\f[R] are the current Java SE release -(\f[CB]18\f[R]) and a limited number of previous releases, detailed in the +(\f[CB]19\f[R]) and a limited number of previous releases, detailed in the command\-line help for \f[CB]javac\f[R], under the \f[CB]\-\-source\f[R] and \f[CB]\-\-release\f[R] options. .RE @@ -512,6 +512,15 @@ of the release. .RS .RE .TP +.B \f[CB]\-\-finalization=\f[R]\f[I]value\f[R] +Controls whether the JVM performs finalization of objects. +Valid values are "enabled" and "disabled". +Finalization is enabled by default, so the value "enabled" does nothing. +The value "disabled" disables finalization, so that no finalizers are +invoked. +.RS +.RE +.TP .B \f[CB]\-\-module\-path\f[R] \f[I]modulepath\f[R]... or \f[CB]\-p\f[R] \f[I]modulepath\f[R] A semicolon (\f[CB];\f[R]) separated list of directories in which each directory is a directory of modules. @@ -935,11 +944,11 @@ size of the heap for the young generation, you can use .RE .TP .B \f[CB]\-Xms\f[R] \f[I]size\f[R] -Sets the minimum and initial size (in bytes) of the heap. +Sets the minimum and the initial size (in bytes) of the heap. This value must be a multiple of 1024 and greater than 1 MB. Append the letter \f[CB]k\f[R] or \f[CB]K\f[R] to indicate kilobytes, -\f[CB]m\f[R] or \f[CB]M\f[R] to indicate megabytes, \f[CB]g\f[R] or \f[CB]G\f[R] -to indicate gigabytes. +\f[CB]m\f[R] or \f[CB]M\f[R] to indicate megabytes, or \f[CB]g\f[R] or +\f[CB]G\f[R] to indicate gigabytes. The following examples show how to set the size of allocated memory to 6 MB using various units: .RS @@ -952,14 +961,17 @@ MB using various units: \f[R] .fi .PP -Instead of the \f[CB]\-Xms\f[R] option to set both the minimum and initial -size of the heap, you can use \f[CB]\-XX:MinHeapSize\f[R] to set the -minimum size and \f[CB]\-XX:InitialHeapSize\f[R] to set the initial size. -.PP -If you don\[aq]t set this option, the initial size is set as the sum of -the sizes allocated for the old generation and the young generation. +If you do not set this option, then the initial size will be set as the +sum of the sizes allocated for the old generation and the young +generation. The initial size of the heap for the young generation can be set using the \f[CB]\-Xmn\f[R] option or the \f[CB]\-XX:NewSize\f[R] option. +.PP +Note that the \f[CB]\-XX:InitialHeapSize\f[R] option can also be used to +set the initial heap size. +If it appears after \f[CB]\-Xms\f[R] on the command line, then the initial +heap size gets set to the value specified with +\f[CB]\-XX:InitialHeapSize\f[R]. .RE .TP .B \f[CB]\-Xmx\f[R] \f[I]size\f[R] @@ -1078,8 +1090,10 @@ Require using shared class data, otherwise fail. .RS .PP \f[B]Note:\f[R] The \f[CB]\-Xshare:on\f[R] option is used for testing -purposes only and may cause intermittent failures due to the use of -address space layout randomization by the operation system. +purposes only. +It may cause the VM to unexpectedly exit during start\-up when the CDS +archive cannot be used (for example, when certain VM parameters are +changed, or when a different JDK is used). This option should not be used in production environments. .RE .TP @@ -1366,7 +1380,7 @@ By default this option is disabled. .RS .RE .TP -.B \f[CB]\-XX:FlightRecorderOptions=\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R] (or)\f[CB]\-XX:FlightRecorderOptions:\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R] +.B \f[CB]\-XX:FlightRecorderOptions=\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R] (or) \f[CB]\-XX:FlightRecorderOptions:\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R] Sets the parameters that control the behavior of JFR. .RS .PP @@ -1428,14 +1442,6 @@ By default, this parameter is enabled. .RS .RE .TP -.B \f[CB]samplethreads=\f[R]{\f[CB]true\f[R]|\f[CB]false\f[R]} -Specifies whether thread sampling is enabled. -Thread sampling occurs only if the sampling event is enabled along with -this parameter. -By default, this parameter is enabled. -.RS -.RE -.TP .B \f[CB]stackdepth=\f[R]\f[I]depth\f[R] Stack depth for stack traces. By default, the depth is set to 64 method calls. @@ -1538,6 +1544,31 @@ and its committed regions. .RE .RE .TP +.B \f[CB]\-XX:+NeverActAsServerClassMachine\f[R] +Enable the "Client VM emulation" mode which only uses the C1 JIT +compiler, a 32Mb CodeCache and the Serial GC. +The maximum amount of memory that the JVM may use (controlled by the +\f[CB]\-XX:MaxRAM=n\f[R] flag) is set to 1GB by default. +The string "emulated\-client" is added to the JVM version string. +.RS +.PP +By default the flag is set to \f[CB]true\f[R] only on Windows in 32\-bit +mode and \f[CB]false\f[R] in all other cases. +.PP +The "Client VM emulation" mode will not be enabled if any of the +following flags are used on the command line: +.IP +.nf +\f[CB] +\-XX:{+|\-}TieredCompilation +\-XX:CompilationMode=mode +\-XX:TieredStopAtLevel=n +\-XX:{+|\-}EnableJVMCI +\-XX:{+|\-}UseJVMCICompiler +\f[R] +.fi +.RE +.TP .B \f[CB]\-XX:ObjectAlignmentInBytes=\f[R]\f[I]alignment\f[R] Sets the memory alignment of Java objects (in bytes). By default, the value is set to 8 bytes. @@ -1640,7 +1671,7 @@ Specifies the path and name of the class data sharing (CDS) archive file See \f[B]Application Class Data Sharing\f[R]. .RE .TP -.B \f[CB]\-XX:SharedArchiveConfigFile\f[R]=\f[I]shared_config_file\f[R] +.B \f[CB]\-XX:SharedArchiveConfigFile=\f[R]\f[I]shared_config_file\f[R] Specifies additional shared data added to the archive file. .RS .RE @@ -1747,9 +1778,6 @@ written when the recording is stopped, for example: \f[CB]/home/user/recordings/recording.jfr\f[R] .IP \[bu] 2 \f[CB]c:\\recordings\\recording.jfr\f[R] -.PP -If \f[CB]%p\f[R] and/or \f[CB]%t\f[R] is specified in the filename, it expands to the JVM\[aq]s -PID and the current timestamp, respectively. .RE .TP .B \f[CB]name=\f[R]\f[I]identifier\f[R] @@ -1825,10 +1853,10 @@ To list available options, use the \f[CB]JAVA_HOME\f[R]/bin/jfr tool. .RS .RE .TP -.B \f[CB]event\-setting\f[R]=\f[I]value\f[R] +.B \f[CB]event\-setting=\f[R]\f[I]value\f[R] Specifies the event setting value to modify. -Use the form: #= To add a new event setting, prefix the event name with -\[aq]+\[aq]. +Use the form: \f[CB]#=\f[R]. +To add a new event setting, prefix the event name with \[aq]+\[aq]. .RS .RE .PP @@ -2591,23 +2619,19 @@ The \f[CB]\-XX:UseRTMLocking\f[R] option must be enabled. .RE .TP .B \f[CB]\-XX:+SegmentedCodeCache\f[R] -Enables segmentation of the code cache. -Without the \f[CB]\-XX:+SegmentedCodeCache\f[R], the code cache consists -of one large segment. -With \f[CB]\-XX:+SegmentedCodeCache\f[R], we have separate segments for -nonmethod, profiled method, and nonprofiled method code. -These segments aren\[aq]t resized at runtime. -The feature is enabled by default if tiered compilation is enabled -(\f[CB]\-XX:+TieredCompilation\f[R] ) and -\f[CB]\-XX:ReservedCodeCacheSize\f[R] >= 240 MB. +Enables segmentation of the code cache, without which the code cache +consists of one large segment. +With \f[CB]\-XX:+SegmentedCodeCache\f[R], separate segments will be used +for non\-method, profiled method, and non\-profiled method code. +The segments are not resized at runtime. The advantages are better control of the memory footprint, reduced code -fragmentation, and better iTLB/iCache behavior due to improved locality. -iTLB/iCache is a CPU\-specific term meaning Instruction Translation -Lookaside Buffer (ITLB). -ICache is an instruction cache in theCPU. -The implementation of the code cache can be found in the file: -\f[CB]/share/vm/code/codeCache.cpp\f[R]. +fragmentation, and better CPU iTLB (instruction translation lookaside +buffer) and instruction cache behavior due to improved locality. .RS +.PP +The feature is enabled by default if tiered compilation is enabled +(\f[CB]\-XX:+TieredCompilation\f[R] ) and the reserved code cache size +(\f[CB]\-XX:ReservedCodeCacheSize\f[R]) is at least 240 MB. .RE .TP .B \f[CB]\-XX:StartAggressiveSweepingAt=\f[R]\f[I]percent\f[R] @@ -2639,7 +2663,8 @@ Is set by default to the highest supported version available (x86 only). Enables hardware\-based AES intrinsics for hardware that supports it. This option is on by default on hardware that has the necessary instructions. -The \f[CB]\-XX:+UseAES\f[R] is used in conjunction with UseAESIntrinsics. +The \f[CB]\-XX:+UseAES\f[R] is used in conjunction with +\f[CB]UseAESIntrinsics\f[R]. Flags that control intrinsics now require the option \f[CB]\-XX:+UnlockDiagnosticVMOptions\f[R]. .RS @@ -2647,8 +2672,8 @@ Flags that control intrinsics now require the option .TP .B \f[CB]\-XX:+UseAESIntrinsics\f[R] Enables AES intrinsics. -Specifying\f[CB]\-XX:+UseAESIntrinsics\f[R] is equivalent to also enabling -\f[CB]\-XX:+UseAES\f[R]. +Specifying \f[CB]\-XX:+UseAESIntrinsics\f[R] is equivalent to also +enabling \f[CB]\-XX:+UseAES\f[R]. To disable hardware\-based AES intrinsics, specify \f[CB]\-XX:\-UseAES\ \-XX:\-UseAESIntrinsics\f[R]. For example, to enable hardware AES, use the following flags: @@ -2844,7 +2869,7 @@ The default value is 1,000. .RS .RE .TP -.B \f[CB]\-XX:LoopStripMiningIterShortLoop\f[R]=\f[I]number_of_iterations\f[R] +.B \f[CB]\-XX:LoopStripMiningIterShortLoop=\f[R]\f[I]number_of_iterations\f[R] Controls loop strip mining optimization. Loops with the number of iterations less than specified will not have safepoints in them. @@ -2971,7 +2996,7 @@ an \f[CB]OutOfMemoryError\f[R] exception is thrown. .RS .RE .TP -.B \f[CB]\-XX:HeapDumpPath=path\f[R] +.B \f[CB]\-XX:HeapDumpPath=\f[R]\f[I]path\f[R] Sets the path and file name for writing the heap dump provided by the heap profiler (HPROF) when the \f[CB]\-XX:+HeapDumpOnOutOfMemoryError\f[R] option is set. @@ -3165,7 +3190,7 @@ The default value is 3. .RS .RE .TP -.B \f[CB]\-XX:G1HeapRegionSize=size\f[R] +.B \f[CB]\-XX:G1HeapRegionSize=\f[R]\f[I]size\f[R] Sets the size of the regions into which the Java heap is subdivided when using the garbage\-first (G1) collector. The value is a power of 2 and can range from 1 MB to 32 MB. @@ -3294,6 +3319,11 @@ If you set this option to 0, then the initial size is set as the sum of the sizes allocated for the old generation and the young generation. The size of the heap for the young generation can be set using the \f[CB]\-XX:NewSize\f[R] option. +Note that the \f[CB]\-Xms\f[R] option sets both the minimum and the +initial heap size of the heap. +If \f[CB]\-Xms\f[R] appears after \f[CB]\-XX:InitialHeapSize\f[R] on the +command line, then the initial heap size gets set to the value specified +with \f[CB]\-Xms\f[R]. .RE .TP .B \f[CB]\-XX:InitialRAMPercentage=\f[R]\f[I]percent\f[R] @@ -3895,7 +3925,7 @@ Supports heap sizes from 8MB to 16TB. .RS .RE .TP -.B \f[CB]\-XX:ZAllocationSpikeTolerance\f[R]=\f[I]factor\f[R] +.B \f[CB]\-XX:ZAllocationSpikeTolerance=\f[R]\f[I]factor\f[R] Sets the allocation spike tolerance for ZGC. By default, this option is set to 2.0. This factor describes the level of allocation spikes to expect. @@ -3904,14 +3934,14 @@ be expected to triple at any time. .RS .RE .TP -.B \f[CB]\-XX:ZCollectionInterval\f[R]=\f[I]seconds\f[R] +.B \f[CB]\-XX:ZCollectionInterval=\f[R]\f[I]seconds\f[R] Sets the maximum interval (in seconds) between two GC cycles when using ZGC. By default, this option is set to 0 (disabled). .RS .RE .TP -.B \f[CB]\-XX:ZFragmentationLimit\f[R]=\f[I]percent\f[R] +.B \f[CB]\-XX:ZFragmentationLimit=\f[R]\f[I]percent\f[R] Sets the maximum acceptable heap fragmentation (in percent) for ZGC. By default, this option is set to 25. Using a lower value will cause the heap to be compacted more @@ -3939,7 +3969,7 @@ JVM, and make that memory available for other processes to use. .RS .RE .TP -.B \f[CB]\-XX:ZUncommitDelay\f[R]=\f[I]seconds\f[R] +.B \f[CB]\-XX:ZUncommitDelay=\f[R]\f[I]seconds\f[R] Sets the amount of time (in seconds) that heap memory must have been unused before being uncommitted. By default, this option is set to 300 (5 minutes). @@ -4037,6 +4067,14 @@ This option was deprecated in JDK 16 by \f[B]JEP 396\f[R] \f[B]JEP 403\f[R] [https://openjdk.java.net/jeps/403]. .RS .RE +.SH REMOVED JAVA OPTIONS +.PP +These \f[CB]java\f[R] options have been removed in JDK 19 and using them +results in an error of: +.RS +.PP +\f[CB]Unrecognized\ VM\ option\f[R] \f[I]option\-name\f[R] +.RE .TP .B \f[CB]\-XX:+UseBiasedLocking\f[R] Enables the use of biased locking. @@ -4044,16 +4082,14 @@ Some applications with significant amounts of uncontended synchronization may attain significant speedups with this flag enabled, but applications with certain patterns of locking may see slowdowns. .RS -.PP -By default, this option is disabled. .RE -.SH REMOVED JAVA OPTIONS -.PP -No documented \f[CB]java\f[R] options have been removed in JDK 18. .PP For the lists and descriptions of options removed in previous releases see the \f[I]Removed Java Options\f[R] section in: .IP \[bu] 2 +\f[B]The \f[BC]java\f[B] Command, Release 18\f[R] +[https://docs.oracle.com/en/java/javase/18/docs/specs/man/java.html] +.IP \[bu] 2 \f[B]The \f[BC]java\f[B] Command, Release 17\f[R] [https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html] .IP \[bu] 2 @@ -4231,7 +4267,7 @@ In the argument file, .nf \f[CB] \-cp\ "/lib/cool\\ -\\app/jars??? +\\app/jars" \f[R] .fi .PP @@ -5222,293 +5258,83 @@ who\[aq]s running the application, because administrators by default don\[aq]t have the privilege to lock pages in memory. .SH APPLICATION CLASS DATA SHARING .PP -Application Class Data Sharing (AppCDS) extends class data sharing (CDS) -to enable application classes to be placed in a shared archive. +Application Class Data Sharing (AppCDS) stores classes used by your +applications in an archive file. +Since these classes are stored in a format that can be loaded very +quickly (compared to classes stored in a JAR file), AppCDS can improve +the start\-up time of your applications. +In addition, AppCDS can reduce the runtime memory footprint by sharing +parts of these classes across multiple processes. .PP -In addition to the core library classes, AppCDS supports \f[B]Class Data -Sharing\f[R] -[https://docs.oracle.com/en/java/javase/12/vm/class\-data\-sharing.html#GUID\-7EAA3411\-8CF0\-4D19\-BD05\-DF5E1780AA91] -from the following locations: -.IP \[bu] 2 -Platform classes from the runtime image -.IP \[bu] 2 -Application classes from the runtime image -.IP \[bu] 2 -Application classes from the class path -.IP \[bu] 2 -Application classes from the module path +Classes in the CDS archive are stored in an optimized format that\[aq]s +about 2 to 5 times larger than classes stored in JAR files or the JDK +runtime image. +Therefore, it\[aq]s a good idea to archive only those classes that are +actually used by your application. +These usually are just a small portion of all available classes. +For example, your application may use only a few APIs provided by a +large library. +.SS Using CDS Archives .PP -Archiving application classes provides better start up time at runtime. -When running multiple JVM processes, AppCDS also reduces the runtime -footprint with memory sharing for read\-only metadata. +By default, in most JDK distributions, unless \f[CB]\-Xshare:off\f[R] is +specified, the JVM starts up with a default CDS archive, which is +usually located in \f[CB]JAVA_HOME/lib/server/classes.jsa\f[R] (or +\f[CB]JAVA_HOME\\bin\\server\\classes.jsa\f[R] on Windows). +This archive contains about 1300 core library classes that are used by +most applications. .PP -CDS/AppCDS supports archiving classes from JAR files only. +To use CDS for the exact set of classes used by your application, you +can use the \f[CB]\-XX:SharedArchiveFile\f[R] option, which has the +general form: +.RS .PP -Prior to JDK 11, a non\-empty directory was reported as a fatal error in -the following conditions: -.IP \[bu] 2 -For base CDS, a non\-empty directory cannot exist in the -\f[CB]\-Xbootclasspath/a\f[R] path +\f[CB]\-XX:SharedArchiveFile=:\f[R] +.RE .IP \[bu] 2 -With \f[CB]\-XX:+UseAppCDS\f[R], a non\-empty directory could not exist in -the \f[CB]\-Xbootclasspath/a\f[R] path, class path, and module path. -.PP -In JDK 11 and later, \f[CB]\-XX:+UseAppCDS\f[R] is obsolete and the -behavior for a non\-empty directory is based on the class types in the -classlist. -A non\-empty directory is reported as a fatal error in the following -conditions: +The \f[CB]\f[R] overrides the default CDS archive. .IP \[bu] 2 -If application classes or platform classes are not loaded, dump time -only reports an error if a non\-empty directory exists in -\f[CB]\-Xbootclasspath/a\f[R] path +The \f[CB]\f[R] provides additional classes that can be +loaded on top of those in the \f[CB]\f[R]. .IP \[bu] 2 -If application classes or platform classes are loaded, dump time reports -an error for a non\-empty directory that exists in -\f[CB]\-Xbootclasspath/a\f[R] path, class path, or module path -.PP -In JDK 11 and later, using -\f[CB]\-XX:DumpLoadedClassList=\f[R]\f[I]class_list_file\f[R] results a -generated classlist with all classes (both system library classes and -application classes) included. -You no longer have to specify \f[CB]\-XX:+UseAppCDS\f[R] with -\f[CB]\-XX:DumpLoadedClassList\f[R] to produce a complete class list. +On Windows, the above path delimiter \f[CB]:\f[R] should be replaced with +\f[CB];\f[R] .PP -In JDK 11 and later, because \f[CB]UseAppCDS\f[R] is obsolete, -\f[CB]SharedArchiveFile\f[R] becomes a product flag by default. -Specifying \f[CB]+UnlockDiagnosticVMOptions\f[R] for -\f[CB]SharedArchiveFile\f[R] is no longer needed in any configuration. +(The names "static" and "dyanmic" are used for historical reasons. +The only significance is that the "static" archive is loaded first and +the "dynamic" archive is loaded second). .PP -Class Data Sharing (CDS)/AppCDS does not support archiving array classes -in a class list. -When an array in the class list is encountered, CDS dump time gives the -explicit error message: +The JVM can use up to two archives. +To use only a single \f[CB]\f[R], you can omit the +\f[CB]\f[R] portion: .RS .PP -\f[CB]Preload\ Warning:\ Cannot\ find\f[R] \f[I]array_name\f[R] +\f[CB]\-XX:SharedArchiveFile=\f[R] .RE .PP -Although an array in the class list is not allowed, some array classes -can still be created at CDS/AppCDS dump time. -Those arrays are created during the execution of the Java code used by -the Java class loaders (\f[CB]PlatformClassLoader\f[R] and the system -class loader) to load classes at dump time. -The created arrays are archived with the rest of the loaded classes. -.SS Extending Class Data Sharing to Support the Module Path -.PP -In JDK 11, Class Data Sharing (CDS) has been improved to support -archiving classes from the module path. -.IP \[bu] 2 -To create a CDS archive using the \f[CB]\-\-module\-path\f[R] VM option, -use the following command line syntax: -.RS 2 -.RS -.PP -\f[CB]java\ \-Xshare:dump\ \-XX:SharedClassListFile=\f[R]\f[I]class_list_file\f[R] -\f[CB]\-XX:SharedArchiveFile=\f[R]\f[I]shared_archive_file\f[R] -\f[CB]\-\-module\-path=\f[R]\f[I]path_to_modular_jar\f[R] \f[CB]\-m\f[R] -\f[I]module_name\f[R] -.RE -.RE -.IP \[bu] 2 -To run with a CDS archive using the \f[CB]\-\-module\-path\f[R] VM option, -use the following the command line syntax: -.RS 2 +For convenience, the \f[CB]\f[R] records the location of +the \f[CB]\f[R]. +Therefore, you can omit the \f[CB]\f[R] by saying only: .RS .PP -\f[CB]java\ \-XX:SharedArchiveFile=\f[R]\f[I]shared_archive_file\f[R] -\f[CB]\-\-module\-path=\f[R]\f[I]path_to_modular_jar\f[R] \f[CB]\-m\f[R] -\f[I]module_name\f[R] -.RE +\f[CB]\-XX:SharedArchiveFile=\f[R] .RE +.SS Creating CDS Archives .PP -The following table describes how the VM options related to module paths -can be used along with the \f[CB]\-Xshare\f[R] option. -.PP -.TS -tab(@); -l l l. -T{ -Option -T}@T{ -\-Xshare:dump -T}@T{ -\-Xshare:{on,auto} -T} -_ -T{ -\f[CB]\-\-module\-path\f[R][1] \f[I]mp\f[R] -T}@T{ -Allowed -T}@T{ -Allowed[2] -T} -T{ -\f[CB]\-\-module\f[R] -T}@T{ -Allowed -T}@T{ -Allowed -T} -T{ -\f[CB]\-\-add\-module\f[R] -T}@T{ -Allowed -T}@T{ -Allowed -T} -T{ -\f[CB]\-\-upgrade\-module\-path\f[R][3] -T}@T{ -Disallowed (exits if specified) -T}@T{ -Allowed (disables CDS) -T} -T{ -\f[CB]\-\-patch\-module\f[R][4] -T}@T{ -Disallowed (exits if specified) -T}@T{ -Allowed (disables CDS) -T} -T{ -\f[CB]\-\-limit\-modules\f[R][5] -T}@T{ -Disallowed (exits if specified) -T}@T{ -Allowed (disables CDS) -T} -.TE -.PP -[1] Although there are two ways of specifying a module in a -\f[CB]\-\-module\-path\f[R], that is, modular JAR or exploded module, only -modular JARs are supported. -.PP -[2] Different \f[I]mp\f[R] can be specified during dump time versus run -time. -If an archived class K was loaded from \f[CB]mp1.jar\f[R] at dump time, -but changes in \f[I]mp\f[R] cause it to be available from a different -\f[CB]mp2.jar\f[R] at run time, then the archived version of K will be -disregarded at run time; K will be loaded dynamically. -.PP -[3] Currently, only two system modules are upgradeable -(\f[CB]java.compiler\f[R] and \f[CB]jdk.internal.vm.compiler\f[R]). -However, these modules are seldom upgraded in production software. -.PP -[4] As documented in JEP 261, using \f[CB]\-\-patch\-module\f[R] is -strongly discouraged for production use. -.PP -[5] \f[CB]\-\-limit\-modules\f[R] is intended for testing purposes. -It is seldom used in production software. -.PP -If \f[CB]\-\-upgrade\-module\-path\f[R], \f[CB]\-\-patch\-module\f[R], or -\f[CB]\-\-limit\-modules\f[R] is specified at dump time, an error will be -printed and the JVM will exit. -For example, if the \f[CB]\-\-limit\-modules\f[R] option is specified at -dump time, the user will see the following error: -.IP -.nf -\f[CB] -Error\ occurred\ during\ initialization\ of\ VM -Cannot\ use\ the\ following\ option\ when\ dumping\ the\ shared\ archive:\ \-\-limit\-modules -\f[R] -.fi -.PP -If \f[CB]\-\-upgrade\-module\-path\f[R], \f[CB]\-\-patch\-module\f[R], or -\f[CB]\-\-limit\-modules\f[R] is specified at run time, a warning message -will be printed indicating that CDS is disabled. -For example, if the \f[CB]\-\-limit\-modules\f[R] options is specified at -run time, the user will see the following warning: -.IP -.nf -\f[CB] -Java\ HotSpot(TM)\ 64\-Bit\ Server\ VM\ warning:\ CDS\ is\ disabled\ when\ the\ \-\-limit\-modules\ option\ is\ specified. -\f[R] -.fi -.PP -Several other noteworthy things include: -.IP \[bu] 2 -Any valid combinations of \f[CB]\-cp\f[R] and \f[CB]\-\-module\-path\f[R] -are supported. -.IP \[bu] 2 -A non\-empty directory in the module path causes a fatal error. -The user will see the following error messages: -.RS 2 -.IP -.nf -\f[CB] -Error:\ non\-empty\ directory\ \ Hint:\ enable\ \-Xlog:class+path=info\ to\ diagnose\ the\ failure\ Error\ occurred\ during\ initialization\ of\ VM\ Cannot\ have\ non\-empty\ directory\ in\ paths -\f[R] -.fi -.RE +CDS archives can be created with several methods: .IP \[bu] 2 -Unlike the class path, there\[aq]s no restriction that the module path -at dump time must be equal to or be a prefix of the module path at run -time. +\f[CB]\-Xshare:dump\f[R] .IP \[bu] 2 -The archive is invalidated if an existing JAR in the module path is -updated after archive generation. +\f[CB]\-XX:ArchiveClassesAtExit\f[R] .IP \[bu] 2 -Removing a JAR from the module path does not invalidate the shared -archive. -Archived classes from the removed JAR are not used at runtime. -.SS Dynamic CDS archive -.PP -Dynamic CDS archive extends AppCDS to allow archiving of classes when a -Java application exits. -It improves the usability of AppCDS by eliminating the trial run step -for creating a class list for each application. -The archived classes include all loaded application classes and library -classes that are not present in the default CDS archive which is -included in the JDK. -.PP -A base archive is required when creating a dynamic archive. -If the base archive is not specified, the default CDS archive is used as -the base archive. +\f[CB]jcmd\ VM.cds\f[R] .PP -To create a dynamic CDS archive with the default CDS archive as the base -archive, just add the -\f[CB]\-XX:ArchiveClassesAtExit=\f[R] option to the -command line for running the Java application. +One common operation in all these methods is a "trial run", where you +run the application once to determine the classes that should be stored +in the archive. +.SS Creating a Static CDS Archive File with \-Xshare:dump .PP -If the default CDS archive does not exist, the VM will exit with the -following error: -.IP -.nf -\f[CB] -ArchiveClassesAtExit\ not\ supported\ when\ base\ CDS\ archive\ is\ not\ loaded -\f[R] -.fi -.PP -To run the Java application using a dynamic CDS archive, just add the -\f[CB]\-XX:SharedArchiveFile=\f[R] option to the command -line for running the Java application. -.PP -The base archive is not required to be specified in the command line. -The base archive information, including its name and full path, will be -retrieved from the dynamic archive header. -Note that the user could also use the \f[CB]\-XX:SharedArchiveFile\f[R] -option for specifying a regular AppCDS archive. -Therefore, the specified archive in the \f[CB]\-XX:SharedArchiveFile\f[R] -option could be either a regular or dynamic archive. -During VM start up the specified archive header will be read. -If \f[CB]\-XX:SharedArchiveFile\f[R] refers to a regular archive, then the -behavior will be unchanged. -If \f[CB]\-XX:SharedArchiveFile\f[R] refers to a dynamic archive, the VM -will retrieve the base archive location from the dynamic archive. -If the dynamic archive was created with the default CDS archive, then -the current default CDS archive will be used, and will be found relative -to the current run time environment. -.PP -Please refer to \f[B]JDK\-8221706\f[R] -[https://bugs.openjdk.java.net/browse/JDK\-8221706] for details on error -checking during dynamic CDS archive dump time and run time. -.SS Creating a Shared Archive File and Using It to Run an Application -.SS AppCDS archive -.PP -The following steps create a shared archive file that contains all the -classes used by the \f[CB]test.Hello\f[R] application. -The last step runs the application with the shared archive file. +The following steps create a static CDS archive file that contains all +the classes used by the \f[CB]test.Hello\f[R] application. .IP "1." 3 Create a list of all classes used by the \f[CB]test.Hello\f[R] application. @@ -5520,23 +5346,20 @@ contains a list of all classes used by this application: \f[CB]java\ \-Xshare:off\ \-XX:DumpLoadedClassList=hello.classlist\ \-cp\ hello.jar\ test.Hello\f[R] .RE .PP -Note that the classpath specified by the \f[CB]\-cp\f[R] parameter must -contain only JAR files. +The classpath specified by the \f[CB]\-cp\f[R] parameter must contain only +JAR files. .RE .IP "2." 3 -Create a shared archive, named \f[CB]hello.jsa\f[R], that contains all the +Create a static archive, named \f[CB]hello.jsa\f[R], that contains all the classes in \f[CB]hello.classlist\f[R]: .RS 4 .RS .PP \f[CB]java\ \-Xshare:dump\ \-XX:SharedArchiveFile=hello.jsa\ \-XX:SharedClassListFile=hello.classlist\ \-cp\ hello.jar\f[R] .RE -.PP -Note that the classpath used at archive creation time must be the same -as (or a prefix of) the classpath used at run time. .RE .IP "3." 3 -Run the application \f[CB]test.Hello\f[R] with the shared archive +Run the application \f[CB]test.Hello\f[R] with the archive \f[CB]hello.jsa\f[R]: .RS 4 .RS @@ -5550,23 +5373,27 @@ using the class contained in the \f[CB]hello.jsa\f[R] shared archive: .RS 4 .RS .PP -\f[CB]java\ \-XX:SharedArchiveFile=hello.jsa\ \-cp\ hello.jar\ \-verbose:class\ test.Hello\f[R] +\f[CB]java\ \-XX:SharedArchiveFile=hello.jsa\ \-cp\ hello.jar\ \-Xlog:class+load\ test.Hello\f[R] .RE .PP The output of this command should contain the following text: -.IP -.nf -\f[CB] -Loaded\ test.Hello\ from\ shared\ objects\ file\ by\ sun/misc/Launcher$AppClassLoader -\f[R] -.fi +.RS +.PP +\f[CB][info][class,load]\ test.Hello\ source:\ shared\ objects\ file\f[R] +.RE .RE -.SS Dynamic CDS archive +.SS Creating a Dynamic CDS Archive File with \-XX:SharedArchiveFile +.PP +Advantages of dynamic CDS archives are: +.IP \[bu] 2 +They usually use less disk space, since they don\[aq]t need to store the +classes that are already in the static archive. +.IP \[bu] 2 +They are created with one fewer step than the comparable static archive. .PP The following steps create a dynamic CDS archive file that contains the -classes used by the \f[CB]test.Hello\f[R] application and are not included -in the default CDS archive. -The second step runs the application with the dynamic CDS archive. +classes that are used by the \f[CB]test.Hello\f[R] application, excluding +those that are already in the default CDS archive. .IP "1." 3 Create a dynamic CDS archive, named \f[CB]hello.jsa\f[R], that contains all the classes in \f[CB]hello.jar\f[R] loaded by the application @@ -5576,9 +5403,6 @@ all the classes in \f[CB]hello.jar\f[R] loaded by the application .PP \f[CB]java\ \-XX:ArchiveClassesAtExit=hello.jsa\ \-cp\ hello.jar\ Hello\f[R] .RE -.PP -Note that the classpath used at archive creation time must be the same -as (or a prefix of) the classpath used at run time. .RE .IP "2." 3 Run the application \f[CB]test.Hello\f[R] with the shared archive @@ -5594,218 +5418,87 @@ Run the application \f[CB]test.Hello\f[R] with the shared archive the \f[CB]test.Hello\f[R] application is using the class contained in the \f[CB]hello.jsa\f[R] shared archive. .PP -To automate the above steps 1 and 2, one can write a script such as the -following: -.IP -.nf -\f[CB] -\ \ \ \ ARCHIVE=hello.jsa -\ \ \ \ if\ test\ \-f\ $ARCHIVE;\ then -\ \ \ \ \ \ \ \ FLAG="\-XX:SharedArchiveFile=$ARCHIVE" -\ \ \ \ else -\ \ \ \ \ \ \ \ FLAG="\-XX:ArchiveClassesAtExit=$ARCHIVE" -\ \ \ \ fi -\ \ \ \ $JAVA_HOME/bin/java\ \-cp\ hello.jar\ $FLAG\ test.Hello -\f[R] -.fi -.PP -Like an AppCDS archive, the archive needs to be re\-generated if the -Java version has changed. -The above script could be adjusted to account for the Java version as -follows: -.IP -.nf -\f[CB] -\ \ \ \ ARCHIVE=hello.jsa -\ \ \ \ VERSION=foo.version -\ \ \ \ if\ test\ \-f\ $ARCHIVE\ \-a\ \-f\ $VERSION\ &&\ cmp\ \-s\ $VERSION\ $JAVA_HOME/release;\ then -\ \ \ \ \ \ \ \ FLAG="\-XX:SharedArchiveFile=$ARCHIVE" -\ \ \ \ else -\ \ \ \ \ \ \ \ FLAG="\-XX:ArchiveClassesAtExit=$ARCHIVE" -\ \ \ \ \ \ \ \ cp\ \-f\ $JAVA_HOME/release\ $VERSION -\ \ \ \ fi -\ \ \ \ $JAVA_HOME/bin/java\ \-cp\ hello.jar\ $FLAG\ test.Hello -\f[R] -.fi -.PP -Currently, we don\[aq]t support concurrent dumping operations to the -same CDS archive. -Care should be taken to avoid multiple writers to the same CDS archive. -.PP -The user could also create a dynamic CDS archive with a specific base -archive, e.g. -named as \f[CB]base.jsa\f[R] as follows: +It\[aq]s also possible to create a dynamic CDS archive with a +non\-default static CDS archive. +E.g., .RS .PP \f[CB]java\ \-XX:SharedArchiveFile=base.jsa\ \-XX:ArchiveClassesAtExit=hello.jsa\ \-cp\ hello.jar\ Hello\f[R] .RE .PP -To run the application using the dynamic CDS archive \f[CB]hello.jsa\f[R] -and a specific base CDS archive \f[CB]base.jsa\f[R]: +To run the application using this dynamic CDS archive: .RS .PP \f[CB]java\ \-XX:SharedArchiveFile=base.jsa:hello.jsa\ \-cp\ hello.jar\ Hello\f[R] .RE .PP -Note that on Windows, the above path delimiter \f[CB]:\f[R] should be -replaced with \f[CB];\f[R]. +(On Windows, the above path delimiter \f[CB]:\f[R] should be replaced with +\f[CB];\f[R]) .PP -The above command for specifying a base archive is useful if the base -archive used for creating the dynamic archive has been moved. -Normally, just specifying the dynamic archive should be sufficient since -the base archive info can be retrieved from the dynamic archive header. -.SS Sharing a Shared Archive Across Multiple Application Processes -.PP -You can share the same archive file across multiple applications -processes. -This reduces memory usage because the archive is memory\-mapped into the -address space of the processes. -The operating system automatically shares the read\-only pages across -these processes. -.PP -The following steps demonstrate how to create a common archive that can -be shared by different applications. -Classes from \f[CB]common.jar\f[R], \f[CB]hello.jar\f[R] and \f[CB]hi.jar\f[R] -are archived in the \f[CB]common.jsa\f[R] because they are all in the -classpath during the archiving step (step 3). -.PP -To include classes from \f[CB]hello.jar\f[R] and \f[CB]hi.jar\f[R], the -\f[CB]\&.jar\f[R] files must be added to the classpath specified by the -\f[CB]\-cp\f[R] parameter. -.IP "1." 3 -Create a list of all classes used by the \f[CB]Hello\f[R] application and -another list for the \f[CB]Hi\f[R] application: -.RS 4 -.RS -.PP -\f[CB]java\ \-XX:DumpLoadedClassList=hello.classlist\ \-cp\ common.jar:hello.jar\ Hello\f[R] -.RE -.RS -.PP -\f[CB]java\ \-XX:DumpLoadedClassList=hi.classlist\ \-cp\ common.jar:hi.jar\ Hi\f[R] -.RE -.RE -.IP "2." 3 -Create a single list of classes used by all the applications that will -share the shared archive file. -.RS 4 -.PP -\f[B]Linux and macOS\f[R] The following commands combine the files -\f[CB]hello.classlist\f[R] and \f[CB]hi.classlist\f[R] into one file, -\f[CB]common.classlist\f[R]: -.RS -.PP -\f[CB]cat\ hello.classlist\ hi.classlist\ >\ common.classlist\f[R] -.RE -.PP -\f[B]Windows\f[R] The following commands combine the files -\f[CB]hello.classlist\f[R] and \f[CB]hi.classlist\f[R] into one file, -\f[CB]common.classlist\f[R]: -.RS -.PP -\f[CB]type\ hello.classlist\ hi.classlist\ >\ common.classlist\f[R] -.RE -.RE -.IP "3." 3 -Create a shared archive named \f[CB]common.jsa\f[R] that contains all the -classes in \f[CB]common.classlist\f[R]: -.RS 4 +As mention above, the name of the static archive can be skipped: .RS .PP -\f[CB]java\ \-Xshare:dump\ \-XX:SharedArchiveFile=common.jsa\ \-XX:SharedClassListFile=common.classlist\ \-cp\ common.jar:hello.jar:hi.jar\f[R] +\f[CB]java\ \-XX:SharedArchiveFile=hello.jsa\ \-cp\ hello.jar\ Hello\f[R] .RE +.SS Creating CDS Archive Files with jcmd .PP -The classpath parameter used is the common class path prefix shared by -the \f[CB]Hello\f[R] and \f[CB]Hi\f[R] applications. -.RE -.IP "4." 3 -Run the \f[CB]Hello\f[R] and \f[CB]Hi\f[R] applications with the same shared -archive: -.RS 4 -.RS +The previous two sections require you to modify the application\[aq]s +start\-up script in order to create a CDS archive. +Sometimes this could be difficult, for example, if the application\[aq]s +class path is set up by complex routines. .PP -\f[CB]java\ \-XX:SharedArchiveFile=common.jsa\ \-cp\ common.jar:hello.jar:hi.jar\ Hello\f[R] -.RE +The \f[CB]jcmd\ VM.cds\f[R] command provides a less intrusive way for +creating a CDS archive by connecting to a running JVM process. +You can create either a static: .RS .PP -\f[CB]java\ \-XX:SharedArchiveFile=common.jsa\ \-cp\ common.jar:hello.jar:hi.jar\ Hi\f[R] -.RE +\f[CB]jcmd\ \ VM.cds\ static_dump\ my_static_archive.jsa\f[R] .RE -.SS Specifying Additional Shared Data Added to an Archive File .PP -The \f[CB]SharedArchiveConfigFile\f[R] option is used to specify -additional shared data to add to the archive file. +or a dynamic archive: .RS .PP -\f[CB]\-XX:SharedArchiveConfigFile=\f[R]\f[I]shared_config_file\f[R] +\f[CB]jcmd\ \ VM.cds\ dynamic_dump\ my_dynamic_archive.jsa\f[R] .RE .PP -JDK 9 and later supports adding both symbols and string objects to an -archive for memory sharing when you have multiple JVM processes running -on the same host. -An example of this is having multiple JVM processes that use the same -set of Java EE classes. -When these common classes are loaded and used, new symbols and strings -may be created and added to the JVM\[aq]s internal "symbol" and "string" -tables. -At runtime, the symbols or string objects mapped from the archive file -can be shared across multiple JVM processes, resulting in a reduction of -overall memory usage. -In addition, archiving strings also provides added performance benefits -in both startup time and runtime execution. -.PP -In JDK 10 and later, CONSTANT_String entries in archived classes are -resolved to interned String objects at dump time, and all interned -String objects are archived. -However, even though all CONSTANT_String literals in all archived -classes are resolved, it might still beneficial to add additional -strings that are not string literals in class files, but are likely to -be used by your application at run time. -.PP -Symbol data should be generated by the \f[CB]jcmd\f[R] tool attaching to a -running JVM process. -See \f[B]jcmd\f[R]. -.PP -The following is an example of the symbol dumping command in -\f[CB]jcmd\f[R]: -.RS -.PP -\f[CB]jcmd\f[R] \f[I]pid\f[R] \f[CB]VM.symboltable\ \-verbose\f[R] -.RE +To use the resulting archive file in a subsequent run of the application +without modifying the application\[aq]s start\-up script, you can use +the following technique: .RS .PP -\f[B]Note:\f[R] The first line (process ID) and the second line -(\f[CB]\@VERSION\ ...\f[R]) of this \f[CB]jcmd\f[R] output should be -excluded from the configuration file. +\f[CB]env\ JAVA_TOOL_OPTIONS=\-XX:SharedArchiveFile=my_static_archive.jsa\ bash\ app_start.sh\f[R] .RE -.SS Example of a Configuration File .PP -The following is an example of a configuration file: -.IP -.nf -\f[CB] -VERSION:\ 1.0 -\@SECTION:\ Symbol -10\ \-1:\ linkMethod -\f[R] -.fi -.PP -In the configuration file example, the \f[CB]\@SECTION:\ Symbol\f[R] entry -uses the following format: +Note: to use \f[CB]jcmd\ \ VM.cds\ dynamic_dump\f[R], the JVM process +identified by \f[CB]\f[R] must be started with +\f[CB]\-XX:+RecordDynamicDumpInfo\f[R], which can also be passed to the +application start\-up script with the same technique: .RS .PP -\f[I]length\f[R] \f[I]refcount\f[R]\f[CB]:\f[R] \f[I]symbol\f[R] +\f[CB]env\ JAVA_TOOL_OPTIONS=\-XX:+RecordDynamicDumpInfo\ bash\ app_start.sh\f[R] .RE -.PP -The \f[I]refcount\f[R] for a shared symbol is always \f[CB]\-1\f[R]. -.PP -\f[CB]\@SECTION\f[R] specifies the type of the section that follows it. -All data within the section must be the same type that\[aq]s specified -by \f[CB]\@SECTION\f[R]. -Different types of data can\[aq]t be mixed. -Multiple separated data sections for the same type specified by -different \f[CB]\@SECTION\f[R] are allowed within one -\f[CB]shared_config_file\f[R] . +.SS Restrictions on Class Path and Module Path +.IP \[bu] 2 +Neither the class path (\f[CB]\-classpath\f[R] and +\f[CB]\-Xbootclasspath/a\f[R]) nor the module path +(\f[CB]\-\-module\-path\f[R]) can contain non\-empty directories. +.IP \[bu] 2 +Only modular JAR files are supported in \f[CB]\-\-module\-path\f[R]. +Exploded modules are not supported. +.IP \[bu] 2 +The class path used at archive creation time must be the same as (or a +prefix of) the class path used at run time. +(There\[aq]s no such requirement for the module path.) +.IP \[bu] 2 +The CDS archive cannot be loaded if any JAR files in the class path or +module path are modified after the archive is generated. +.IP \[bu] 2 +If any of the VM options \f[CB]\-\-upgrade\-module\-path\f[R], +\f[CB]\-\-patch\-module\f[R] or \f[CB]\-\-limit\-modules\f[R] are specified, +CDS is disabled. +This means that the JVM will execute without loading any CDS archives. +In addition, if you try to create a CDS archive with any of these 3 +options specified, the JVM will report an error. .SH PERFORMANCE TUNING EXAMPLES .PP You can use the Java advanced runtime options to optimize the diff --git a/src/java.base/share/man/keytool.1 b/src/java.base/share/man/keytool.1 index c5777f2db8b86206d91417cf457fd6caddc09831..7d0cdf6a161cca9b5b6afae22e91bcca312589db 100644 --- a/src/java.base/share/man/keytool.1 +++ b/src/java.base/share/man/keytool.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. .\" 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,7 +22,7 @@ .\"t .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "KEYTOOL" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "KEYTOOL" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP @@ -70,6 +70,8 @@ keystore \f[CB]\-storepasswd\f[R]: Changes the store password of a keystore .IP \[bu] 2 \f[CB]\-showinfo\f[R]: Displays security\-related information +.IP \[bu] 2 +\f[CB]\-version\f[R]: Prints the program version .PP See \f[B]Commands and Options\f[R] for a description of these commands with their options. @@ -219,6 +221,10 @@ they perform. \f[B]Commands for Displaying Security\-related Information\f[R]: .IP \[bu] 2 \f[CB]\-showinfo\f[R] +.PP +\f[B]Commands for Displaying Program Version\f[R]: +.IP \[bu] 2 +\f[CB]\-version\f[R] .SH COMMANDS FOR CREATING OR ADDING DATA TO THE KEYSTORE .TP .B \f[CB]\-gencert\f[R] @@ -1314,6 +1320,10 @@ information. The \f[CB]\-tls\f[R] option displays TLS configurations, such as the list of enabled protocols and cipher suites. .RE +.SH COMMANDS FOR DISPLAYING PROGRAM VERSION +.PP +You can use \f[CB]\-version\f[R] to print the program version of +\f[CB]keytool\f[R]. .SH COMMANDS FOR DISPLAYING HELP INFORMATION .PP You can use \f[CB]\-\-help\f[R] to display a list of \f[CB]keytool\f[R] diff --git a/src/java.base/share/native/libjava/Finalizer.c b/src/java.base/share/native/libjava/Finalizer.c index d0b81f63d6e7f03290e2c680cef0ea7d5e8d73c2..063e330ac9b911670f5c3a2f0b2314685e7008e3 100644 --- a/src/java.base/share/native/libjava/Finalizer.c +++ b/src/java.base/share/native/libjava/Finalizer.c @@ -32,4 +32,7 @@ Java_java_lang_ref_Finalizer_reportComplete(JNIEnv* env, jclass cls, jobject fin JVM_ReportFinalizationComplete(env, finalizee); } - +JNIEXPORT jboolean JNICALL +Java_java_lang_ref_Finalizer_isFinalizationEnabled(JNIEnv* env, jclass cls) { + return JVM_IsFinalizationEnabled(env); +} diff --git a/src/java.base/share/native/libjimage/imageDecompressor.cpp b/src/java.base/share/native/libjimage/imageDecompressor.cpp index 5deebe350f7f562bc9c3cecd788c58c2b3337330..65bda0957b86889bff9d9f9d987f9bf257a8ef6e 100644 --- a/src/java.base/share/native/libjimage/imageDecompressor.cpp +++ b/src/java.base/share/native/libjimage/imageDecompressor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,6 +30,7 @@ */ #include "jni.h" +#include "jvm.h" #include "imageDecompressor.hpp" #include "endian.hpp" #ifdef WIN32 @@ -57,24 +58,14 @@ static ZipInflateFully_t ZipInflateFully = NULL; * @return the address of the entry point or NULL */ static void* findEntry(const char* name) { - void *addr = NULL; -#ifdef WIN32 - HMODULE handle = GetModuleHandle("zip.dll"); - if (handle == NULL) { - handle = LoadLibrary("zip.dll"); - } - if (handle == NULL) { - return NULL; - } - addr = (void*) GetProcAddress(handle, name); - return addr; -#else - addr = dlopen(JNI_LIB_PREFIX "zip" JNI_LIB_SUFFIX, RTLD_GLOBAL|RTLD_LAZY); + void *addr = JVM_LoadZipLibrary(); if (addr == NULL) { return NULL; } - addr = dlsym(addr, name); - return addr; +#ifdef WIN32 + return (void*) GetProcAddress(static_cast(addr), name); +#else + return dlsym(addr, name); #endif } diff --git a/src/java.base/unix/classes/java/lang/ProcessImpl.java b/src/java.base/unix/classes/java/lang/ProcessImpl.java index 2bf36f8f136794af4030e12c64026ab217696959..0a3f4e34783fefa183b32841878ea1150c9599aa 100644 --- a/src/java.base/unix/classes/java/lang/ProcessImpl.java +++ b/src/java.base/unix/classes/java/lang/ProcessImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,6 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.util.Properties; import jdk.internal.access.JavaIOFileDescriptorAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.util.StaticProperty; @@ -641,109 +640,6 @@ final class ProcessImpl extends Process { } } - // A FileInputStream that supports the deferment of the actual close - // operation until the last pending I/O operation on the stream has - // finished. This is required on Solaris because we must close the stdin - // and stdout streams in the destroy method in order to reclaim the - // underlying file descriptors. Doing so, however, causes any thread - // currently blocked in a read on one of those streams to receive an - // IOException("Bad file number"), which is incompatible with historical - // behavior. By deferring the close we allow any pending reads to see -1 - // (EOF) as they did before. - // - private static class DeferredCloseInputStream extends PipeInputStream { - DeferredCloseInputStream(FileDescriptor fd) { - super(fd); - } - - private Object lock = new Object(); // For the following fields - private boolean closePending = false; - private int useCount = 0; - private InputStream streamToClose; - - private void raise() { - synchronized (lock) { - useCount++; - } - } - - private void lower() throws IOException { - synchronized (lock) { - useCount--; - if (useCount == 0 && closePending) { - streamToClose.close(); - } - } - } - - // stc is the actual stream to be closed; it might be this object, or - // it might be an upstream object for which this object is downstream. - // - private void closeDeferred(InputStream stc) throws IOException { - synchronized (lock) { - if (useCount == 0) { - stc.close(); - } else { - closePending = true; - streamToClose = stc; - } - } - } - - public void close() throws IOException { - synchronized (lock) { - useCount = 0; - closePending = false; - } - super.close(); - } - - public int read() throws IOException { - raise(); - try { - return super.read(); - } finally { - lower(); - } - } - - public int read(byte[] b) throws IOException { - raise(); - try { - return super.read(b); - } finally { - lower(); - } - } - - public int read(byte[] b, int off, int len) throws IOException { - raise(); - try { - return super.read(b, off, len); - } finally { - lower(); - } - } - - public long skip(long n) throws IOException { - raise(); - try { - return super.skip(n); - } finally { - lower(); - } - } - - public int available() throws IOException { - raise(); - try { - return super.available(); - } finally { - lower(); - } - } - } - /** * A buffered input stream for a subprocess pipe file descriptor * that allows the underlying file descriptor to be reclaimed when @@ -757,7 +653,7 @@ final class ProcessImpl extends Process { * will block if another thread is at the same time blocked in a file * operation (e.g. 'read()') on the same file descriptor. We therefore * combine 'ProcessPipeInputStream' approach used on Linux and Bsd - * with the DeferredCloseInputStream approach used on Solaris. This means + * with the deferring 'close' of InputStream. This means * that every potentially blocking operation on the file descriptor * increments a counter before it is executed and decrements it once it * finishes. The 'close()' operation will only be executed if there are diff --git a/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java b/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java index c082bb6f02c842071830f6a6ca25d7b1d973d057..f9530cf779768675d08f4edca6ca93b2419e4a28 100644 --- a/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java +++ b/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintStream; -import sun.net.sdp.SdpSupport; import sun.security.action.GetPropertyAction; /** @@ -192,8 +191,7 @@ public class SdpProvider extends NetHooks.Provider { private static List loadRulesFromFile(String file) throws IOException { - Scanner scanner = new Scanner(new File(file)); - try { + try (Scanner scanner = new Scanner(new File(file))) { List result = new ArrayList<>(); while (scanner.hasNextLine()) { String line = scanner.nextLine().trim(); @@ -279,8 +277,6 @@ public class SdpProvider extends NetHooks.Provider { } } return result; - } finally { - scanner.close(); } } diff --git a/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java b/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java index 5892517e938e2332fbe5778c5ab75962ffa562b1..207e95d27f8fd01e1e5b40d723036d4ed71295b5 100644 --- a/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java +++ b/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,10 @@ package sun.net.www.protocol.file; -import java.net.InetAddress; import java.net.URLConnection; import java.net.URL; import java.net.Proxy; -import java.net.MalformedURLException; import java.net.URLStreamHandler; -import java.io.InputStream; import java.io.IOException; import sun.net.www.ParseUtil; import java.io.File; @@ -42,14 +39,6 @@ import java.io.File; */ public class Handler extends URLStreamHandler { - private String getHost(URL url) { - String host = url.getHost(); - if (host == null) - host = ""; - return host; - } - - protected void parseURL(URL u, String spec, int start, int limit) { /* * Ugly backwards compatibility. Flip any file separator @@ -61,18 +50,18 @@ public class Handler extends URLStreamHandler { * rather than forcing this to be fixed in the caller of the URL * class where it belongs. Since backslash is an "unwise" * character that would normally be encoded if literally intended - * as a non-seperator character the damage of veering away from the + * as a non-separator character the damage of veering away from the * specification is presumably limited. */ super.parseURL(u, spec.replace(File.separatorChar, '/'), start, limit); } - public synchronized URLConnection openConnection(URL u) + public URLConnection openConnection(URL u) throws IOException { return openConnection(u, null); } - public synchronized URLConnection openConnection(URL u, Proxy p) + public URLConnection openConnection(URL u, Proxy p) throws IOException { String host = u.getHost(); if (host == null || host.isEmpty() || host.equals("~") || diff --git a/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java b/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java index 5475eca7c2eb44480d199fee2e2f370a2d7b111e..18ccda6e7c1d96a02839d3edb61b4d97222ff6b0 100644 --- a/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java +++ b/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,10 @@ package sun.net.www.protocol.file; -import java.net.InetAddress; import java.net.URLConnection; import java.net.URL; import java.net.Proxy; -import java.net.MalformedURLException; import java.net.URLStreamHandler; -import java.io.InputStream; import java.io.IOException; import sun.net.www.ParseUtil; import java.io.File; @@ -42,14 +39,6 @@ import java.io.File; */ public class Handler extends URLStreamHandler { - private String getHost(URL url) { - String host = url.getHost(); - if (host == null) - host = ""; - return host; - } - - protected void parseURL(URL u, String spec, int start, int limit) { /* * Ugly backwards compatibility. Flip any file separator @@ -61,18 +50,18 @@ public class Handler extends URLStreamHandler { * rather than forcing this to be fixed in the caller of the URL * class where it belongs. Since backslash is an "unwise" * character that would normally be encoded if literally intended - * as a non-seperator character the damage of veering away from the + * as a non-separator character the damage of veering away from the * specification is presumably limited. */ super.parseURL(u, spec.replace(File.separatorChar, '/'), start, limit); } - public synchronized URLConnection openConnection(URL url) + public URLConnection openConnection(URL url) throws IOException { return openConnection(url, null); } - public synchronized URLConnection openConnection(URL url, Proxy p) + public URLConnection openConnection(URL url, Proxy p) throws IOException { String path; diff --git a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java index 8b786f04d124d4c343330d2a3d3b2d619b9a4bf9..005a0a93339e29a6f8ac4cb60bceec6c6f50f5ce 100644 --- a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,9 +32,8 @@ import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; -import java.net.UnixDomainSocketAddress; -import java.net.StandardProtocolFamily; import java.net.StandardSocketOptions; +import java.net.UnixDomainSocketAddress; import java.nio.*; import java.nio.channels.*; import java.nio.file.Files; @@ -46,6 +45,7 @@ import java.security.PrivilegedActionException; import java.security.SecureRandom; import java.util.Random; +import static java.net.StandardProtocolFamily.UNIX; /** * A simple Pipe implementation based on a socket connection. @@ -69,12 +69,14 @@ class PipeImpl { private final SelectorProvider sp; + private final boolean preferUnixDomain; private IOException ioe; SourceChannelImpl source; SinkChannelImpl sink; - private Initializer(SelectorProvider sp) { + private Initializer(SelectorProvider sp, boolean preferUnixDomain) { this.sp = sp; + this.preferUnixDomain = preferUnixDomain; } @Override @@ -122,7 +124,7 @@ class PipeImpl // Bind ServerSocketChannel to a port on the loopback // address if (ssc == null || !ssc.isOpen()) { - ssc = createListener(); + ssc = createListener(preferUnixDomain); sa = ssc.getLocalAddress(); } @@ -164,9 +166,8 @@ class PipeImpl try { if (ssc != null) ssc.close(); - if (sa instanceof UnixDomainSocketAddress) { - Path path = ((UnixDomainSocketAddress) sa).getPath(); - Files.deleteIfExists(path); + if (sa instanceof UnixDomainSocketAddress uaddr) { + Files.deleteIfExists(uaddr.getPath()); } } catch (IOException e2) {} } @@ -175,22 +176,24 @@ class PipeImpl } /** - * Creates a Pipe implementation that supports buffering. + * Creates a (TCP) Pipe implementation that supports buffering. */ PipeImpl(SelectorProvider sp) throws IOException { - this(sp, true); + this(sp, true, false); } /** - * Creates Pipe implementation that supports optionally buffering. + * Creates Pipe implementation that supports optionally buffering + * and is TCP by default, but if Unix domain is supported and + * preferAfUnix is true, then Unix domain sockets are used. * - * @implNote The pipe uses Unix domain sockets where possible. It uses a - * loopback connection on older editions of Windows. When buffering is - * disabled then it sets TCP_NODELAY on the sink channel. + * @param preferAfUnix use Unix domain sockets if supported + * + * @param buffering if false set TCP_NODELAY on TCP sockets */ @SuppressWarnings("removal") - PipeImpl(SelectorProvider sp, boolean buffering) throws IOException { - Initializer initializer = new Initializer(sp); + PipeImpl(SelectorProvider sp, boolean preferAfUnix, boolean buffering) throws IOException { + Initializer initializer = new Initializer(sp, preferAfUnix); try { AccessController.doPrivileged(initializer); SinkChannelImpl sink = initializer.sink; @@ -212,18 +215,14 @@ class PipeImpl return sink; } - private static volatile boolean noUnixDomainSockets; - - private static ServerSocketChannel createListener() throws IOException { + private static ServerSocketChannel createListener(boolean preferUnixDomain) throws IOException { ServerSocketChannel listener = null; - if (!noUnixDomainSockets) { + if (preferUnixDomain && UnixDomainSockets.isSupported()) { try { - listener = ServerSocketChannel.open(StandardProtocolFamily.UNIX); - return listener.bind(null); - } catch (UnsupportedOperationException | IOException e) { - // IOException is most likely to be caused by the temporary directory - // name being too long. Possibly should log this. - noUnixDomainSockets = true; + listener = ServerSocketChannel.open(UNIX); + listener.bind(null); + return listener; + } catch (IOException | UnsupportedOperationException e) { if (listener != null) listener.close(); } diff --git a/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java b/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java index 89331e1211d5f9d222b3437310b4f6cc499f3390..8a2f26ef2b7369dc50d53fee12ef7c434712e39b 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java @@ -75,7 +75,7 @@ class WEPollSelectorImpl extends SelectorImpl { // wakeup support try { - this.pipe = new PipeImpl(sp, /*buffering*/ false); + this.pipe = new PipeImpl(sp, /* AF_UNIX */ true, /*buffering*/ false); } catch (IOException ioe) { WEPoll.freePollArray(pollArrayAddress); WEPoll.close(eph); diff --git a/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java b/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java index 1df7cb76b328e82a5bd7bfe3a56fb5cb12dcff8c..4aa565674a46010c48dd79a92ebb705a6da8725e 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java @@ -139,7 +139,7 @@ class WindowsSelectorImpl extends SelectorImpl { WindowsSelectorImpl(SelectorProvider sp) throws IOException { super(sp); pollWrapper = new PollArrayWrapper(INIT_CAP); - wakeupPipe = new PipeImpl(sp, false); + wakeupPipe = new PipeImpl(sp, /* AF_UNIX */ true, /*buffering*/ false); wakeupSourceFd = ((SelChImpl)wakeupPipe.source()).getFDVal(); wakeupSinkFd = ((SelChImpl)wakeupPipe.sink()).getFDVal(); pollWrapper.addWakeupSocket(wakeupSourceFd, 0); diff --git a/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c b/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c index 879422f096f3aabbbee1b2e88c0ce4372186d092..b7c2bcc28db60538546cb4508e8af6f715f474bc 100644 --- a/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c +++ b/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -835,7 +835,7 @@ void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jint calid, jobjec WCHAR name[BUFLEN]; const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); jstring tmp_string; - CALTYPE isGenitive; + CALTYPE isGenitive = 0; CHECK_NULL(langtag); diff --git a/src/java.base/windows/native/libnet/DefaultProxySelector.c b/src/java.base/windows/native/libnet/DefaultProxySelector.c index 74efd4ab91e3ae4000a3219e76aa43cf734ccd3f..6b91874eda1d3881159e4ac0f6cf8da3b785892f 100644 --- a/src/java.base/windows/native/libnet/DefaultProxySelector.c +++ b/src/java.base/windows/native/libnet/DefaultProxySelector.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,7 +104,6 @@ static int createProxyList(LPWSTR win_proxy, const WCHAR *pproto, list_item **he int nr_elems = 0; wchar_t *context = NULL; wchar_t *current_proxy = NULL; - BOOL error = FALSE; /* * The proxy server list contains one or more of the following strings @@ -116,7 +115,6 @@ static int createProxyList(LPWSTR win_proxy, const WCHAR *pproto, list_item **he LPWSTR pport; LPWSTR phost; int portVal = 0; - wchar_t *next_proxy = NULL; list_item *proxy = NULL; wchar_t* pos = NULL; @@ -230,16 +228,12 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env, auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; auto_proxy_options.fAutoLogonIfChallenged = TRUE; use_auto_proxy = TRUE; - } else if (ie_proxy_config.lpszAutoConfigUrl != NULL) { + } + if (ie_proxy_config.lpszAutoConfigUrl != NULL) { /* Windows uses PAC file */ auto_proxy_options.lpszAutoConfigUrl = ie_proxy_config.lpszAutoConfigUrl; - auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; + auto_proxy_options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL; use_auto_proxy = TRUE; - } else if (ie_proxy_config.lpszProxy != NULL) { - /* Windows uses manually entered proxy. */ - use_auto_proxy = FALSE; - win_bypass_proxy = ie_proxy_config.lpszProxyBypass; - win_proxy = ie_proxy_config.lpszProxy; } if (use_auto_proxy) { @@ -254,6 +248,12 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env, } } + if (!use_auto_proxy && ie_proxy_config.lpszProxy != NULL) { + /* Windows uses manually entered proxy. */ + win_bypass_proxy = ie_proxy_config.lpszProxyBypass; + win_proxy = ie_proxy_config.lpszProxy; + } + /* Check the bypass entry. */ if (NULL != win_bypass_proxy) { /* @@ -290,7 +290,6 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env, } if (win_proxy != NULL) { - wchar_t *context = NULL; int defport = 0; int nr_elems = 0; @@ -313,27 +312,28 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env, nr_elems = createProxyList(win_proxy, lpProto, &head); if (nr_elems != 0 && head != NULL) { int index = 0; + list_item *current = head; proxy_array = (*env)->NewObjectArray(env, nr_elems, proxy_class, NULL); if (proxy_array == NULL || (*env)->ExceptionCheck(env)) { goto noproxy; } - while (head != NULL && index < nr_elems) { + while (current != NULL && index < nr_elems) { jstring jhost; jobject isa; jobject proxy; - if (head->host != NULL && proxy_array != NULL) { + if (current->host != NULL && proxy_array != NULL) { /* Let's create the appropriate Proxy object then. */ - if (head->port == 0) { - head->port = defport; + if (current->port == 0) { + current->port = defport; } - jhost = (*env)->NewString(env, head->host, (jsize)wcslen(head->host)); + jhost = (*env)->NewString(env, current->host, (jsize)wcslen(current->host)); if (jhost == NULL || (*env)->ExceptionCheck(env)) { proxy_array = NULL; } isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, - head->port); + current->port); if (isa == NULL || (*env)->ExceptionCheck(env)) { proxy_array = NULL; } @@ -347,7 +347,7 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env, } index++; } - head = head->next; + current = current->next; } } } diff --git a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c index a08f3a3564fab61c22f066396aea29321a676665..340bbb9c8decc27eda10e634481b2be1bcfa007f 100644 --- a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c +++ b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,6 +69,10 @@ Java_sun_nio_ch_WindowsAsynchronousServerSocketChannelImpl_initIDs(JNIEnv* env, DWORD dwBytes; s = socket(AF_INET, SOCK_STREAM, 0); + if (s == INVALID_SOCKET && WSAGetLastError() == WSAEAFNOSUPPORT) { + /* IPv4 unavailable... try IPv6 instead */ + s = socket(AF_INET6, SOCK_STREAM, 0); + } if (s == INVALID_SOCKET) { JNU_ThrowIOExceptionWithLastError(env, "socket failed"); return; diff --git a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c index 40b8d8ba8dc13e111bf0e6a16a3aeb2f39b49f34..6b1fa64e708610de367c34bf7c349b032c9cc23d 100644 --- a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c +++ b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,6 +66,10 @@ Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_initIDs(JNIEnv* env, jclass DWORD dwBytes; s = socket(AF_INET, SOCK_STREAM, 0); + if (s == INVALID_SOCKET && WSAGetLastError() == WSAEAFNOSUPPORT) { + /* IPv4 unavailable... try IPv6 instead */ + s = socket(AF_INET6, SOCK_STREAM, 0); + } if (s == INVALID_SOCKET) { JNU_ThrowIOExceptionWithLastError(env, "socket failed"); return; diff --git a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java index 0f315a3fe17b43bbfdbf6d8c2a364344d76d190a..7d29f9011bf0b392414268ba1211e022079d4a4a 100644 --- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java +++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java @@ -252,7 +252,15 @@ public enum SourceVersion { * * @since 18 */ - RELEASE_18; + RELEASE_18, + + /** + * The version recognized by the Java Platform, Standard Edition + * 19. + * + * @since 19 + */ + RELEASE_19; // Note that when adding constants for newer releases, the // behavior of latest() and latestSupported() must be updated too. @@ -261,7 +269,7 @@ public enum SourceVersion { * {@return the latest source version that can be modeled} */ public static SourceVersion latest() { - return RELEASE_18; + return RELEASE_19; } private static final SourceVersion latestSupported = getLatestSupported(); @@ -276,7 +284,7 @@ public enum SourceVersion { private static SourceVersion getLatestSupported() { int intVersion = Runtime.version().feature(); return (intVersion >= 11) ? - valueOf("RELEASE_" + Math.min(18, intVersion)): + valueOf("RELEASE_" + Math.min(19, intVersion)): RELEASE_10; } diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java index fa49170a7c621313a9b22d0b29ec652520a6cb97..004aa596b3a8004d5391961d95e7fd7db58565d0 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java @@ -44,7 +44,7 @@ import javax.annotation.processing.SupportedSourceVersion; * @see AbstractAnnotationValueVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public abstract class AbstractAnnotationValueVisitor14 extends AbstractAnnotationValueVisitor9 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java index 7c69778c89e765266205a02d0ee9c633eaf28b3f..8200e6c00deec0f3b93e5dd236f6686460ef3417 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java @@ -49,7 +49,7 @@ import static javax.lang.model.SourceVersion.*; * @see AbstractElementVisitor9 * @since 16 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public abstract class AbstractElementVisitor14 extends AbstractElementVisitor9 { /** * Constructor for concrete subclasses to call. diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java index 9df8eef86f29525f2d1c5f34ce88d3bb23eba20e..a2a9d098e6b3806d27aef1819c44ab7fb9f6ca41 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java @@ -47,7 +47,7 @@ import static javax.lang.model.SourceVersion.*; * @see AbstractTypeVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public abstract class AbstractTypeVisitor14 extends AbstractTypeVisitor9 { /** * Constructor for concrete subclasses to call. diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java index ab71cdb9c9d9de29c77f080d7336a716ba555e72..93b035e17721cde0dab6d5a30082f9d8edd7a970 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java @@ -61,7 +61,7 @@ import javax.lang.model.SourceVersion; * @see ElementKindVisitor9 * @since 16 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public class ElementKindVisitor14 extends ElementKindVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java index cdc86c1f63be64e32f5999453f139c7a4d4fccf6..ac1bc4976cac1ffdff4f543d04c1c18769c2d399 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java @@ -76,7 +76,7 @@ import static javax.lang.model.SourceVersion.*; * @see ElementScanner9 * @since 16 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public class ElementScanner14 extends ElementScanner9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java index b9015109bb86ecc31c9bdc6e20c28081e1f467b4..9174602cde0f3299b222d87613caf7394503755b 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java @@ -52,7 +52,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleAnnotationValueVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public class SimpleAnnotationValueVisitor14 extends SimpleAnnotationValueVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java index b90c2c97c96eb7d034c39f1f06b525a107f39a15..8e992025e4a8abe318b694c93b34986e6e16a5aa 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java @@ -57,7 +57,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleElementVisitor9 * @since 16 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public class SimpleElementVisitor14 extends SimpleElementVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java index 331297c8f2ee4573459627f9b3193688988a95eb..86e7cb1d981e398e82c7df10a4015a19c40e1329 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java @@ -56,7 +56,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleTypeVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public class SimpleTypeVisitor14 extends SimpleTypeVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java index 66743281bb031dfd7b405c6482934f19fc22fa85..b83307c20959fc75edbbda45f2c2de036ebb7ca0 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java @@ -61,7 +61,7 @@ import static javax.lang.model.SourceVersion.*; * @see TypeKindVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_18) +@SupportedSourceVersion(RELEASE_19) public class TypeKindVisitor14 extends TypeKindVisitor9 { /** * Constructor for concrete subclasses to call; uses {@code null} diff --git a/src/java.compiler/share/classes/javax/tools/JavaCompiler.java b/src/java.compiler/share/classes/javax/tools/JavaCompiler.java index f7c1c61a41bc9bcfa2b4667325ac433c257dbfe9..9039490524ba1f691252cb311d11502795a7b3e8 100644 --- a/src/java.compiler/share/classes/javax/tools/JavaCompiler.java +++ b/src/java.compiler/share/classes/javax/tools/JavaCompiler.java @@ -26,6 +26,7 @@ package javax.tools; import java.io.Writer; +import java.net.URI; import java.nio.charset.Charset; import java.util.Locale; import java.util.concurrent.Callable; @@ -106,42 +107,45 @@ import javax.annotation.processing.Processor; * work with multiple sequential compilations making the following * example a recommended coding pattern: * - *

      - *       File[] files1 = ... ; // input for first compilation task
      - *       File[] files2 = ... ; // input for second compilation task
      + *     {@snippet id="use-sjfm" lang=java :
      + *       File[] files1 = null ; // input for first compilation task     // @replace substring=null replacement="..."
      + *       File[] files2 = null ; // input for second compilation task    // @replace substring=null replacement="..."
        *
        *       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        *       StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        *
      - *       {@code Iterable} compilationUnits1 =
      - *           fileManager.getJavaFileObjectsFromFiles({@linkplain java.util.Arrays#asList Arrays.asList}(files1));
      + *       Iterable compilationUnits1 =
      + *           fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files1));  // @link substring=Arrays.asList target="java.util.Arrays#asList"
        *       compiler.getTask(null, fileManager, null, null, null, compilationUnits1).call();
        *
      - *       {@code Iterable} compilationUnits2 =
      + *       Iterable compilationUnits2 =
        *           fileManager.getJavaFileObjects(files2); // use alternative method
        *       // reuse the same file manager to allow caching of jar files
        *       compiler.getTask(null, fileManager, null, null, null, compilationUnits2).call();
        *
      - *       fileManager.close();
      + * fileManager.close(); + * } * * * *
      {@link DiagnosticCollector}
      *
      * Used to collect diagnostics in a list, for example: - *
      - *       {@code Iterable} compilationUnits = ...;
      + *     {@snippet id="use-diag-collector" lang=java :
      + *       Iterable compilationUnits = null;        // @replace substring=null replacement="..."
        *       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
      - *       {@code DiagnosticCollector diagnostics = new DiagnosticCollector();}
      + *       DiagnosticCollector diagnostics = new DiagnosticCollector();
        *       StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
        *       compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();
        *
      - *       for ({@code Diagnostic} diagnostic : diagnostics.getDiagnostics())
      + *       for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
        *           System.out.format("Error on line %d in %s%n",
        *                             diagnostic.getLineNumber(),
        *                             diagnostic.getSource().toUri());
      + *       }
        *
      - *       fileManager.close();
      + * fileManager.close(); + * } *
      * *
      @@ -158,9 +162,9 @@ import javax.annotation.processing.Processor; * allowing customizing behavior. For example, consider how to * log all calls to {@linkplain JavaFileManager#flush}: * - *
      - *       final  Logger logger = ...;
      - *       {@code Iterable} compilationUnits = ...;
      + *     {@snippet id="forward-fm" lang=java :
      + *       final  Logger logger = null;                                       // @replace substring=null replacement="..."
      + *       Iterable compilationUnits = null;        // @replace substring=null replacement="..."
        *       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        *       StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
        *       JavaFileManager fileManager = new ForwardingJavaFileManager(stdFileManager) {
      @@ -170,7 +174,8 @@ import javax.annotation.processing.Processor;
        *               logger.exiting(StandardJavaFileManager.class.getName(), "flush");
        *           }
        *       };
      - *       compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
      + * compiler.getTask(null, fileManager, null, null, null, compilationUnits).call(); + * } * * *
      {@link SimpleJavaFileObject}
      @@ -181,32 +186,7 @@ import javax.annotation.processing.Processor; * example, here is how to define a file object which represent * source code stored in a string: * - *
      - *       /**
      - *        * A file object used to represent source coming from a string.
      - *        {@code *}/
      - *       public class JavaSourceFromString extends SimpleJavaFileObject {
      - *           /**
      - *            * The source code of this "file".
      - *            {@code *}/
      - *           final String code;
      - *
      - *           /**
      - *            * Constructs a new JavaSourceFromString.
      - *            * {@code @}param name the name of the compilation unit represented by this file object
      - *            * {@code @}param code the source code for the compilation unit represented by this file object
      - *            {@code *}/
      - *           JavaSourceFromString(String name, String code) {
      - *               super({@linkplain java.net.URI#create URI.create}("string:///" + name.replace('.','/') + Kind.SOURCE.extension),
      - *                     Kind.SOURCE);
      - *               this.code = code;
      - *           }
      - *
      - *           {@code @}Override
      - *           public CharSequence getCharContent(boolean ignoreEncodingErrors) {
      - *               return code;
      - *           }
      - *       }
      + * {@snippet id=fileObject class=JavaSourceFromString } * * * diff --git a/src/java.compiler/share/classes/javax/tools/JavaFileManager.java b/src/java.compiler/share/classes/javax/tools/JavaFileManager.java index af926147845404ca13320924503944d88ccb17ec..1fe510e809d2c11f2bcc414b461a0c94a457c2f6 100644 --- a/src/java.compiler/share/classes/javax/tools/JavaFileManager.java +++ b/src/java.compiler/share/classes/javax/tools/JavaFileManager.java @@ -28,6 +28,7 @@ package javax.tools; import java.io.Closeable; import java.io.Flushable; import java.io.IOException; +import java.net.URI; import java.util.Iterator; import java.util.ServiceLoader; import java.util.Set; @@ -80,8 +81,10 @@ import static javax.tools.JavaFileObject.Kind; * href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, * section 3.3. Informally, this should be true: * - * - *
        URI.{@linkplain java.net.URI#create create}(relativeName).{@linkplain java.net.URI#normalize() normalize}().{@linkplain java.net.URI#getPath getPath}().equals(relativeName)
      + * {@snippet id="valid-relative-name" lang=java : + * // @link substring="create" target="URI#create" @link substring=normalize target="URI#normalize" @link substring=getPath target="URI#getPath" : + * URI.create(relativeName).normalize().getPath().equals(relativeName) + * } * *

      All methods in this interface might throw a SecurityException. * @@ -403,7 +406,9 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker { * StandardLocation#SOURCE_PATH SOURCE_PATH} location, this method * might be called like so: * - *

      getFileForInput(SOURCE_PATH, "com.sun.tools.javac", "resources/compiler.properties");
      + * {@snippet id="call-getFileForInput" lang=java : + * getFileForInput(SOURCE_PATH, "com.sun.tools.javac", "resources/compiler.properties"); + * } * *

      If the call was executed on Windows, with SOURCE_PATH set to * "C:\Documents and Settings\UncleBob\src\share\classes", @@ -666,16 +671,17 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker { *

      For a package-oriented location, a file object is contained in the location if there exist * values for packageName and relativeName such that either of the following * calls would return the {@link #isSameFile same} file object: - *

      -     *     getFileForInput(location, packageName, relativeName)
      -     *     getFileForOutput(location, packageName, relativeName, null)
      -     * 
      + * {@snippet : + * // @highlight region substring=packageName type=italic @highlight region substring=relativeName type=italic : + * getFileForInput(location, packageName, relativeName) + * getFileForOutput(location, packageName, relativeName, null) // @end @end + * } * *

      For a module-oriented location, a file object is contained in the location if there exists * a module that may be obtained by the call: - *

      -     *     getLocationForModule(location, moduleName)
      -     * 
      + * {@snippet id="call-getLocationForModule" lang=java : + * getLocationForModule(location, moduleName) // @highlight substring=moduleName type=italic + * } * such that the file object is contained in the (package-oriented) location for that module. * * @implSpec This implementation throws {@code UnsupportedOperationException}. diff --git a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java index 5b6590bf926a524536f781e67c2edc4f5de33e92..bd36f64be6f879d6eaa31fc8236f0f2bdf3203cd 100644 --- a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java +++ b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java @@ -75,9 +75,10 @@ import java.util.List; * {@linkplain FileObject#openReader(boolean)} * must succeed if the following would succeed (ignoring * encoding issues): - *
      - *
      new {@linkplain java.io.FileInputStream#FileInputStream(File) FileInputStream}(new {@linkplain File#File(java.net.URI) File}({@linkplain FileObject fileObject}.{@linkplain FileObject#toUri() toUri}()))
      - *
      + * {@snippet id="equiv-input" lang=java : + * // @link substring=FileInputStream target="java.io.FileInputStream#FileInputStream(File)" @link regex="File\b" target="File#File(java.net.URI)" @link substring=fileObject target=FileObject @link substring=toUri target="FileObject#toUri()" : + * new FileInputStream(new File(fileObject.toUri())) + * } * *
    • * and the methods @@ -85,9 +86,10 @@ import java.util.List; * {@linkplain FileObject#openWriter()} must * succeed if the following would succeed (ignoring encoding * issues): - *
      - *
      new {@linkplain java.io.FileOutputStream#FileOutputStream(File) FileOutputStream}(new {@linkplain File#File(java.net.URI) File}({@linkplain FileObject fileObject}.{@linkplain FileObject#toUri() toUri}()))
      - *
      + * {@snippet id="equiv-output" lang=java : + * // @link substring=FileOutputStream target="java.io.FileOutputStream#FileOutputStream(File)" @link regex="File\b" target="File#File(java.net.URI)" @link substring=fileObject target=FileObject @link substring=toUri target="FileObject#toUri()" : + * new FileOutputStream(new File(fileObject.toUri())) + * } *
    • * * @@ -241,9 +243,9 @@ public interface StandardJavaFileManager extends JavaFileManager { * Returns file objects representing the given files. * Convenience method equivalent to: * - *
      -     *     getJavaFileObjectsFromFiles({@linkplain java.util.Arrays#asList Arrays.asList}(files))
      -     * 
      + * {@snippet id="equiv-getJavaFileObjects" lang=java : + * getJavaFileObjectsFromFiles(Arrays.asList(files)) // @link substring="Arrays.asList" target="Arrays#asList" + * } * * @param files an array of files * @return a list of file objects @@ -259,9 +261,9 @@ public interface StandardJavaFileManager extends JavaFileManager { * Returns file objects representing the given paths. * Convenience method equivalent to: * - *
      -     *     getJavaFileObjectsFromPaths({@linkplain java.util.Arrays#asList Arrays.asList}(paths))
      -     * 
      + * {@snippet id="equiv-getJavaFileObjectsFromPaths" lang=java : + * getJavaFileObjectsFromPaths(Arrays.asList(paths)) // @link substring="Arrays.asList" target="Arrays#asList" + * } * * @implSpec * The default implementation will only throw {@code NullPointerException} @@ -296,9 +298,9 @@ public interface StandardJavaFileManager extends JavaFileManager { * Returns file objects representing the given file names. * Convenience method equivalent to: * - *
      -     *     getJavaFileObjectsFromStrings({@linkplain java.util.Arrays#asList Arrays.asList}(names))
      -     * 
      + * {@snippet id="equiv-getJavaFileObjectsFromStrings" lang=java : + * getJavaFileObjectsFromStrings(Arrays.asList(names)) // @link substring="Arrays.asList" target="Arrays#asList" + * } * * @param names a list of file names * @return a list of file objects diff --git a/src/java.compiler/share/classes/javax/tools/package-info.java b/src/java.compiler/share/classes/javax/tools/package-info.java index c5ec54e7871e0495204da9cc29df9996a20b2512..963e6f2261c43a32a4f83689f215ecb49eff714b 100644 --- a/src/java.compiler/share/classes/javax/tools/package-info.java +++ b/src/java.compiler/share/classes/javax/tools/package-info.java @@ -52,7 +52,9 @@ * a default compiler is provided, it can be located using the * {@link javax.tools.ToolProvider}, for example: * - *

      {@code JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();} + * {@snippet id="show-getSystemJavaCompiler" lang=java : + * JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + * } * *

      It is possible to provide alternative compilers or tools * through the {@linkplain java.util.ServiceLoader service provider @@ -64,12 +66,16 @@ * META-INF/services/javax.tools.JavaCompiler}. This file would * contain the single line: * - *

      {@code com.vendor.VendorJavaCompiler} + * {@snippet id="show-service" : + * com.vendor.VendorJavaCompiler + * } * - *

      If the jar file is on the class path, VendorJavaCompiler can be + *

      If the jar file is on the class path, {@code VendorJavaCompiler} can be * located using code like this: * - *

      {@code JavaCompiler compiler = ServiceLoader.load(JavaCompiler.class).iterator().next();} + * {@snippet id="show-serviceLoader" lang=java : + * JavaCompiler compiler = ServiceLoader.load(JavaCompiler.class).iterator().next(); + * } * * @author Peter von der Ahé * @author Jonathan Gibbons diff --git a/src/java.compiler/share/classes/javax/tools/snippet-files/JavaSourceFromString.java b/src/java.compiler/share/classes/javax/tools/snippet-files/JavaSourceFromString.java new file mode 100644 index 0000000000000000000000000000000000000000..f0555a02e9e3baf276857052c22659a1923d5bf1 --- /dev/null +++ b/src/java.compiler/share/classes/javax/tools/snippet-files/JavaSourceFromString.java @@ -0,0 +1,54 @@ +// @replace region replacement="" +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.tools.SimpleJavaFileObject; +import java.net.URI; +// @end +/** + * A file object used to represent source coming from a string. + */ +public class JavaSourceFromString extends SimpleJavaFileObject { + /** + * The source code of this "file". + */ + final String code; + + /** + * Constructs a new JavaSourceFromString. + * @param name the name of the compilation unit represented by this file object + * @param code the source code for the compilation unit represented by this file object + */ + JavaSourceFromString(String name, String code) { + super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), // @link substring="URI.create" target="URI#create(String)" + Kind.SOURCE); + this.code = code; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return code; + } +} diff --git a/src/java.compiler/share/classes/module-info.java b/src/java.compiler/share/classes/module-info.java index 3d937e09f0cc88d558360becf9b7158f0199de09..0793855d1dc6efb9846d77c5219be91b8a25ce84 100644 --- a/src/java.compiler/share/classes/module-info.java +++ b/src/java.compiler/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,9 @@ */ /** - * Defines the Language Model, Annotation Processing, and Java Compiler APIs. + * Defines the {@index "Language Model"}, {@index "Annotation Processing"}, and + * {@index "Java Compiler"} APIs. + * *

      * These APIs model declarations and types of the Java programming language, * and define interfaces for tools such as compilers which can be invoked diff --git a/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java b/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java index ad3a56a701fd824b64ae6490274cc295e53e3050..bc3ed00a0300ad14f0b45ec30c1f7c7b792a66e9 100644 --- a/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java +++ b/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,10 +43,11 @@ import sun.datatransfer.DataFlavorUtil; * * @author Amy Fowler * @author Alexander Gerasimov - * @see java.awt.Toolkit#getSystemClipboard - * @see java.awt.Toolkit#getSystemSelection + * @see java.desktop/java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemSelection * @since 1.1 */ +@SuppressWarnings("doclint:reference") // cross-module links public class Clipboard { String name; @@ -81,7 +82,7 @@ public class Clipboard { * Creates a clipboard object. * * @param name for the clipboard - * @see java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemClipboard */ public Clipboard(String name) { this.name = name; @@ -91,7 +92,7 @@ public class Clipboard { * Returns the name of this clipboard object. * * @return the name of this clipboard object - * @see java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemClipboard */ public String getName() { return name; @@ -118,7 +119,7 @@ public class Clipboard { * content * @param owner the object which owns the clipboard content * @throws IllegalStateException if the clipboard is currently unavailable - * @see java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemClipboard */ public synchronized void setContents(Transferable contents, ClipboardOwner owner) { final ClipboardOwner oldOwner = this.owner; @@ -145,7 +146,7 @@ public class Clipboard { * @param requestor the object requesting the clip data (not used) * @return the current transferable object on the clipboard * @throws IllegalStateException if the clipboard is currently unavailable - * @see java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemClipboard */ public synchronized Transferable getContents(Object requestor) { return contents; diff --git a/src/java.desktop/macosx/classes/apple/laf/JRSUIControl.java b/src/java.desktop/macosx/classes/apple/laf/JRSUIControl.java index e3579449b7570396b7c0767272d2720ebfd27fe2..6e6c86ccf7ac33d8e1116a1c8bd4978cb7635e9a 100644 --- a/src/java.desktop/macosx/classes/apple/laf/JRSUIControl.java +++ b/src/java.desktop/macosx/classes/apple/laf/JRSUIControl.java @@ -114,7 +114,7 @@ public final class JRSUIControl { changes.putAll(other.changes); } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected synchronized void finalize() throws Throwable { if (cfDictionaryPtr == 0) return; disposeCFDictionary(cfDictionaryPtr); diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java index 3a9ed6b12f511e960e8703f7c407e35cbe0c504b..3c21b325f36cfb400a46b1a9a1dd9ffe751fd33c 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -170,7 +170,7 @@ public abstract class AquaButtonLabeledUI extends AquaButtonToggleUI implements } int offset = 0; - if (b.isFocusOwner()) { + if (b.isFocusOwner() && b.isFocusPainted()) { offset = 2; altIcon = AquaFocus.createFocusedIcon(altIcon, c, 2); } diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaScrollBarUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaScrollBarUI.java index 9d87013c48e2c29056033ee13aedc0630f9ccc11..ea239d83a23a6a91192f81dba3814e689e3a2881 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaScrollBarUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaScrollBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,7 +144,8 @@ public class AquaScrollBarUI extends ScrollBarUI { public void paint(final Graphics g, final JComponent c) { syncState(c); - painter.paint(g, c, 0, 0, fScrollBar.getWidth(), fScrollBar.getHeight()); + Rectangle trackBounds = getTrackBounds(); + painter.paint(g, c, trackBounds.x, trackBounds.y, trackBounds.width, trackBounds.height); } protected State getState(final JComponent c, final ScrollBarPart pressedPart) { @@ -188,11 +189,17 @@ public class AquaScrollBarUI extends ScrollBarUI { } protected Rectangle getTrackBounds() { - return new Rectangle(0, 0, fScrollBar.getWidth(), fScrollBar.getHeight()); + Insets insets = fScrollBar.getInsets(); + return new Rectangle(insets.left, insets.top, + fScrollBar.getWidth() - (insets.left + insets.right), + fScrollBar.getHeight() - (insets.top + insets.bottom)); } protected Rectangle getDragBounds() { - return new Rectangle(0, 0, fScrollBar.getWidth(), fScrollBar.getHeight()); + Insets insets = fScrollBar.getInsets(); + return new Rectangle(insets.left, insets.top, + fScrollBar.getWidth() - (insets.left + insets.right), + fScrollBar.getHeight() - (insets.top + insets.bottom)); } protected void startTimer(final boolean initial) { @@ -228,7 +235,10 @@ public class AquaScrollBarUI extends ScrollBarUI { protected Hit getPartHit(final int x, final int y) { syncState(fScrollBar); - return JRSUIUtils.HitDetection.getHitForPoint(painter.getControl(), 0, 0, fScrollBar.getWidth(), fScrollBar.getHeight(), x, y); + Insets insets = fScrollBar.getInsets(); + return JRSUIUtils.HitDetection.getHitForPoint(painter.getControl(), insets.left, insets.top, + fScrollBar.getWidth() - (insets.left + insets.right), + fScrollBar.getHeight() - (insets.top + insets.bottom), x, y); } protected class PropertyChangeHandler implements PropertyChangeListener { @@ -344,7 +354,9 @@ public class AquaScrollBarUI extends ScrollBarUI { // scroller goes 0-100 with a visible area of 20 we are getting a ratio of the // remaining 80. syncState(fScrollBar); - final double offsetChange = JRSUIUtils.ScrollBar.getNativeOffsetChange(painter.getControl(), 0, 0, fScrollBar.getWidth(), fScrollBar.getHeight(), offsetWeCareAbout, visibleAmt, extent); + final Rectangle limitRect = getDragBounds(); // GetThemeTrackDragRect + final double offsetChange = JRSUIUtils.ScrollBar.getNativeOffsetChange(painter.getControl(), + limitRect.x, limitRect.y, limitRect.width, limitRect.height, offsetWeCareAbout, visibleAmt, extent); // the scrollable area is the extent - visible amount; final int scrollableArea = extent - visibleAmt; @@ -597,7 +609,7 @@ public class AquaScrollBarUI extends ScrollBarUI { // determine the bounding rectangle for our thumb region syncState(fScrollBar); double[] rect = new double[4]; - JRSUIUtils.ScrollBar.getPartBounds(rect, painter.getControl(), 0, 0, fScrollBar.getWidth(), fScrollBar.getHeight(), ScrollBarPart.THUMB); + JRSUIUtils.ScrollBar.getPartBounds(rect, painter.getControl(), limitRect.x, limitRect.y, limitRect.width, limitRect.height, ScrollBarPart.THUMB); final Rectangle r = new Rectangle((int)rect[0], (int)rect[1], (int)rect[2], (int)rect[3]); // figure out the scroll-to-here start location based on our orientation, the diff --git a/src/java.desktop/macosx/classes/sun/awt/CGraphicsEnvironment.java b/src/java.desktop/macosx/classes/sun/awt/CGraphicsEnvironment.java index e96ce7e18d79ac35bf2552e1ac6ef92b4278f7b0..fe4431e3091284a994bbc42e40f50330a41638dc 100644 --- a/src/java.desktop/macosx/classes/sun/awt/CGraphicsEnvironment.java +++ b/src/java.desktop/macosx/classes/sun/awt/CGraphicsEnvironment.java @@ -144,7 +144,7 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment { } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { try { super.finalize(); diff --git a/src/java.desktop/macosx/classes/sun/font/CFont.java b/src/java.desktop/macosx/classes/sun/font/CFont.java index 885fc7fc471d2bb3241b9d06b138ea76fe31cb10..073364719f04d06ef5ea155ce6d38609dc5ad838 100644 --- a/src/java.desktop/macosx/classes/sun/font/CFont.java +++ b/src/java.desktop/macosx/classes/sun/font/CFont.java @@ -206,7 +206,7 @@ public final class CFont extends PhysicalFont implements FontSubstitution { // In some italic cases the standard Mac cascade list is missing Arabic. listOfString.add("GeezaPro"); - FontManager fm = FontManagerFactory.getInstance(); + CFontManager fm = (CFontManager) FontManagerFactory.getInstance(); int numFonts = 1 + listOfString.size(); PhysicalFont[] fonts = new PhysicalFont[numFonts]; fonts[0] = this; @@ -222,7 +222,7 @@ public final class CFont extends PhysicalFont implements FontSubstitution { // Don't know why we get the weird name above .. replace. s = "AppleSymbols"; } - Font2D f2d = fm.findFont2D(s, Font.PLAIN, FontManager.NO_FALLBACK); + Font2D f2d = fm.getOrCreateFallbackFont(s); if (f2d == null || f2d == this) { continue; } @@ -247,7 +247,7 @@ public final class CFont extends PhysicalFont implements FontSubstitution { return compFont; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected synchronized void finalize() { if (nativeFontPtr != 0) { disposeNativeFont(nativeFontPtr); diff --git a/src/java.desktop/macosx/classes/sun/font/CFontManager.java b/src/java.desktop/macosx/classes/sun/font/CFontManager.java index 8775d561f7c7f365b03725959f9a5b2e3a7f13b3..5af2be3f60c97d158d7f8568f0b1478e92cec16d 100644 --- a/src/java.desktop/macosx/classes/sun/font/CFontManager.java +++ b/src/java.desktop/macosx/classes/sun/font/CFontManager.java @@ -33,8 +33,10 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.Locale; +import java.util.Map; import java.util.TreeMap; import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; import javax.swing.plaf.FontUIResource; @@ -45,6 +47,7 @@ import sun.lwawt.macosx.*; public final class CFontManager extends SunFontManager { private static Hashtable genericFonts = new Hashtable(); + private final Map fallbackFonts = new ConcurrentHashMap<>(); @Override protected FontConfiguration createFontConfiguration() { @@ -321,4 +324,17 @@ public final class CFontManager extends SunFontManager { @Override protected void populateFontFileNameMap(HashMap fontToFileMap, HashMap fontToFamilyNameMap, HashMap> familyToFontListMap, Locale locale) {} + + Font2D getOrCreateFallbackFont(String fontName) { + Font2D font2D = findFont2D(fontName, Font.PLAIN, FontManager.NO_FALLBACK); + if (font2D != null || fontName.startsWith(".")) { + return font2D; + } else { + // macOS doesn't list some system fonts in [NSFontManager availableFontFamilies] output, + // so they are not registered in font manager as part of 'loadNativeFonts'. + // These fonts are present in [NSFontManager availableFonts] output though, + // and can be accessed in the same way as other system fonts. + return fallbackFonts.computeIfAbsent(fontName, name -> new CFont(name, null)); + } + } } diff --git a/src/java.desktop/macosx/classes/sun/font/CStrike.java b/src/java.desktop/macosx/classes/sun/font/CStrike.java index 088fb01591e2b83031bc59e6463c2e7e78c26a3d..eb049c3d449d4b1ffb975090ff7e2c9062244bc6 100644 --- a/src/java.desktop/macosx/classes/sun/font/CStrike.java +++ b/src/java.desktop/macosx/classes/sun/font/CStrike.java @@ -125,7 +125,7 @@ public final class CStrike extends PhysicalStrike { return nativeStrikePtr; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected synchronized void finalize() throws Throwable { if (nativeStrikePtr != 0) { disposeNativeStrikePtr(nativeStrikePtr); diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java index 0ea70549d430b33bf41f263e8a805c3ccb6eab60..e6a16ed670fc2808e85f3da8f5b1dea85564e04d 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java @@ -33,8 +33,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URL; import java.nio.charset.Charset; -import java.text.Normalizer; -import java.text.Normalizer.Form; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -165,9 +163,6 @@ public class CDataTransferer extends DataTransferer { // regular string that allows to translate data to target represantation // class by base method format = CF_STRING; - } else if (format == CF_STRING) { - String src = new String(bytes, UTF_8); - bytes = Normalizer.normalize(src, Form.NFC).getBytes(UTF_8); } return super.translateBytes(bytes, flavor, format, transferable); diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java index de0553501e6b400a06c0e807ac581ac8384a54c5..43d6c218b29686652edc52357254e76a875f421b 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java @@ -163,7 +163,7 @@ public class CFRetainedResource { } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected final void finalize() throws Throwable { dispose(); } diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java index de96e59d92ec189748f0076bb6ddedf63975ac28..8dd0246228437192f5d08799196fb925b527f87e 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java @@ -598,7 +598,7 @@ public final class CPrinterJob extends RasterPrinterJob { // The following methods are CPrinterJob specific. @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { synchronized (fNSPrintInfoLock) { if (fNSPrintInfo != -1) { diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index 4a8f5bafe85206dfb243981fef3e1831e4a44700..2362b68c41cfc3f97aaef0d15e7e4e1ef2c0e193 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -453,7 +453,7 @@ public final class LWCToolkit extends LWToolkit { desktopProperties.put("awt.multiClickInterval", getMultiClickTime()); // These DnD properties must be set, otherwise Swing ends up spewing NPEs - // all over the place. The values came straight off of MToolkit. + // all over the place. The values came straight off of XToolkit. desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50)); desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50)); desktopProperties.put("DnD.Autoscroll.cursorHysteresis", Integer.valueOf(5)); diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m index 8e44052333c2c8786405d3f888abb91ef82d4094..15be2ae90f2243fe29c019c6d8f6a3b32c95c5c6 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m @@ -546,12 +546,13 @@ static BOOL shouldUsePressAndHold() { -(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint { if ((codePoint == 0x0024) || (codePoint == 0x00A3) || (codePoint == 0x00A5) || + ((codePoint >= 0x900) && (codePoint <= 0x97F)) || ((codePoint >= 0x20A3) && (codePoint <= 0x20BF)) || ((codePoint >= 0x3000) && (codePoint <= 0x303F)) || ((codePoint >= 0xFF00) && (codePoint <= 0xFFEF))) { // Code point is in 'CJK Symbols and Punctuation' or // 'Halfwidth and Fullwidth Forms' Unicode block or - // currency symbols unicode + // currency symbols unicode or Devanagari script return YES; } return NO; @@ -957,11 +958,17 @@ static jclass jc_CInputMethod = NULL; #ifdef IM_DEBUG NSLog(@"insertText kbdlayout %@ ",(NSString *)kbdLayout); + + NSLog(@"utf8Length %lu utf16Length %lu", (unsigned long)utf8Length, (unsigned long)utf16Length); + NSLog(@"codePoint %x", codePoint); #endif // IM_DEBUG if ((utf16Length > 2) || ((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:codePoint]) || ((codePoint == 0x5c) && ([(NSString *)kbdLayout containsString:@"Kotoeri"]))) { +#ifdef IM_DEBUG + NSLog(@"string complex "); +#endif aStringIsComplex = YES; } diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h index ef67c92a06d556f31253d4a4f47f6f48d7013a6c..103f2c3191239eca5dc95ee99d269d4ab6db671d 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m index c44309a1e3cf49a6a36465df7f1976103f1c588f..ba91dbb8b6f582d3947261f9e2fb2ad089fae0d9 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h index a78afaa924b0162adafe7fc78caae0bbf79853b0..80f633f4a911390f239fdfa0cb31654f1bc55c34 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m index 238b82f609e6ef188315cce627eba5527caa2b5a..fb41511275b21897fe36c2b818833f9f910ed01e 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h index 4a39938a826faf87c59d6b05b5f65127c72d647e..cfdd1faee61e37548e7a873a001ab9384b44be14 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m index 0fd70eb81516502803a862e3676b1d6a666ab841..0029436579f788f899754b47bce968b0ad8404bb 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.h index 33ab5c5fd2e5cb9623ba41eb7023ab96a427efcd..be0169a064df06e2bb279d311774a598200ccc52 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.h @@ -83,6 +83,7 @@ - (NSView* _Nonnull)view; - (NSWindow* _Nonnull)window; - (id _Nonnull)parent; +- (CommonComponentAccessibility* _Nullable)typeSafeParent; - (NSString* _Nonnull)javaRole; - (BOOL)isMenu; diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.m index 201fe5c359124f80003cd1b9ce50a6fdf9528aab..d53d0350abf31c391e25a54e7088bef9fe4d5602 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.m @@ -95,7 +95,11 @@ static jobject sAccessibilityClass = NULL; return NO; } - return isChildSelected(env, ((CommonComponentAccessibility *)[self parent])->fAccessible, fIndex, fComponent); + CommonComponentAccessibility* parent = [self typeSafeParent]; + if (parent != nil) { + return isChildSelected(env, parent->fAccessible, fIndex, fComponent); + } + return NO; } - (BOOL)isSelectable:(JNIEnv *)env @@ -708,6 +712,15 @@ static jobject sAccessibilityClass = NULL; return fParent; } +- (CommonComponentAccessibility *)typeSafeParent +{ + id parent = [self parent]; + if ([parent isKindOfClass:[CommonComponentAccessibility class]]) { + return (CommonComponentAccessibility*)parent; + } + return nil; +} + - (NSString *)javaRole { if(fJavaRole == nil) { @@ -792,7 +805,7 @@ static jobject sAccessibilityClass = NULL; (*env)->DeleteLocalRef(env, axComponent); point.y += size.height; - point.y = [[[[self view] window] screen] frame].size.height - point.y; + point.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - point.y; return NSMakeRect(point.x, point.y, size.width, size.height); } @@ -824,11 +837,13 @@ static jobject sAccessibilityClass = NULL; if (fNSRole == nil) { NSString *javaRole = [self javaRole]; fNSRole = [sRoles objectForKey:javaRole]; + CommonComponentAccessibility* parent = [self typeSafeParent]; // The sRoles NSMutableDictionary maps popupmenu to Mac's popup button. // JComboBox behavior currently relies on this. However this is not the // proper mapping for a JPopupMenu so fix that. if ( [javaRole isEqualToString:@"popupmenu"] && - ![[[self parent] javaRole] isEqualToString:@"combobox"] ) { + parent != nil && + ![[parent javaRole] isEqualToString:@"combobox"] ) { fNSRole = NSAccessibilityMenuRole; } if (fNSRole == nil) { @@ -990,7 +1005,7 @@ static jobject sAccessibilityClass = NULL; point.y += size.height; // Now make it into Cocoa screen coords. - point.y = [[[[self view] window] screen] frame].size.height - point.y; + point.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - point.y; return point; } @@ -1025,8 +1040,9 @@ static jobject sAccessibilityClass = NULL; // This may change when later fixing issues which currently // exist for combo boxes, but for now the following is only // for JPopupMenus, not for combobox menus. - id parent = [self parent]; + id parent = [self typeSafeParent]; if ( [[self javaRole] isEqualToString:@"popupmenu"] && + parent != nil && ![[parent javaRole] isEqualToString:@"combobox"] ) { NSArray *children = [CommonComponentAccessibility childrenOfParent:self @@ -1098,7 +1114,7 @@ static jobject sAccessibilityClass = NULL; "(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;", nil); // Make it into java screen coords - point.y = [[[[self view] window] screen] frame].size.height - point.y; + point.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - point.y; jobject jparent = fComponent; diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h index fd1e774c274cbdb5a766b2169d8a0457c1f5c452..269ea2d5ff8e101eb502e5f9893d40e463f79096 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m index 2101d7042fe62fa757022b09fcc8f2d6ebee1ee7..c2ce32608717b83adcdd929ea0b7f222470837eb 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h index ddfcd2217f8cb7f2ca7fc4b46771d93ec3d49cd1..88f55f99c348781c5762a06001d00d1e4fa3ba0c 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m index 4dc958886bb2142af48b89bc4f7996704e29ff1b..fc75efc6029c81f2c572cd2daee0636e671d80d3 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.h index 130d12721e6de0e54a793204aaa5991885182cee..2b3b4412beb9c6ae5f8741a56c05e896c180d118 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.m index 8b30080c85b78eb772eda242b61dbc6c9e4f9172..dc9e617d43c50d2a5c2f83163de730acabb601f5 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h index 33a05318b5a4abe6c0e991081aa54833b82b09f2..ebf314c7394cf6589521f908414f6eb81307d94b 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m index 84d8785e20541b9ca4942b0e1df4ced0d87da99d..138d502f10fb67fede121bf0d4d6839fb37380cf 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h index 48074b209e0bef591a95cf4bbe589c9d9c1ff00c..2992d82cbe4f521ebf444979f287897b5a6579f5 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m index acc5727cd6b31abc26d75afc1e6d4878b027153d..cdf6dbbd4ab7783d393246ded05d6a5911038ebd 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h index 8cc8e1760c60777dd3db21a5a2ed8d9d56992017..4185c0a27b91779de0fbb6cce0b63c8e7bef464c 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m index e4d7e66027d9609dce2ec94c2e5854167d103542..4653821283dac1623b4de5357212fd8bdd727d14 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h index 0b497d4afc26497e0945896875a7a30a601ea2e1..892225cf2acb0781cb29a148b33ade07700a0e23 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m index 4caf97c21cb67ad5c69f6d8b531206bbfc92761b..2b22db80aa8eb21cf35c9e28ab9b8e740c20f94a 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or @@ -59,11 +61,14 @@ - (jobject)tabGroup { if (fTabGroupAxContext == NULL) { - JNIEnv* env = [ThreadUtilities getJNIEnv]; - jobject tabGroupAxContext = [(CommonComponentAccessibility *)[self parent] axContextWithEnv:env]; - fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroupAxContext); - CHECK_EXCEPTION(); - (*env)->DeleteLocalRef(env, tabGroupAxContext); + CommonComponentAccessibility* parent = [self typeSafeParent]; + if (parent != nil) { + JNIEnv *env = [ThreadUtilities getJNIEnv]; + jobject tabGroupAxContext = [parent axContextWithEnv:env]; + fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroupAxContext); + CHECK_EXCEPTION(); + (*env)->DeleteLocalRef(env, tabGroupAxContext); + } } return fTabGroupAxContext; } diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h index c99b18c904e95d0549314aa1b61306075cc23dbb..c660ff0e780a332270632a9b2cf8d9eb66804755 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m index 76fafc0faafdabb0035d693c4982465b4aef4bf1..06375fc293426e47426c9fc5dd09737ac499c030 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h index 5fe04aa257f61376c355d53f57ccb09052a3af29..6fa9fd0b636acab0edafb39b939f74a037b5d0fb 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m index d6382822e1e52a95a6a43691724e35a8175449a3..d9d18b24fcedf2ed42dec73e39c51db1d893e54d 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.h index afa9eb44e3f22891049981e4e1d3f461e69d6ab0..d9c19ccbc424025e8033aceb2cf10ffdb216cb84 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m index 31636dd99bb4acdfd08aaeda34aee3db6e1d6276..890ac973311f2aebe5479900d86b6153356063e1 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m index 0fb18c3f4c314e29eeae50141aa885160a121398..95374d2c93e53f1d4af0bd960b70e9b7be584bee 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m @@ -41,11 +41,9 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; - (void)dealloc; - (void)reset:(id)destination - isDstOpaque:(jboolean)isDstOpaque - isDstPremultiplied:(jboolean)isDstPremultiplied - isAA:(jboolean)isAA - isText:(jboolean)isText - isLCD:(jboolean)isLCD; + isAA:(jboolean)isAA + isText:(jboolean)isText + isLCD:(jboolean)isLCD; - (void)updateEncoder:(id)encoder context:(MTLContext *)mtlc @@ -64,7 +62,6 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; // Persistent encoder properties id _destination; - SurfaceRasterFlags _dstFlags; jboolean _isAA; jboolean _isText; @@ -123,14 +120,10 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; } - (void)reset:(id)destination - isDstOpaque:(jboolean)isDstOpaque - isDstPremultiplied:(jboolean)isDstPremultiplied - isAA:(jboolean)isAA - isText:(jboolean)isText - isLCD:(jboolean)isLCD { + isAA:(jboolean)isAA + isText:(jboolean)isText + isLCD:(jboolean)isLCD { _destination = destination; - _dstFlags.isOpaque = isDstOpaque; - _dstFlags.isPremultiplied = isDstPremultiplied; _isAA = isAA; _isText = isText; _isLCD = isLCD; @@ -288,20 +281,20 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; - (id _Nonnull)getAARenderEncoder:(const BMTLSDOps * _Nonnull)dstOps { id dstTxt = dstOps->pTexture; - RenderOptions roptions = {JNI_FALSE, JNI_TRUE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {dstOps->isOpaque, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; + RenderOptions roptions = {JNI_FALSE, JNI_TRUE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, JNI_FALSE, JNI_FALSE, JNI_FALSE}; return [self getEncoder:dstTxt renderOptions:&roptions]; } - (id _Nonnull)getAAShaderRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps { - RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {dstOps->isOpaque, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_TRUE}; + RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, JNI_FALSE, JNI_FALSE, JNI_TRUE}; return [self getEncoder:dstOps->pTexture renderOptions:&roptions]; } - (id _Nonnull)getRenderEncoder:(id _Nonnull)dest isDstOpaque:(bool)isOpaque { - RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {isOpaque, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; + RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, JNI_FALSE, JNI_FALSE, JNI_FALSE}; return [self getEncoder:dest renderOptions:&roptions]; } @@ -329,7 +322,7 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; isSrcOpaque:(bool)isSrcOpaque isDstOpaque:(bool)isDstOpaque { - RenderOptions roptions = {JNI_TRUE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, {isSrcOpaque, JNI_TRUE }, {isDstOpaque, JNI_TRUE}, JNI_FALSE, JNI_TRUE, JNI_FALSE}; + RenderOptions roptions = {JNI_TRUE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, {isSrcOpaque, JNI_TRUE }, JNI_FALSE, JNI_TRUE, JNI_FALSE}; return [self getEncoder:dest renderOptions:&roptions]; } @@ -339,7 +332,7 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; interpolation:(int)interpolation isAA:(jboolean)isAA { - RenderOptions roptions = {JNI_TRUE, isAA, interpolation, { isSrcOpaque, JNI_TRUE }, {isDstOpaque, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; + RenderOptions roptions = {JNI_TRUE, isAA, interpolation, { isSrcOpaque, JNI_TRUE }, JNI_FALSE, JNI_FALSE, JNI_FALSE}; return [self getEncoder:dest renderOptions:&roptions]; } @@ -354,7 +347,8 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; - (id _Nonnull) getTextEncoder:(const BMTLSDOps * _Nonnull)dstOps isSrcOpaque:(bool)isSrcOpaque { - RenderOptions roptions = {JNI_TRUE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, { isSrcOpaque, JNI_TRUE }, {dstOps->isOpaque, JNI_TRUE}, JNI_TRUE, JNI_FALSE, JNI_FALSE}; + RenderOptions roptions = {JNI_TRUE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, { isSrcOpaque, JNI_TRUE }, + JNI_TRUE, JNI_FALSE, JNI_FALSE}; return [self getEncoder:dstOps->pTexture renderOptions:&roptions]; } @@ -437,11 +431,9 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE }; _encoder = [[cbw getCommandBuffer] renderCommandEncoderWithDescriptor:rpd]; [_encoderStates reset:dest - isDstOpaque:renderOptions->dstFlags.isOpaque - isDstPremultiplied:YES - isAA:renderOptions->isAA - isText:renderOptions->isText - isLCD:renderOptions->isLCD]; + isAA:renderOptions->isAA + isText:renderOptions->isText + isLCD:renderOptions->isLCD]; } // diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m index bf55d8c8976d0454cd1e1f43bf895b917ac72b45..47571a5e7ae4a98862c92d59fa8aa5de880efaa0 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m @@ -595,8 +595,9 @@ MTLBlitLoops_Blit(JNIEnv *env, } #ifdef TRACE_BLIT - J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, - "MTLBlitLoops_Blit [tx=%d, xf=%d, AC=%s]: bdst=%s, src=%p (%dx%d) O=%d premul=%d | (%d, %d, %d, %d)->(%1.2f, %1.2f, %1.2f, %1.2f)", + J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, + "MTLBlitLoops_Blit srctype=%d [tx=%d, xf=%d, AC=%s]: bdst=%s, src=%p (%dx%d) O=%d premul=%d | (%d, " + "%d, %d, %d)->(%1.2f, %1.2f, %1.2f, %1.2f)", srctype, texture, xform, [mtlc getCompositeDescription].cString, getSurfaceDescription(dstOps).cString, srcOps, sx2 - sx1, sy2 - sy1, diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.m index 35d8ba624c9bd00f85a1e3bea6ea0a291b50c3de..effe7aebae6f89a71e2c5c98dea19ebac98bb18d 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLClip.m @@ -58,7 +58,6 @@ static void initTemplatePipelineDescriptors() { BMTLSDOps* _dstOps; BOOL _stencilMaskGenerationInProgress; BOOL _stencilMaskGenerationStarted; - BOOL _clipReady; MTLOrigin _clipShapeOrigin; MTLSize _clipShapeSize; } @@ -73,7 +72,6 @@ static void initTemplatePipelineDescriptors() { _dstOps = NULL; _stencilMaskGenerationInProgress = NO; _stencilMaskGenerationStarted = NO; - _clipReady = NO; } return self; } @@ -189,7 +187,6 @@ static void initTemplatePipelineDescriptors() { _stencilMaskGenerationStarted = NO; _dstOps = dstOps; _clipType = SHAPE_CLIP; - _clipReady = NO; } - (void)setMaskGenerationPipelineState:(id)encoder diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m index a3b1254bf13745882cac470186788b5ada3151a3..5686449a295602e900b46342ccdc819484475993 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m @@ -56,7 +56,7 @@ static MTLRenderPipelineDescriptor * templateLCDPipelineDesc = nil; static MTLRenderPipelineDescriptor * templateAAPipelineDesc = nil; static void setTxtUniforms(MTLContext *mtlc, int color, id encoder, int interpolation, bool repeat, - jfloat extraAlpha, const SurfaceRasterFlags *srcFlags, const SurfaceRasterFlags *dstFlags, int mode); + jfloat extraAlpha, const SurfaceRasterFlags *srcFlags, int mode); static void initTemplatePipelineDescriptors() { if (templateRenderPipelineDesc != nil && templateTexturePipelineDesc != nil && @@ -228,8 +228,8 @@ jint _color; rpDesc = [[templateLCDPipelineDesc copy] autorelease]; } setTxtUniforms(mtlc, _color, encoder, - renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], &renderOptions->srcFlags, - &renderOptions->dstFlags, 1); + renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], + &renderOptions->srcFlags, 1); } else if (renderOptions->isAAShader) { vertShader = @"vert_col_aa"; fragShader = @"frag_col_aa"; @@ -270,7 +270,7 @@ jint _color; setTxtUniforms(mtlc, col, encoder, renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], - &renderOptions->srcFlags, &renderOptions->dstFlags, 1); + &renderOptions->srcFlags, 1); [encoder setFragmentBytes:&xorColor length:sizeof(xorColor) atIndex:0]; [encoder setFragmentTexture:dstOps->pTexture atIndex:1]; @@ -809,9 +809,8 @@ jint _color; [encoder setFragmentTexture:_paintTexture atIndex:0]; } const SurfaceRasterFlags srcFlags = {_isOpaque, renderOptions->srcFlags.isPremultiplied}; - setTxtUniforms(mtlc, 0, encoder, - renderOptions->interpolation, YES, [mtlc.composite getExtraAlpha], - &srcFlags, &renderOptions->dstFlags, 0); + setTxtUniforms(mtlc, 0, encoder, renderOptions->interpolation, YES, [mtlc.composite getExtraAlpha], + &srcFlags, 0); id pipelineState = [pipelineStateStorage getPipelineState:rpDesc vertexShaderId:vertShader @@ -893,8 +892,8 @@ jint _color; static void setTxtUniforms(MTLContext *mtlc, int color, id encoder, int interpolation, bool repeat, - jfloat extraAlpha, const SurfaceRasterFlags *srcFlags, const SurfaceRasterFlags *dstFlags, int mode) { - struct TxtFrameUniforms uf = {RGBA_TO_V4(color), mode, srcFlags->isOpaque, dstFlags->isOpaque, extraAlpha}; + jfloat extraAlpha, const SurfaceRasterFlags *srcFlags, int mode) { + struct TxtFrameUniforms uf = {RGBA_TO_V4(color), mode, srcFlags->isOpaque, extraAlpha}; [encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer]; [mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:interpolation repeat:repeat]; } @@ -956,8 +955,7 @@ setTxtUniforms(MTLContext *mtlc, int color, id encoder } else { setTxtUniforms(mtlc, 0, encoder, renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], - &renderOptions->srcFlags, - &renderOptions->dstFlags, 0); + &renderOptions->srcFlags, 0); } id pipelineState = [pipelineStateStorage getPipelineState:rpDesc @@ -998,7 +996,7 @@ setTxtUniforms(MTLContext *mtlc, int color, id encoder const int col = 0 ^ xorColor; setTxtUniforms(mtlc, col, encoder, renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], - &renderOptions->srcFlags, &renderOptions->dstFlags, 0); + &renderOptions->srcFlags, 0); [encoder setFragmentBytes:&xorColor length:sizeof(xorColor) atIndex: 0]; BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination(); @@ -1006,8 +1004,7 @@ setTxtUniforms(MTLContext *mtlc, int color, id encoder setTxtUniforms(mtlc, 0, encoder, renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], - &renderOptions->srcFlags, - &renderOptions->dstFlags, 0); + &renderOptions->srcFlags, 0); id pipelineState = [pipelineStateStorage getPipelineState:rpDesc vertexShaderId:vertShader diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m index 0928f12d426958d74803eff3e1353a40ecad5b89..9a7862e8c263044cd1a1c9c8977add83640a3587 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m @@ -84,7 +84,7 @@ static void setBlendingFactors( vertexShaderId:(NSString *)vertexShaderId fragmentShaderId:(NSString *)fragmentShaderId { - RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, {JNI_FALSE, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; + RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; return [self getPipelineState:pipelineDescriptor vertexShaderId:vertexShaderId fragmentShaderId:fragmentShaderId @@ -98,7 +98,7 @@ static void setBlendingFactors( fragmentShaderId:(NSString *)fragmentShaderId stencilNeeded:(bool)stencilNeeded { - RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, {JNI_FALSE, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; + RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, JNI_FALSE, JNI_FALSE, JNI_FALSE}; return [self getPipelineState:pipelineDescriptor vertexShaderId:vertexShaderId fragmentShaderId:fragmentShaderId @@ -107,6 +107,19 @@ static void setBlendingFactors( stencilNeeded:stencilNeeded]; } +// Pipeline state index +union StateIndex { + uint32_t value; + struct { + uint32_t srcPremultiplied : 1, + srcOpaque : 1, + stencil : 1, + aa : 1, + extAlpha : 1, + compositeRule : 27; + } bits; +}; + // Base method to obtain MTLRenderPipelineState. // NOTE: parameters compositeRule, srcFlags, dstFlags are used to set MTLRenderPipelineColorAttachmentDescriptor multipliers - (id) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor @@ -123,45 +136,31 @@ static void setBlendingFactors( // Calculate index by flags and compositeRule // TODO: reimplement, use map with convenient key (calculated by all arguments) - int subIndex = 0; + union StateIndex index; + index.value = 0; if (useXorComposite) { // compositeRule value is already XOR_COMPOSITE_RULE } else { if (useComposite) { - if (!renderOptions->srcFlags.isPremultiplied) - subIndex |= 1; - if (renderOptions->srcFlags.isOpaque) - subIndex |= 1 << 1; - if (!renderOptions->dstFlags.isPremultiplied) - subIndex |= 1 << 2; - if (renderOptions->dstFlags.isOpaque) - subIndex |= 1 << 3; + index.bits.srcPremultiplied = renderOptions->srcFlags.isPremultiplied; + index.bits.srcOpaque = renderOptions->srcFlags.isOpaque; } else compositeRule = RULE_Src; } - if (stencilNeeded) { - subIndex |= 1 << 4; - } - - if (renderOptions->isAA) { - subIndex |= 1 << 5; - } - - if ((composite != nil && FLT_LT([composite getExtraAlpha], 1.0f))) { - subIndex |= 1 << 6; - } - - int index = compositeRule*128 + subIndex; + index.bits.stencil = stencilNeeded; + index.bits.aa = renderOptions->isAA; + index.bits.extAlpha = composite != nil && FLT_LT([composite getExtraAlpha], 1.0f); + index.bits.compositeRule = compositeRule; NSPointerArray * subStates = [self getSubStates:vertexShaderId fragmentShader:fragmentShaderId]; - if (index >= subStates.count) { - subStates.count = (NSUInteger) (index + 1); + if (index.value >= subStates.count) { + subStates.count = index.value + 1; } - id result = [subStates pointerAtIndex:index]; + id result = [subStates pointerAtIndex:index.value]; if (result == nil) { @autoreleasepool { id vertexShader = [self getShader:vertexShaderId]; @@ -222,7 +221,7 @@ static void setBlendingFactors( exit(0); } - [subStates insertPointer:result atIndex:index]; + [subStates replacePointerAtIndex:index.value withPointer:result]; } } diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h index 46521ca5b09a93d389cb96c6eb10d4131671d87f..f24f131631af88b6106e617a8032f2afa980172a 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h @@ -35,7 +35,6 @@ typedef struct { jboolean isAA; int interpolation; SurfaceRasterFlags srcFlags; - SurfaceRasterFlags dstFlags; jboolean isText; jboolean isLCD; jboolean isAAShader; diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/common.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/common.h index 556bbf5d88ef4ded24a60900a1806f8baab6cf4a..70218f7e849c56a711d4771dd21278b20a40a263 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/common.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/common.h @@ -114,7 +114,6 @@ struct TxtFrameUniforms { vector_float4 color; int mode; // NOTE: consider to use bit fields int isSrcOpaque; - int isDstOpaque; float extraAlpha; }; diff --git a/src/java.desktop/share/classes/com/sun/beans/TypeResolver.java b/src/java.desktop/share/classes/com/sun/beans/TypeResolver.java index 25f079473100cafe6e41dd85de85e6d8ca0be293..c8f2d1891dc0672ec840c9201009cb4181c3c2d5 100644 --- a/src/java.desktop/share/classes/com/sun/beans/TypeResolver.java +++ b/src/java.desktop/share/classes/com/sun/beans/TypeResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,7 +104,7 @@ public final class TypeResolver { * of those parameters. For example, Map<K,V> is a generic class, and * a corresponding ParameterizedType might look like * Map<K=String,V=Integer>. Given such a ParameterizedType, this method - * will replace K with String, or List<K> with List<String;, or + * will replace K with String, or List<K> with List<String>, or * List<? super K> with List<? super String>.

      * *

      The {@code actual} argument to this method can also be a Class. diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java index df283e8102cd9ab099fbbe759718ac2669df6d0a..2e1c2db03ca84d64cdaa2c2abb00dabffeb1edb9 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java @@ -52,6 +52,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import javax.imageio.IIOException; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; @@ -223,6 +224,33 @@ public class BMPImageReader extends ImageReader implements BMPConstants { } } + private void readColorPalette(int sizeOfPalette) throws IOException { + final int UNIT_SIZE = 1024000; + if (sizeOfPalette < UNIT_SIZE) { + palette = new byte[sizeOfPalette]; + iis.readFully(palette, 0, sizeOfPalette); + } else { + int bytesToRead = sizeOfPalette; + int bytesRead = 0; + List bufs = new ArrayList<>(); + while (bytesToRead != 0) { + int sz = Math.min(bytesToRead, UNIT_SIZE); + byte[] unit = new byte[sz]; + iis.readFully(unit, 0, sz); + bufs.add(unit); + bytesRead += sz; + bytesToRead -= sz; + } + byte[] paletteData = new byte[bytesRead]; + int copiedBytes = 0; + for (byte[] ba : bufs) { + System.arraycopy(ba, 0, paletteData, copiedBytes, ba.length); + copiedBytes += ba.length; + } + palette = paletteData; + } + } + /** * Process the image header. * @@ -305,8 +333,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants { // Read in the palette int numberOfEntries = (int)((bitmapOffset - 14 - size) / 3); int sizeOfPalette = numberOfEntries*3; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = numberOfEntries; } else { @@ -343,8 +370,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants { } int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries * 4; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = numberOfEntries; @@ -404,8 +430,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants { if (colorsUsed != 0) { // there is a palette sizeOfPalette = (int)colorsUsed*4; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = (int)colorsUsed; @@ -430,8 +455,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants { // Read in the palette int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries*4; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = numberOfEntries; @@ -529,8 +553,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants { // Read in the palette int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries*4; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = numberOfEntries; @@ -592,7 +615,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants { } if (metadata.compression == BI_RGB) { - long imageDataSize = (width * height * (bitsPerPixel / 8)); + long imageDataSize = ((long)width * height * (bitsPerPixel / 8)); if (imageDataSize > (bitmapFileSize - bitmapOffset)) { throw new IIOException(I18N.getString("BMPImageReader9")); } diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java index 0f8d1d66a28d206c2092ab3541e060d05622c7b5..906aa3a8a38fa7377456112b05b86474e2b53db1 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ package com.sun.imageio.plugins.common; import java.awt.Point; import java.awt.Rectangle; import java.io.IOException; +import java.util.List; +import java.util.ArrayList; import javax.imageio.stream.ImageInputStream; /** @@ -213,4 +215,47 @@ public class ReaderUtil { } return result; } + + /** + * An utility method to allocate and initialize a byte array + * step by step with pre-defined limit, instead of allocating + * a large array up-front based on the length derived from + * an image header. + * + * @param iis a {@code ImageInputStream} to decode data and store + * it in byte array. + * @param length the size of data to decode + * + * @return array of size length when decode succeeeds + * + * @throws IOException if decoding of stream fails + */ + public static byte[] staggeredReadByteStream(ImageInputStream iis, + int length) throws IOException { + final int UNIT_SIZE = 1024000; + byte[] decodedData; + if (length < UNIT_SIZE) { + decodedData = new byte[length]; + iis.readFully(decodedData, 0, length); + } else { + int bytesToRead = length; + int bytesRead = 0; + List bufs = new ArrayList<>(); + while (bytesToRead != 0) { + int sz = Math.min(bytesToRead, UNIT_SIZE); + byte[] unit = new byte[sz]; + iis.readFully(unit, 0, sz); + bufs.add(unit); + bytesRead += sz; + bytesToRead -= sz; + } + decodedData = new byte[bytesRead]; + int copiedBytes = 0; + for (byte[] ba : bufs) { + System.arraycopy(ba, 0, decodedData, copiedBytes, ba.length); + copiedBytes += ba.length; + } + } + return decodedData; + } } diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/common/SubImageInputStream.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/common/SubImageInputStream.java index 8ddffc522f1873a8689e14a19ca0667d174d71e4..10211c6636c90bb572937f71794925fdbc21cff1 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/common/SubImageInputStream.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/common/SubImageInputStream.java @@ -72,7 +72,7 @@ public final class SubImageInputStream extends ImageInputStreamImpl { streamPos = pos; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { // Empty finalizer (for improved performance; no need to call // super.finalize() in this case) diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java index 2bedc9440ee9435349836be4a2a76d284c5694c7..9632e37d1d41d06a5079857c3701c04d423266d9 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1007,6 +1007,11 @@ public class GIFImageReader extends ImageReader { } } + if (tableIndex >= prefix.length) { + throw new IIOException("Code buffer limit reached," + + " no End of Image tag present, possibly data is corrupted. "); + } + int ti = tableIndex; int oc = oldCode; diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java index ab15bdfc6b810e9b40779164d2dcdfb351d623ef..a7edf73cb80b6cbb4e518ea9150dac18ac62dedc 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java @@ -1156,6 +1156,13 @@ public class JPEGImageReader extends ImageReader { throw new IIOException("Unsupported Image Type"); } + if ((long)width * height > Integer.MAX_VALUE - 2) { + // We are not able to properly decode image that has number + // of pixels greater than Integer.MAX_VALUE - 2 + throw new IIOException("Can not read image of the size " + + width + " by " + height); + } + image = getDestination(param, imageTypes, width, height); imRas = image.getRaster(); diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java index fc731506af37c0a758735c935161525dcc89b72b..edebce1d62e00837b3646347971cee02eb85176b 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java @@ -669,18 +669,9 @@ public class PNGImageReader extends ImageReader { private static byte[] inflate(byte[] b) throws IOException { InputStream bais = new ByteArrayInputStream(b); - InputStream iis = new InflaterInputStream(bais); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - int c; - try { - while ((c = iis.read()) != -1) { - baos.write(c); - } - } finally { - iis.close(); + try (InputStream iis = new InflaterInputStream(bais)) { + return iis.readAllBytes(); } - return baos.toByteArray(); } private void parse_zTXt_chunk(int chunkLength) throws IOException { @@ -1424,6 +1415,13 @@ public class PNGImageReader extends ImageReader { int width = metadata.IHDR_width; int height = metadata.IHDR_height; + if ((long)width * height > Integer.MAX_VALUE - 2) { + // We are not able to properly decode image that has number + // of pixels greater than Integer.MAX_VALUE - 2 + throw new IIOException("Can not read image of the size " + + width + " by " + height); + } + // Init default values sourceXSubsampling = 1; sourceYSubsampling = 1; diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java index 449661b8c91800b48d8c835dc52ff946a3a58866..ce6f771ecdceb539a4bc27562fbda1167cb429d0 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java @@ -147,7 +147,7 @@ final class ChunkStream extends ImageOutputStreamImpl { } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { // Empty finalizer (for improved performance; no need to call // super.finalize() in this case) @@ -284,7 +284,7 @@ final class IDATOutputStream extends ImageOutputStreamImpl { } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { // Empty finalizer (for improved performance; no need to call // super.finalize() in this case) diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFBaseJPEGCompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFBaseJPEGCompressor.java index 74695ae46cea80e2029fdfa88a84196f19afcd7a..dba8d87816953a71c6cd094e663196dd9ffd65f2 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFBaseJPEGCompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFBaseJPEGCompressor.java @@ -435,7 +435,7 @@ public abstract class TIFFBaseJPEGCompressor extends TIFFCompressor { return compDataLength; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { super.finalize(); if(JPEGWriter != null) { diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java index a1b0439097758409a855b970b552dd897f79a679..4516ce0ad82e391319cb46d7332112d2892b5c26 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1438,7 +1438,11 @@ public abstract class TIFFDecompressor { * * @param byteCount the number of bytes of compressed data. */ - public void setByteCount(int byteCount) { + public void setByteCount(int byteCount) throws IOException{ + if (byteCount < 0) { + throw new IIOException("Strip byte count can't be" + + " negative: " + byteCount); + } this.byteCount = byteCount; } diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFaxDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFaxDecompressor.java index 22ebda2187af01eccbccad45acb7f973b374f27c..4d64072075a6ea362e99c2cf7e99835ad6b2f8bd 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFaxDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFaxDecompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.io.EOFException; import javax.imageio.IIOException; import javax.imageio.plugins.tiff.BaselineTIFFTagSet; import javax.imageio.plugins.tiff.TIFFField; +import com.sun.imageio.plugins.common.ReaderUtil; class TIFFFaxDecompressor extends TIFFDecompressor { @@ -637,14 +638,14 @@ class TIFFFaxDecompressor extends TIFFDecompressor { this.bitsPerScanline = scanlineStride*8; this.lineBitNum = 8*dstOffset; - this.data = new byte[byteCount]; this.bitPointer = 0; this.bytePointer = 0; this.prevChangingElems = new int[w + 1]; this.currChangingElems = new int[w + 1]; stream.seek(offset); - stream.readFully(data); + this.data = ReaderUtil. + staggeredReadByteStream(stream, byteCount); if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) { decodeRLE(); diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFJPEGDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFJPEGDecompressor.java index 384687f8344b104ac1d93287f7732f5927c77d8f..0b21835901b44621456e41188e3a2c8d256eb59e 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFJPEGDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFJPEGDecompressor.java @@ -139,7 +139,7 @@ public class TIFFJPEGDecompressor extends TIFFDecompressor { JPEGReader.read(0, JPEGParam); } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { super.finalize(); JPEGReader.dispose(); diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java index 9010674bdb18abe8cee1b5133f0442802ab89d21..fc682589ce2700cbb29547ca9bd6323474a20002 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ package com.sun.imageio.plugins.tiff; import java.io.IOException; import javax.imageio.IIOException; import javax.imageio.plugins.tiff.BaselineTIFFTagSet; +import com.sun.imageio.plugins.common.ReaderUtil; class TIFFLZWDecompressor extends TIFFDecompressor { @@ -95,9 +96,8 @@ class TIFFLZWDecompressor extends TIFFDecompressor { } stream.seek(offset); - - byte[] sdata = new byte[byteCount]; - stream.readFully(sdata); + byte[] sdata = ReaderUtil. + staggeredReadByteStream(stream, byteCount); if (flipBits) { for (int i = 0; i < byteCount; i++) { diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFNullDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFNullDecompressor.java index 6ffc1f0acb7da9d4b3b5dc9a9f2fdfe458ac9c1f..9b5a746eec1da0eddd064a8ff785ad5150982d5a 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFNullDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFNullDecompressor.java @@ -136,12 +136,7 @@ public class TIFFNullDecompressor extends TIFFDecompressor { int lastRow = activeSrcHeight - 1; for (int y = 0; y < activeSrcHeight; y++) { - int bytesRead = stream.read(b, dstOffset, activeBytesPerRow); - if (bytesRead < 0) { - throw new EOFException(); - } else if (bytesRead != activeBytesPerRow) { - break; - } + stream.readFully(b, dstOffset, activeBytesPerRow); dstOffset += scanlineStride; // Skip unneeded bytes (row suffix + row prefix). @@ -154,17 +149,10 @@ public class TIFFNullDecompressor extends TIFFDecompressor { stream.seek(offset); int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8; if(bytesPerRow == scanlineStride) { - if (stream.read(b, dstOffset, bytesPerRow*srcHeight) < 0) { - throw new EOFException(); - } + stream.readFully(b, dstOffset, bytesPerRow*srcHeight); } else { for (int y = 0; y < srcHeight; y++) { - int bytesRead = stream.read(b, dstOffset, bytesPerRow); - if (bytesRead < 0) { - throw new EOFException(); - } else if (bytesRead != bytesPerRow) { - break; - } + stream.readFully(b, dstOffset, bytesPerRow); dstOffset += scanlineStride; } } diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFOldJPEGDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFOldJPEGDecompressor.java index 67dd60f8a79a4480a8c4cf99b288f920e0cf0582..3cd89b396ccc007beec977d0db210194bc1ba53b 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFOldJPEGDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFOldJPEGDecompressor.java @@ -610,7 +610,7 @@ public class TIFFOldJPEGDecompressor extends TIFFJPEGDecompressor { JPEGReader.read(0, JPEGParam); } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { super.finalize(); JPEGReader.dispose(); diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFPackBitsDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFPackBitsDecompressor.java index 42a44a43eee4e396005496ab4f8cf1e3fed5362a..0a5dfe8308e206620c5bb87fb2a2c2fe9b2c1add 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFPackBitsDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFPackBitsDecompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package com.sun.imageio.plugins.tiff; import java.io.IOException; +import com.sun.imageio.plugins.common.ReaderUtil; public class TIFFPackBitsDecompressor extends TIFFDecompressor { @@ -77,8 +78,8 @@ public class TIFFPackBitsDecompressor extends TIFFDecompressor { int scanlineStride) throws IOException { stream.seek(offset); - byte[] srcData = new byte[byteCount]; - stream.readFully(srcData); + byte[] srcData = ReaderUtil. + staggeredReadByteStream(stream, byteCount); int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8; byte[] buf; diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFYCbCrDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFYCbCrDecompressor.java index 11151d8e6c8e71700e3465d95d52fcc477854d87..0f10904cab413b5fa6126387d69d36a0eea41331 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFYCbCrDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFYCbCrDecompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,7 +180,7 @@ public class TIFFYCbCrDecompressor extends TIFFDecompressor { super.setOffset(offset); } - public void setByteCount(int byteCount) { + public void setByteCount(int byteCount) throws IOException { if(decompressor != null) { decompressor.setByteCount(byteCount); } diff --git a/src/java.desktop/share/classes/com/sun/imageio/stream/StreamFinalizer.java b/src/java.desktop/share/classes/com/sun/imageio/stream/StreamFinalizer.java index be1e659ee6e7784e1131d48f22a4d1846642c3c1..012d7e106459823b25b62310c06bd48296e370ea 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/stream/StreamFinalizer.java +++ b/src/java.desktop/share/classes/com/sun/imageio/stream/StreamFinalizer.java @@ -60,7 +60,7 @@ public class StreamFinalizer { this.stream = stream; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { try { stream.close(); diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java index 134cdd9a2dc6cadaa8194f5ecd671c0e3422e725..d2388fa6b04e639019d6090d0b5d7fc102e77e5d 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java @@ -583,15 +583,16 @@ class Metacity implements SynthConstants { URL url = new URL(new File(userHome).toURI().toURL(), ".gconf/apps/metacity/general/%25gconf.xml"); // Pending: verify character encoding spec for gconf - Reader reader = new InputStreamReader(url.openStream(), - ISO_8859_1); - char[] buf = new char[1024]; StringBuilder sb = new StringBuilder(); - int n; - while ((n = reader.read(buf)) >= 0) { - sb.append(buf, 0, n); + try (InputStream in = url.openStream(); + Reader reader = new InputStreamReader(in, ISO_8859_1)) + { + char[] buf = new char[1024]; + int n; + while ((n = reader.read(buf)) >= 0) { + sb.append(buf, 0, n); + } } - reader.close(); String str = sb.toString(); if (str != null) { String strLowerCase = str.toLowerCase(); diff --git a/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java b/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java index 1b50f31eb9e89271936032e11a8e31a51fdb6f51..3ba4ce2ed366b13eb76709bcf4f8eb4bd707fd3e 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java @@ -425,7 +425,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice * close this device if discarded by the garbage collector. */ @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected final void finalize() { close(); } diff --git a/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java b/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java index de9d124753fcaea58a47348752e20d56c4dcd7cd..32b06d47bd2965dce4375fd3a1ee9526d1527086 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,10 +48,8 @@ public final class AudioFileSoundbankReader extends SoundbankReader { @Override public Soundbank getSoundbank(URL url) throws InvalidMidiDataException, IOException { - try { - AudioInputStream ais = AudioSystem.getAudioInputStream(url); + try (AudioInputStream ais = AudioSystem.getAudioInputStream(url)) { Soundbank sbk = getSoundbank(ais); - ais.close(); return sbk; } catch (UnsupportedAudioFileException e) { return null; diff --git a/src/java.desktop/share/classes/com/sun/media/sound/DLSSoundbank.java b/src/java.desktop/share/classes/com/sun/media/sound/DLSSoundbank.java index 3d62b3ae5a63074180f5dda2828a69978dc668e9..ba25dcacd20b92a990c5d6686adb98f340808809 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/DLSSoundbank.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/DLSSoundbank.java @@ -191,22 +191,16 @@ public final class DLSSoundbank implements Soundbank { } public DLSSoundbank(URL url) throws IOException { - InputStream is = url.openStream(); - try { + try (InputStream is = url.openStream()) { readSoundbank(is); - } finally { - is.close(); } } public DLSSoundbank(File file) throws IOException { largeFormat = true; sampleFile = file; - InputStream is = new FileInputStream(file); - try { + try (InputStream is = new FileInputStream(file)) { readSoundbank(is); - } finally { - is.close(); } } @@ -875,15 +869,21 @@ public final class DLSSoundbank implements Soundbank { } public void save(String name) throws IOException { - writeSoundbank(new RIFFWriter(name, "DLS ")); + try (RIFFWriter writer = new RIFFWriter(name, "DLS ")) { + writeSoundbank(writer); + } } public void save(File file) throws IOException { - writeSoundbank(new RIFFWriter(file, "DLS ")); + try (RIFFWriter writer = new RIFFWriter(file, "DLS ")) { + writeSoundbank(writer); + } } public void save(OutputStream out) throws IOException { - writeSoundbank(new RIFFWriter(out, "DLS ")); + try (RIFFWriter writer = new RIFFWriter(out, "DLS ")) { + writeSoundbank(writer); + } } private void writeSoundbank(RIFFWriter writer) throws IOException { @@ -923,8 +923,6 @@ public final class DLSSoundbank implements Soundbank { writer.seek(bak); writeInfo(writer.writeList("INFO"), info); - - writer.close(); } private void writeSample(RIFFWriter writer, DLSSample sample) diff --git a/src/java.desktop/share/classes/com/sun/media/sound/DataPusher.java b/src/java.desktop/share/classes/com/sun/media/sound/DataPusher.java index 8944df836aef4f68821ff47e90f61d6a00ab8585..d40c2cd8c317f5faa67ae58b4e6bd4232a2436ed 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/DataPusher.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/DataPusher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,7 +108,7 @@ public final class DataPusher implements Runnable { source.start(); if (pushThread == null) { pushThread = JSSecurityManager.createThread(this, - null, // name + "DataPusher", // name false, // daemon -1, // priority true); // doStart diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java b/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java index e01bc10cf3912b013deb4247378caa1b2ae6c6b6..967d35d31dc35caf2720cd7214c029d9665dcf56 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,8 +51,7 @@ public final class JARSoundbankReader extends SoundbankReader { private static boolean isZIP(URL url) { boolean ok = false; try { - InputStream stream = url.openStream(); - try { + try (InputStream stream = url.openStream()) { byte[] buff = new byte[4]; ok = stream.read(buff) == 4; if (ok) { @@ -61,8 +60,6 @@ public final class JARSoundbankReader extends SoundbankReader { && buff[2] == 0x03 && buff[3] == 0x04); } - } finally { - stream.close(); } } catch (IOException e) { } @@ -81,8 +78,7 @@ public final class JARSoundbankReader extends SoundbankReader { "META-INF/services/javax.sound.midi.Soundbank"); if (stream == null) return null; - try - { + try (stream) { BufferedReader r = new BufferedReader(new InputStreamReader(stream)); String line = r.readLine(); while (line != null) { @@ -100,10 +96,6 @@ public final class JARSoundbankReader extends SoundbankReader { line = r.readLine(); } } - finally - { - stream.close(); - } if (soundbanks.size() == 0) return null; if (soundbanks.size() == 1) diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java index f593ed8b89749206a6d9f4b058c41c7cc8a1f45f..51482b24aeaae88ecab6d19bb8a35463841f2831 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,6 @@ final class JSSecurityManager { final boolean isDaemon, final int priority, final boolean doStart) { - String name = (threadName != null) ? threadName : "JSSM Thread"; Thread thread = new Thread(null, runnable, threadName, 0, false); thread.setDaemon(isDaemon); diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java b/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java index bc2f87fe33f04797bbde82e52870dd0ea6e1d4dc..c804a0e49c225ff1a0b852c54479d9dd71d41df7 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java @@ -283,6 +283,7 @@ public final class JavaSoundAudioClip implements AudioClip, MetaEventListener, L } @Override + @SuppressWarnings("removal") protected void finalize() { if (clip != null) { diff --git a/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBuffer.java b/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBuffer.java index 13cbf54fe6d27708e6f45a5ac557c813f1454ccd..2476ff09bbcc7d18c816fd04b4c8670a7449c852 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBuffer.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBuffer.java @@ -315,11 +315,13 @@ public final class ModelByteBuffer { "No file associated with this ByteBuffer!"); } - DataInputStream is = new DataInputStream(getInputStream()); - buffer = new byte[(int) capacity()]; - offset = 0; - is.readFully(buffer); - is.close(); + try (InputStream is = getInputStream(); + DataInputStream dis = new DataInputStream(is)) + { + buffer = new byte[(int) capacity()]; + offset = 0; + dis.readFully(buffer); + } } diff --git a/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java b/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java index 45fa29542117d0e2b470bd6327908c2a60060e50..bc8829d288c6fe7620d6190a831c2d8abf542290 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -182,18 +182,12 @@ public final class ModelByteBufferWavetable implements ModelWavetable { if (format == null) { if (buffer == null) return null; - InputStream is = buffer.getInputStream(); AudioFormat format = null; - try { + try (InputStream is = buffer.getInputStream()) { format = AudioSystem.getAudioFileFormat(is).getFormat(); } catch (Exception e) { //e.printStackTrace(); } - try { - is.close(); - } catch (IOException e) { - //e.printStackTrace(); - } return format; } return format; diff --git a/src/java.desktop/share/classes/com/sun/media/sound/SF2Soundbank.java b/src/java.desktop/share/classes/com/sun/media/sound/SF2Soundbank.java index ccade6b1a2e5abba6e3f49537b3888ea9d2e8176..831423664e69c68b14ad761a4a552be636876943 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/SF2Soundbank.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/SF2Soundbank.java @@ -92,23 +92,16 @@ public final class SF2Soundbank implements Soundbank { } public SF2Soundbank(URL url) throws IOException { - - InputStream is = url.openStream(); - try { + try (InputStream is = url.openStream()) { readSoundbank(is); - } finally { - is.close(); } } public SF2Soundbank(File file) throws IOException { largeFormat = true; sampleFile = file; - InputStream is = new FileInputStream(file); - try { + try (InputStream is = new FileInputStream(file)) { readSoundbank(is); - } finally { - is.close(); } } @@ -517,22 +510,27 @@ public final class SF2Soundbank implements Soundbank { } public void save(String name) throws IOException { - writeSoundbank(new RIFFWriter(name, "sfbk")); + try (RIFFWriter writer = new RIFFWriter(name, "sfbk")) { + writeSoundbank(writer); + } } public void save(File file) throws IOException { - writeSoundbank(new RIFFWriter(file, "sfbk")); + try (RIFFWriter writer = new RIFFWriter(file, "sfbk")) { + writeSoundbank(writer); + } } public void save(OutputStream out) throws IOException { - writeSoundbank(new RIFFWriter(out, "sfbk")); + try (RIFFWriter writer = new RIFFWriter(out, "sfbk")) { + writeSoundbank(writer); + } } private void writeSoundbank(RIFFWriter writer) throws IOException { writeInfo(writer.writeList("INFO")); writeSdtaChunk(writer.writeList("sdta")); writePdtaChunk(writer.writeList("pdta")); - writer.close(); } private void writeInfoStringChunk(RIFFWriter writer, String name, diff --git a/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java b/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java index c2642436fe4d10947ecaef7f8715abb4c0870f55..d614fbc10e5fb447e69e54a19d3537cf5e49c61c 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java @@ -755,10 +755,8 @@ public final class SoftSynthesizer implements AudioSynthesizer, InputStream is = AccessController.doPrivileged(action); if(is == null) continue; Soundbank sbk; - try { + try (is) { sbk = MidiSystem.getSoundbank(new BufferedInputStream(is)); - } finally { - is.close(); } if (sbk != null) { defaultSoundBank = sbk; @@ -802,9 +800,8 @@ public final class SoftSynthesizer implements AudioSynthesizer, return null; }); if (out != null) { - try { + try (out) { ((SF2Soundbank) defaultSoundBank).save(out); - out.close(); } catch (final IOException ignored) { } } diff --git a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java index e13bae6ce92d6c924be2076e64f3e05962aceaef..7303cb771756e8c11a27792433ee208751da1fb3 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,34 +146,27 @@ public final class StandardMidiFileReader extends MidiFileReader { @Override public MidiFileFormat getMidiFileFormat(URL url) throws InvalidMidiDataException, IOException { - InputStream urlStream = url.openStream(); // throws IOException - BufferedInputStream bis = new BufferedInputStream( urlStream, bisBufferSize ); - MidiFileFormat fileFormat = null; - try { - fileFormat = getMidiFileFormat( bis ); // throws InvalidMidiDataException - } finally { - bis.close(); + try (InputStream urlStream = url.openStream(); // throws IOException + BufferedInputStream bis = new BufferedInputStream(urlStream, bisBufferSize)) + { + MidiFileFormat fileFormat = getMidiFileFormat(bis); // throws InvalidMidiDataException + return fileFormat; } - return fileFormat; } @Override public MidiFileFormat getMidiFileFormat(File file) throws InvalidMidiDataException, IOException { - FileInputStream fis = new FileInputStream(file); // throws IOException - BufferedInputStream bis = new BufferedInputStream(fis, bisBufferSize); - - // $$fb 2002-04-17: part of fix for 4635286: MidiSystem.getMidiFileFormat() returns format having invalid length - long length = file.length(); - if (length > Integer.MAX_VALUE) { - length = MidiFileFormat.UNKNOWN_LENGTH; - } - MidiFileFormat fileFormat = null; - try { - fileFormat = getMidiFileFormatFromStream(bis, (int) length, null); - } finally { - bis.close(); + try (FileInputStream fis = new FileInputStream(file); // throws IOException + BufferedInputStream bis = new BufferedInputStream(fis, bisBufferSize)) + { + // $$fb 2002-04-17: part of fix for 4635286: MidiSystem.getMidiFileFormat() returns format having invalid length + long length = file.length(); + if (length > Integer.MAX_VALUE) { + length = MidiFileFormat.UNKNOWN_LENGTH; + } + MidiFileFormat fileFormat = getMidiFileFormatFromStream(bis, (int) length, null); + return fileFormat; } - return fileFormat; } @Override @@ -204,28 +197,22 @@ public final class StandardMidiFileReader extends MidiFileReader { @Override public Sequence getSequence(URL url) throws InvalidMidiDataException, IOException { - InputStream is = url.openStream(); // throws IOException - is = new BufferedInputStream(is, bisBufferSize); - Sequence seq = null; - try { - seq = getSequence(is); - } finally { - is.close(); + try (InputStream is = url.openStream(); // throws IOException + BufferedInputStream bis = new BufferedInputStream(is, bisBufferSize)) + { + Sequence seq = getSequence(bis); + return seq; } - return seq; } @Override public Sequence getSequence(File file) throws InvalidMidiDataException, IOException { - InputStream is = new FileInputStream(file); // throws IOException - is = new BufferedInputStream(is, bisBufferSize); - Sequence seq = null; - try { - seq = getSequence(is); - } finally { - is.close(); + try (InputStream is = new FileInputStream(file); // throws IOException + BufferedInputStream bis = new BufferedInputStream(is, bisBufferSize)) + { + Sequence seq = getSequence(bis); + return seq; } - return seq; } } @@ -392,6 +379,10 @@ final class SMFParser { // meta int metaType = readUnsigned(); int metaLength = (int) readVarInt(); + if (metaLength < 0) { + throw new InvalidMidiDataException("length out of bounds: " + + metaLength); + } final byte[] metaData; try { metaData = new byte[metaLength]; diff --git a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java index a46a2e4e46783e6c0ba748d3e32cb26c5c96aac7..7d96bfaebfc3dade1f61ca449686a20e1bf72473 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java @@ -129,10 +129,10 @@ public final class StandardMidiFileWriter extends MidiFileWriter { @Override public int write(Sequence in, int type, File out) throws IOException { Objects.requireNonNull(in); - FileOutputStream fos = new FileOutputStream(out); // throws IOException - int bytesWritten = write( in, type, fos ); - fos.close(); - return bytesWritten; + try (FileOutputStream fos = new FileOutputStream(out)) { // throws IOException + int bytesWritten = write(in, type, fos); + return bytesWritten; + } } //================================================================================= diff --git a/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java b/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java index 2c3be1507fc1c0d11fbd36ded942bf72304f19f2..f8365f7178080e6c1bac2e4361c8bdd50a36df80 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java @@ -73,6 +73,10 @@ public final class WaveFloatFileReader extends SunFileReader { samplerate = chunk.readUnsignedInt(); /* framerate = */chunk.readUnsignedInt(); framesize = chunk.readUnsignedShort(); + if (framesize == 0) { + throw new UnsupportedAudioFileException( + "Can not process audio format with 0 frame size"); + } bits = chunk.readUnsignedShort(); } if (chunk.getFormat().equals("data")) { diff --git a/src/java.desktop/share/classes/java/awt/BufferCapabilities.java b/src/java.desktop/share/classes/java/awt/BufferCapabilities.java index 8d2288023b54272084dd6072ce9ab134dfc187bd..22df13cfb5072998e55129e0343ef4838f9f7ff1 100644 --- a/src/java.desktop/share/classes/java/awt/BufferCapabilities.java +++ b/src/java.desktop/share/classes/java/awt/BufferCapabilities.java @@ -33,7 +33,6 @@ package java.awt; * @author Michael Martak * @since 1.4 */ -@SuppressWarnings("doclint:missing") public class BufferCapabilities implements Cloneable { private ImageCapabilities frontCaps; @@ -63,6 +62,8 @@ public class BufferCapabilities implements Cloneable { } /** + * Returns the image capabilities of the front (displayed) buffer. + * * @return the image capabilities of the front (displayed) buffer */ public ImageCapabilities getFrontBufferCapabilities() { @@ -70,6 +71,9 @@ public class BufferCapabilities implements Cloneable { } /** + * Returns the image capabilities of all back buffers (intermediate buffers + * are considered back buffers). + * * @return the image capabilities of all back buffers (intermediate buffers * are considered back buffers) */ @@ -78,27 +82,31 @@ public class BufferCapabilities implements Cloneable { } /** - * @return whether or not the buffer strategy uses page flipping; a set of - * buffers that uses page flipping + * Returns whether or not the buffer strategy uses page flipping. + * A set of buffers that uses page flipping * can swap the contents internally between the front buffer and one or * more back buffers by switching the video pointer (or by copying memory * internally). A non-flipping set of * buffers uses blitting to copy the contents from one buffer to * another; when this is the case, {@code getFlipContents} returns - * {@code null} + * {@code null}. + * + * @return whether or not the buffer strategy uses page flipping */ public boolean isPageFlipping() { return (getFlipContents() != null); } /** - * @return the resulting contents of the back buffer after page-flipping. + * Returns the resulting contents of the back buffer after page-flipping. * This value is {@code null} when the {@code isPageFlipping} * returns {@code false}, implying blitting. It can be one of * {@code FlipContents.UNDEFINED} * (the assumed default), {@code FlipContents.BACKGROUND}, * {@code FlipContents.PRIOR}, or * {@code FlipContents.COPIED}. + * + * @return the resulting contents of the back buffer after page-flipping * @see #isPageFlipping * @see FlipContents#UNDEFINED * @see FlipContents#BACKGROUND @@ -110,9 +118,11 @@ public class BufferCapabilities implements Cloneable { } /** - * @return whether page flipping is only available in full-screen mode. If this + * Returns whether page flipping is only available in full-screen mode. If this * is {@code true}, full-screen exclusive mode is required for * page-flipping. + * + * @return whether page flipping is only available in full-screen mode * @see #isPageFlipping * @see GraphicsDevice#setFullScreenWindow */ @@ -121,9 +131,12 @@ public class BufferCapabilities implements Cloneable { } /** - * @return whether or not + * Returns whether or not * page flipping can be performed using more than two buffers (one or more * intermediate buffers as well as the front and back buffer). + * + * @return whether or not + * page flipping can be performed using more than two buffers * @see #isPageFlipping */ public boolean isMultiBufferAvailable() { diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index 2378588b03385c21d568c613f44fa3d0aec4ccac..813f9bd0c796eea6b84f543004b91f85b48a52fc 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -214,7 +214,6 @@ import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.VSYNC_ON; * @author Arthur van Hoff * @author Sami Shaio */ -@SuppressWarnings("doclint:missing") public abstract class Component implements ImageObserver, MenuContainer, Serializable { @@ -4133,7 +4132,9 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * @return direct access to the back buffer, as an image. + * Provides direct access to the back buffer as an image. + * + * @return the back buffer as an image * @exception IllegalStateException if the buffers have not yet * been created */ @@ -4693,9 +4694,12 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * @return whether or not paint messages received from the operating system + * Returns whether or not paint messages received from the operating system * should be ignored. * + * @return whether or not paint messages received from the operating system + * should be ignored + * * @since 1.4 * @see #setIgnoreRepaint */ diff --git a/src/java.desktop/share/classes/java/awt/Font.java b/src/java.desktop/share/classes/java/awt/Font.java index 95087864d2a0e9bc663c86228055bfbd83a68d72..020bd95b3b37c95b45dd37535491384a525f9ba3 100644 --- a/src/java.desktop/share/classes/java/awt/Font.java +++ b/src/java.desktop/share/classes/java/awt/Font.java @@ -1131,7 +1131,7 @@ public class Font implements java.io.Serializable if (tracker != null) { tracker.set(tFile, outStream); } - try { + try (outStream) { /* don't close the input stream */ byte[] buf = new byte[8192]; for (;;) { int bytesRead = fontStream.read(buf); @@ -1152,9 +1152,6 @@ public class Font implements java.io.Serializable } outStream.write(buf, 0, bytesRead); } - /* don't close the input stream */ - } finally { - outStream.close(); } /* After all references to a Font2D are dropped, the file * will be removed. To support long-lived AppContexts, diff --git a/src/java.desktop/share/classes/java/awt/Graphics.java b/src/java.desktop/share/classes/java/awt/Graphics.java index 51cdd6a88da30d1f732fb09f58d621897c5e8d28..5ed31aeadb0565e5d14cbf539843c07f0d4ac1d8 100644 --- a/src/java.desktop/share/classes/java/awt/Graphics.java +++ b/src/java.desktop/share/classes/java/awt/Graphics.java @@ -1162,17 +1162,14 @@ public abstract class Graphics { /** * Disposes of this graphics context once it is no longer referenced. * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. + * * @see #dispose */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") public void finalize() { dispose(); } diff --git a/src/java.desktop/share/classes/java/awt/List.java b/src/java.desktop/share/classes/java/awt/List.java index 3877fcd3b3dba01866bfb16f88c6ba810c6aa3d5..f29374ab6bc062101dd13632dd42eeccaa246a82 100644 --- a/src/java.desktop/share/classes/java/awt/List.java +++ b/src/java.desktop/share/classes/java/awt/List.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1750,7 +1750,7 @@ public class List extends Component implements ItemSelectable, Accessible { /** * Get the Font of this object. * - * @return the Font,if supported, for the object; otherwise, null + * @return the Font, if supported, for the object; otherwise, null * @see #setFont */ public Font getFont() { diff --git a/src/java.desktop/share/classes/java/awt/MenuComponent.java b/src/java.desktop/share/classes/java/awt/MenuComponent.java index 0e7ab46cedf0391c0dfd0c1d77f4c673116db5d3..2550eea7f520f3f4eab189678a4e594d248cf47b 100644 --- a/src/java.desktop/share/classes/java/awt/MenuComponent.java +++ b/src/java.desktop/share/classes/java/awt/MenuComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -742,7 +742,7 @@ public abstract class MenuComponent implements java.io.Serializable { /** * Gets the {@code Font} of this object. * - * @return the {@code Font},if supported, for the object; + * @return the {@code Font}, if supported, for the object; * otherwise, {@code null} */ public Font getFont() { diff --git a/src/java.desktop/share/classes/java/awt/PrintJob.java b/src/java.desktop/share/classes/java/awt/PrintJob.java index a9e2bd8bea29aa1fb9eabf8962117548349e17e8..f4ea24efd97b383dd3d054320c8db8de5259f5a4 100644 --- a/src/java.desktop/share/classes/java/awt/PrintJob.java +++ b/src/java.desktop/share/classes/java/awt/PrintJob.java @@ -85,17 +85,14 @@ public abstract class PrintJob { /** * Ends this print job once it is no longer referenced. * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. + * * @see #end */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") public void finalize() { end(); } diff --git a/src/java.desktop/share/classes/java/awt/Toolkit.java b/src/java.desktop/share/classes/java/awt/Toolkit.java index 520d2d9bb9048cb974cd32f0984d2e170f979ff9..f3f4bcbb5c83041723e4d10ae329ab77dbcd2362 100644 --- a/src/java.desktop/share/classes/java/awt/Toolkit.java +++ b/src/java.desktop/share/classes/java/awt/Toolkit.java @@ -413,12 +413,10 @@ public abstract class Toolkit { File propsFile = new File( System.getProperty("user.home") + sep + ".accessibility.properties"); - FileInputStream in = - new FileInputStream(propsFile); - - // Inputstream has been buffered in Properties class - properties.load(in); - in.close(); + try (FileInputStream in = new FileInputStream(propsFile)) { + // Inputstream has been buffered in Properties class + properties.load(in); + } } catch (Exception e) { // Per-user accessibility properties file does not exist } @@ -431,12 +429,10 @@ public abstract class Toolkit { File propsFile = new File( System.getProperty("java.home") + sep + "conf" + sep + "accessibility.properties"); - FileInputStream in = - new FileInputStream(propsFile); - - // Inputstream has been buffered in Properties class - properties.load(in); - in.close(); + try (FileInputStream in = new FileInputStream(propsFile)) { + // Inputstream has been buffered in Properties class + properties.load(in); + } } catch (Exception e) { // System-wide accessibility properties file does // not exist; diff --git a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java index f416719fd2ec9498c65658e83212d9299e83eb88..21bf7ec17162b7f82ee974aa0d18070536243dfe 100644 --- a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java @@ -151,7 +151,6 @@ import sun.awt.AWTAccessor; * * @since 1.1 */ -@SuppressWarnings("doclint:missing") public class KeyEvent extends InputEvent { /** @@ -650,53 +649,142 @@ public class KeyEvent extends InputEvent { public static final int VK_KP_RIGHT = 0xE3; /* For European keyboards */ - /** @since 1.2 */ + /** + * Constant for the Dead Grave key. + * @since 1.2 + */ public static final int VK_DEAD_GRAVE = 0x80; - /** @since 1.2 */ + + /** + * Constant for the Dead Acute key. + * @since 1.2 + */ public static final int VK_DEAD_ACUTE = 0x81; - /** @since 1.2 */ + + /** + * Constant for the Dead Circumflex key. + * @since 1.2 + */ public static final int VK_DEAD_CIRCUMFLEX = 0x82; - /** @since 1.2 */ + + /** + * Constant for the Dead Tilde key. + * @since 1.2 + */ public static final int VK_DEAD_TILDE = 0x83; - /** @since 1.2 */ + + /** + * Constant for the Dead Macron key. + * @since 1.2 + */ public static final int VK_DEAD_MACRON = 0x84; - /** @since 1.2 */ + + /** + * Constant for the Dead Breve key. + * @since 1.2 + */ public static final int VK_DEAD_BREVE = 0x85; - /** @since 1.2 */ + + /** + * Constant for the Dead Above Dot key. + * @since 1.2 + */ public static final int VK_DEAD_ABOVEDOT = 0x86; - /** @since 1.2 */ + + /** + * Constant for the Dead Diaeresis key. + * @since 1.2 + */ public static final int VK_DEAD_DIAERESIS = 0x87; - /** @since 1.2 */ + + /** + * Constant for the Dead Above Ring key. + * @since 1.2 + */ public static final int VK_DEAD_ABOVERING = 0x88; - /** @since 1.2 */ + + /** + * Constant for the Dead Double Acute key. + * @since 1.2 + */ public static final int VK_DEAD_DOUBLEACUTE = 0x89; - /** @since 1.2 */ + + /** + * Constant for the Dead Caron key. + * @since 1.2 + */ public static final int VK_DEAD_CARON = 0x8a; - /** @since 1.2 */ + + /** + * Constant for the Dead Cedilla key. + * @since 1.2 + */ public static final int VK_DEAD_CEDILLA = 0x8b; - /** @since 1.2 */ + + /** + * Constant for the Dead Ogonek key. + * @since 1.2 + */ public static final int VK_DEAD_OGONEK = 0x8c; - /** @since 1.2 */ + + /** + * Constant for the Dead Iota key. + * @since 1.2 + */ public static final int VK_DEAD_IOTA = 0x8d; - /** @since 1.2 */ + + /** + * Constant for the Dead Voiced Sound key. + * @since 1.2 + */ public static final int VK_DEAD_VOICED_SOUND = 0x8e; - /** @since 1.2 */ + + /** + * Constant for the Dead Semivoiced Sound key. + * @since 1.2 + */ public static final int VK_DEAD_SEMIVOICED_SOUND = 0x8f; - /** @since 1.2 */ + /** + * Constant for the "&" key. + * @since 1.2 + */ public static final int VK_AMPERSAND = 0x96; - /** @since 1.2 */ + + /** + * Constant for the "*" key. + * @since 1.2 + */ public static final int VK_ASTERISK = 0x97; - /** @since 1.2 */ + + /** + * Constant for the """" key. + * @since 1.2 + */ public static final int VK_QUOTEDBL = 0x98; - /** @since 1.2 */ + + /** + * Constant for the "<" key. + * @since 1.2 + */ public static final int VK_LESS = 0x99; - /** @since 1.2 */ + /** + * Constant for the ">" key. + * @since 1.2 + */ public static final int VK_GREATER = 0xa0; - /** @since 1.2 */ + + /** + * Constant for the "{" key. + * @since 1.2 + */ public static final int VK_BRACELEFT = 0xa1; - /** @since 1.2 */ + + /** + * Constant for the "}" key. + * @since 1.2 + */ public static final int VK_BRACERIGHT = 0xa2; /** @@ -926,21 +1014,52 @@ public class KeyEvent extends InputEvent { public static final int VK_INPUT_METHOD_ON_OFF = 0x0107; /* for Sun keyboards */ - /** @since 1.2 */ + /** + * Constant for the Cut key. + * @since 1.2 + */ public static final int VK_CUT = 0xFFD1; - /** @since 1.2 */ + + /** + * Constant for the Copy key. + * @since 1.2 + */ public static final int VK_COPY = 0xFFCD; - /** @since 1.2 */ + + /** + * Constant for the Paste key. + * @since 1.2 + */ public static final int VK_PASTE = 0xFFCF; - /** @since 1.2 */ + + /** + * Constant for the Undo key. + * @since 1.2 + */ public static final int VK_UNDO = 0xFFCB; - /** @since 1.2 */ + + /** + * Constant for the Again key. + * @since 1.2 + */ public static final int VK_AGAIN = 0xFFC9; - /** @since 1.2 */ + + /** + * Constant for the Find key. + * @since 1.2 + */ public static final int VK_FIND = 0xFFD0; - /** @since 1.2 */ + + /** + * Constant for the Props key. + * @since 1.2 + */ public static final int VK_PROPS = 0xFFCA; - /** @since 1.2 */ + + /** + * Constant for the Stop key. + * @since 1.2 + */ public static final int VK_STOP = 0xFFC8; /** diff --git a/src/java.desktop/share/classes/java/awt/font/GlyphJustificationInfo.java b/src/java.desktop/share/classes/java/awt/font/GlyphJustificationInfo.java index c4a8a7452b6222f3776dc730fd002b734089013b..f9cc5d547f3afc3effcde46d44789020961444ac 100644 --- a/src/java.desktop/share/classes/java/awt/font/GlyphJustificationInfo.java +++ b/src/java.desktop/share/classes/java/awt/font/GlyphJustificationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -193,7 +193,7 @@ public final class GlyphJustificationInfo { public final int shrinkPriority; /** - * If {@code true},this glyph absorbs all remaining shrinkage at + * If {@code true}, this glyph absorbs all remaining shrinkage at * this and lower priority levels as it shrinks. */ public final boolean shrinkAbsorb; diff --git a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java index b6d98309ffcba1d3e1abd6a19bbe39c50fa4f79e..c12d63e995151708845f08b6dcb85400e6d89365 100644 --- a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java +++ b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java @@ -1533,12 +1533,7 @@ public final class NumericShaper implements java.io.Serializable { rangeArray = rangeSet.toArray(new Range[rangeSet.size()]); if (rangeArray.length > BSEARCH_THRESHOLD) { // sort rangeArray for binary search - Arrays.sort(rangeArray, - new Comparator() { - public int compare(Range s1, Range s2) { - return s1.base > s2.base ? 1 : s1.base == s2.base ? 0 : -1; - } - }); + Arrays.sort(rangeArray, Comparator.comparingInt(s -> s.base)); } } diff --git a/src/java.desktop/share/classes/java/awt/geom/Arc2D.java b/src/java.desktop/share/classes/java/awt/geom/Arc2D.java index 849cc4703797fdaaf6bc75639f038e7245c65777..16a891b2cc4728ec11b4f23f06eac3a6d2cf9a60 100644 --- a/src/java.desktop/share/classes/java/awt/geom/Arc2D.java +++ b/src/java.desktop/share/classes/java/awt/geom/Arc2D.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -777,7 +777,7 @@ public abstract class Arc2D extends RectangularShape { * elliptical boundary of the arc. * * @return A {@code Point2D} object representing the - * x,y coordinates of the ending point of the arc. + * x,y coordinates of the ending point of the arc. * @since 1.2 */ public Point2D getEndPoint() { diff --git a/src/java.desktop/share/classes/java/beans/Beans.java b/src/java.desktop/share/classes/java/beans/Beans.java index 3be687b10e5cb901a71a2cc7ded2bc2013d077c5..dbe678b70927e881cc8446bb0e3758bd9f19c8e6 100644 --- a/src/java.desktop/share/classes/java/beans/Beans.java +++ b/src/java.desktop/share/classes/java/beans/Beans.java @@ -201,7 +201,7 @@ public class Beans { else ins = cls.getResourceAsStream(serName); if (ins != null) { - try { + try (ins) { if (cls == null) { oins = new ObjectInputStream(ins); } else { @@ -211,13 +211,9 @@ public class Beans { serialized = true; oins.close(); } catch (IOException ex) { - ins.close(); // Drop through and try opening the class. But remember // the exception in case we can't find the class either. serex = ex; - } catch (ClassNotFoundException ex) { - ins.close(); - throw ex; } } diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java index d3e6c6ea87a485715b543b57846e4e0156d97290..21e136ba9e5e3c6201f97b8d0bc83d8cefc51e42 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java @@ -54,7 +54,6 @@ import java.util.TooManyListenersException; * @author Laurence P. G. Cable * @since 1.2 */ -@SuppressWarnings("doclint:missing") public class BeanContextServicesSupport extends BeanContextSupport implements BeanContextServices { @@ -157,6 +156,10 @@ public class BeanContextServicesSupport extends BeanContextSupport * when the BeanContextSupport is serialized. */ + /** + * A protected nested class containing per-child information + * in the {@code children} hashtable. + */ protected class BCSSChild extends BeanContextSupport.BCSChild { /** @@ -787,6 +790,10 @@ public class BeanContextServicesSupport extends BeanContextSupport * to an enclosing BeanContext. */ + /** + * Subclasses may subclass this nested class to represent a proxy for + * each BeanContextServiceProvider. + */ protected class BCSSProxyServiceProvider implements BeanContextServiceProvider, BeanContextServiceRevokedListener { BCSSProxyServiceProvider(BeanContextServices bcs) { diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java index e5e53db3dfe6edfd8de96fb43eb86afc15f0b511..66b0995bf021e452acd25884610b24ed6a8903b4 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java @@ -59,7 +59,6 @@ import java.util.Map; * @author Laurence P. G. Cable * @since 1.2 */ -@SuppressWarnings("doclint:missing") public class BeanContextSupport extends BeanContextChildSupport implements BeanContext, Serializable, @@ -305,13 +304,17 @@ public class BeanContextSupport extends BeanContextChildSupport * when the BeanContextSupport is serialized. */ - protected class BCSChild implements Serializable { - /** - * Use serialVersionUID from JDK 1.7 for interoperability. + * A protected nested class containing per-child information + * in the {@code children} hashtable. */ - @Serial - private static final long serialVersionUID = -5815286101609939109L; + protected class BCSChild implements Serializable { + + /** + * Use serialVersionUID from JDK 1.7 for interoperability. + */ + @Serial + private static final long serialVersionUID = -5815286101609939109L; BCSChild(Object bcc, Object peer) { super(); diff --git a/src/java.desktop/share/classes/javax/imageio/ImageIO.java b/src/java.desktop/share/classes/javax/imageio/ImageIO.java index 04793b6f46498ef3888db5f925a8416b2014004d..8c62ef92b116bd11546fe61dc90740bf909170e9 100644 --- a/src/java.desktop/share/classes/javax/imageio/ImageIO.java +++ b/src/java.desktop/share/classes/javax/imageio/ImageIO.java @@ -39,8 +39,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Set; import javax.imageio.spi.IIORegistry; import javax.imageio.spi.ImageReaderSpi; import javax.imageio.spi.ImageReaderWriterSpi; @@ -1402,7 +1400,7 @@ public final class ImageIO { throw new IllegalArgumentException("input == null!"); } - InputStream istream = null; + InputStream istream; try { istream = input.openStream(); } catch (IOException e) { @@ -1418,13 +1416,11 @@ public final class ImageIO { throw new IIOException("Can't create an ImageInputStream!"); } BufferedImage bi; - try { + try (istream) { bi = read(stream); if (bi == null) { stream.close(); } - } finally { - istream.close(); } return bi; } @@ -1466,11 +1462,10 @@ public final class ImageIO { ImageReadParam param = reader.getDefaultReadParam(); reader.setInput(stream, true, true); BufferedImage bi; - try { + try (stream) { bi = reader.read(0, param); } finally { reader.dispose(); - stream.close(); } return bi; } @@ -1552,10 +1547,8 @@ public final class ImageIO { if (stream == null) { throw new IIOException("Can't create an ImageOutputStream!"); } - try { + try (stream) { return doWrite(im, writer, stream); - } finally { - stream.close(); } } @@ -1592,10 +1585,8 @@ public final class ImageIO { if (stream == null) { throw new IIOException("Can't create an ImageOutputStream!"); } - try { + try (stream) { return doWrite(im, getWriter(im, formatName), stream); - } finally { - stream.close(); } } diff --git a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java index 741ca55c5010efa9dbae99e6ec7c6e7b19387a72..4a43ca8133a5b7d14f12d270021441896dca8c21 100644 --- a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java +++ b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java @@ -680,16 +680,12 @@ public class ServiceRegistry { * @exception Throwable if an error occurs during superclass * finalization. * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") public void finalize() throws Throwable { deregisterAll(); super.finalize(); @@ -842,7 +838,7 @@ class SubRegistry { accMap.clear(); } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") public synchronized void finalize() { clear(); } diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java index e597490016123cfb7de02b451ca375e131d96c9f..6bf14838b7fc42d0e4ee853e9ff9f710033ec228 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java @@ -261,16 +261,12 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl { /** * {@inheritDoc} * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") protected void finalize() throws Throwable { // Empty finalizer: for performance reasons we instead use the // Disposer mechanism for ensuring that the underlying diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileImageInputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileImageInputStream.java index 7ecc28767a0284881d37335ea094e0548604ed61..b1cce6fae4cc64bd98db88d535e8cb088b9478f6 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileImageInputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileImageInputStream.java @@ -156,16 +156,12 @@ public class FileImageInputStream extends ImageInputStreamImpl { /** * {@inheritDoc} * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") protected void finalize() throws Throwable { // Empty finalizer: for performance reasons we instead use the // Disposer mechanism for ensuring that the underlying diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java index e75c40396d8157a1957f75e27ffd887f06c006a7..715b43f40fb764aa4b3df57941cef1959c7029d6 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java @@ -164,16 +164,12 @@ public class FileImageOutputStream extends ImageOutputStreamImpl { /** * {@inheritDoc} * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") protected void finalize() throws Throwable { // Empty finalizer: for performance reasons we instead use the // Disposer mechanism for ensuring that the underlying diff --git a/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStream.java index 6c05a7183c9e7b1790c1693762f3aa23d3b62847..d8999d4a884de701c13da49bef0568403cb7c557 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -393,7 +393,7 @@ public interface ImageInputStream extends DataInput, Closeable { * zero-extension. If the character {@code '\n'} is * encountered, it is discarded and reading ceases. If the * character {@code '\r'} is encountered, it is discarded - * and, if the following byte converts to the character + * and, if the following byte converts to the character * {@code '\n'}, then that is discarded also; reading then * ceases. If end of file is encountered before either of the * characters {@code '\n'} and {@code '\r'} is diff --git a/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStreamImpl.java b/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStreamImpl.java index c7cdc47cdafc3698312db86ea154b65573f78a68..053bbf7491826e852d0b0f466f68edf37841e0f7 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStreamImpl.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStreamImpl.java @@ -868,16 +868,12 @@ public abstract class ImageInputStreamImpl implements ImageInputStream { * @exception Throwable if an error occurs during superclass * finalization. * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") protected void finalize() throws Throwable { if (!isClosed) { try { diff --git a/src/java.desktop/share/classes/javax/imageio/stream/MemoryCacheImageInputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/MemoryCacheImageInputStream.java index 4fcb0f40b8171a3e136bc30bfe5fc6abf0670af8..44b9d8cd5fbf9c0b3ce2130da8ed12b1bb9dd9f8 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/MemoryCacheImageInputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/MemoryCacheImageInputStream.java @@ -179,16 +179,12 @@ public class MemoryCacheImageInputStream extends ImageInputStreamImpl { /** * {@inheritDoc} * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for background information and details + * about migration options. */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval=true) + @SuppressWarnings("removal") protected void finalize() throws Throwable { // Empty finalizer: for performance reasons we instead use the // Disposer mechanism for ensuring that the underlying diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReason.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReason.java index f5ab4103098963140a4b0ff1dce1dc451949c840..2f8526cb7b15a48038fa1943e0ae1f32380e2737 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReason.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReason.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,7 +89,7 @@ public class JobStateReason extends EnumSyntax implements Attribute { /** * The printer could not access one or more documents passed by reference * (i.e., the print data representation object is a {@code URL}). This - * reason is intended to cover any file access problem,including file does + * reason is intended to cover any file access problem, including file does * not exist and access denied because of an access control problem. Whether * the printer aborts the job and moves the job to the {@code ABORTED} job * state or prints all documents that are accessible and moves the job to diff --git a/src/java.desktop/share/classes/javax/sound/midi/Sequencer.java b/src/java.desktop/share/classes/javax/sound/midi/Sequencer.java index 4ee2cbcfd5a6942cbdf4a44339e632cc2f65b1ef..f51cb37342761928586e07cd6caeabe04e6e5ed7 100644 --- a/src/java.desktop/share/classes/javax/sound/midi/Sequencer.java +++ b/src/java.desktop/share/classes/javax/sound/midi/Sequencer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -472,7 +472,7 @@ public interface Sequencer extends MidiDevice { /** * Registers a meta-event listener to receive notification whenever a * meta-event is encountered in the sequence and processed by the sequencer. - * This method can fail if, for instance,this class of sequencer does not + * This method can fail if, for instance, this class of sequencer does not * support meta-event notification. * * @param listener listener to add diff --git a/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java b/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java index 1924df3123e2ad703da27accfc6e230cbe0b4c74..55b8fbba66cfac1f2bc1ff0c6e2ea4b04876a083 100644 --- a/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java +++ b/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java @@ -50,8 +50,7 @@ import javax.swing.event.*; * @see ListSelectionModel * @since 1.2 */ -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public class DefaultListSelectionModel implements ListSelectionModel, Cloneable, Serializable { private static final int MIN = -1; @@ -206,6 +205,11 @@ public class DefaultListSelectionModel implements ListSelectionModel, Cloneable, } /** + * Notifies ListSelectionListeners that the value + * of the selection, in the closed interval firstIndex, + * lastIndex, has changed and if this is the final change + * in the series of adjustments. + * * @param firstIndex the first index in the interval * @param lastIndex the last index in the interval * @param isAdjusting true if this is the final change in a series of diff --git a/src/java.desktop/share/classes/javax/swing/JApplet.java b/src/java.desktop/share/classes/javax/swing/JApplet.java index a1ba64dcf0dd76ef00a15e0583a0e9776baa427c..a1d51bf0069f10791400c3b1682273c1fdc2e58c 100644 --- a/src/java.desktop/share/classes/javax/swing/JApplet.java +++ b/src/java.desktop/share/classes/javax/swing/JApplet.java @@ -99,13 +99,15 @@ import javax.accessibility.AccessibleContext; @Deprecated(since = "9", forRemoval = true) @JavaBean(defaultProperty = "JMenuBar", description = "Swing's Applet subclass.") @SwingContainer(delegate = "getContentPane") -@SuppressWarnings({"serial", "removal", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial", "removal"}) // Same-version serialization only public class JApplet extends Applet implements Accessible, RootPaneContainer, TransferHandler.HasGetTransferHandler { /** + * The JRootPane instance that manages the + * contentPane. + * * @see #getRootPane * @see #setRootPane */ diff --git a/src/java.desktop/share/classes/javax/swing/JDialog.java b/src/java.desktop/share/classes/javax/swing/JDialog.java index 97013e59a6b298e670a706fd26435cf4f039033b..ace7d15adad89215b6edc2c99a5e4b7b7ad02a9a 100644 --- a/src/java.desktop/share/classes/javax/swing/JDialog.java +++ b/src/java.desktop/share/classes/javax/swing/JDialog.java @@ -95,8 +95,7 @@ import javax.accessibility.*; */ @JavaBean(defaultProperty = "JMenuBar", description = "A toplevel window for creating dialog boxes.") @SwingContainer(delegate = "getContentPane") -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public class JDialog extends Dialog implements WindowConstants, Accessible, RootPaneContainer, @@ -112,6 +111,9 @@ public class JDialog extends Dialog implements WindowConstants, private int defaultCloseOperation = HIDE_ON_CLOSE; /** + * The JRootPane instance that manages the + * contentPane. + * * @see #getRootPane * @see #setRootPane */ diff --git a/src/java.desktop/share/classes/javax/swing/JEditorPane.java b/src/java.desktop/share/classes/javax/swing/JEditorPane.java index 6d708f1b8b8d9e32491f6bcefee24ed90cd237b5..6b9189d550d584c851e9e7a1c93127bc92a9e6f1 100644 --- a/src/java.desktop/share/classes/javax/swing/JEditorPane.java +++ b/src/java.desktop/share/classes/javax/swing/JEditorPane.java @@ -41,6 +41,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectOutputStream; +import java.io.OutputStream; import java.io.Reader; import java.io.Serial; import java.io.StringReader; @@ -852,16 +853,12 @@ public class JEditorPane extends JTextComponent { private void handlePostData(HttpURLConnection conn, Object postData) throws IOException { conn.setDoOutput(true); - DataOutputStream os = null; - try { - conn.setRequestProperty("Content-Type", - "application/x-www-form-urlencoded"); - os = new DataOutputStream(conn.getOutputStream()); - os.writeBytes((String) postData); - } finally { - if (os != null) { - os.close(); - } + conn.setRequestProperty("Content-Type", + "application/x-www-form-urlencoded"); + try (OutputStream os = conn.getOutputStream(); + DataOutputStream dos = new DataOutputStream(os)) + { + dos.writeBytes((String)postData); } } diff --git a/src/java.desktop/share/classes/javax/swing/JFileChooser.java b/src/java.desktop/share/classes/javax/swing/JFileChooser.java index 544f4ee953bb356a9390fa3a779de7d5e4ca42ef..8d286e05f3bab1f030e805182ae1aa6ba968051a 100644 --- a/src/java.desktop/share/classes/javax/swing/JFileChooser.java +++ b/src/java.desktop/share/classes/javax/swing/JFileChooser.java @@ -1412,7 +1412,8 @@ public class JFileChooser extends JComponent implements Accessible { /** * Returns true if hidden files are not shown in the file chooser; - * otherwise, returns false. + * otherwise, returns false. The default value of this property may be + * derived from the underlying Operating System. * * @return the status of the file hiding property * @see #setFileHidingEnabled diff --git a/src/java.desktop/share/classes/javax/swing/JLabel.java b/src/java.desktop/share/classes/javax/swing/JLabel.java index bb1db1fdfb80e1494a21427e9cff1ec98ee780d9..8dff4a8fd25b3ba8eacd741730138d189071d537 100644 --- a/src/java.desktop/share/classes/javax/swing/JLabel.java +++ b/src/java.desktop/share/classes/javax/swing/JLabel.java @@ -1075,6 +1075,10 @@ public class JLabel extends JComponent implements SwingConstants, Accessible * @see AccessibleContext#setAccessibleName */ public String getAccessibleName() { + return getAccessibleNameCheckIcon(getAccessibleNameImpl()); + } + + private String getAccessibleNameImpl() { String name = accessibleName; if (name == null) { @@ -1089,6 +1093,19 @@ public class JLabel extends JComponent implements SwingConstants, Accessible return name; } + private String getAccessibleNameCheckIcon(String name) { + if (((name == null) || name.isEmpty()) && + (JLabel.this.getIcon() != null)) { + if (JLabel.this.getIcon() instanceof Accessible) { + AccessibleContext ac = ((Accessible) JLabel.this.getIcon()).getAccessibleContext(); + if (ac != null) { + name = ac.getAccessibleName(); + } + } + } + return name; + } + /** * Get the role of this object. * @@ -1097,6 +1114,11 @@ public class JLabel extends JComponent implements SwingConstants, Accessible * @see AccessibleRole */ public AccessibleRole getAccessibleRole() { + String name = getAccessibleNameImpl(); + if (((name == null) || name.isEmpty()) && + (JLabel.this.getIcon() != null)) { + return AccessibleRole.ICON; + } return AccessibleRole.LABEL; } diff --git a/src/java.desktop/share/classes/javax/swing/JScrollBar.java b/src/java.desktop/share/classes/javax/swing/JScrollBar.java index 25cdb0886a9867236ba796712658a152de4f97d0..6bb997a6150321932bd17b41c9a2e6b1f6bcb4ac 100644 --- a/src/java.desktop/share/classes/javax/swing/JScrollBar.java +++ b/src/java.desktop/share/classes/javax/swing/JScrollBar.java @@ -83,8 +83,7 @@ import javax.swing.plaf.ScrollBarUI; */ @JavaBean(defaultProperty = "UI", description = "A component that helps determine the visible content range of an area.") @SwingContainer(false) -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public class JScrollBar extends JComponent implements Adjustable, Accessible { /** @@ -109,18 +108,26 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible /** + * Orientation of this scrollBar. + * * @see #setOrientation */ protected int orientation; /** + * Stores the amount by which the value of the scrollbar is changed + * upon a unit up/down request. + * * @see #setUnitIncrement */ protected int unitIncrement; /** + * Stores the amount by which the value of the scrollbar is changed + * upon a block (usually "page") up/down request. + * * @see #setBlockIncrement */ protected int blockIncrement; diff --git a/src/java.desktop/share/classes/javax/swing/UIManager.java b/src/java.desktop/share/classes/javax/swing/UIManager.java index 570cd6e2f3414c6a6a3c11031840758dc78f8218..309aaa7447e31b4fd762e0139bd2300dab62fff0 100644 --- a/src/java.desktop/share/classes/javax/swing/UIManager.java +++ b/src/java.desktop/share/classes/javax/swing/UIManager.java @@ -57,7 +57,6 @@ import sun.awt.SunToolkit; import sun.awt.OSInfo; import sun.security.action.GetPropertyAction; import sun.swing.SwingUtilities2; -import java.lang.reflect.Method; import java.util.HashMap; import java.util.Objects; import sun.awt.AppContext; @@ -1301,9 +1300,9 @@ public class UIManager implements Serializable if (file.exists()) { // InputStream has been buffered in Properties // class - FileInputStream ins = new FileInputStream(file); - props.load(ins); - ins.close(); + try (FileInputStream ins = new FileInputStream(file)) { + props.load(ins); + } } } catch (Exception e) { diff --git a/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java b/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java index 0f30ef14d88c2de6e46c5ac0f86ebfc95714e9c2..8b0b1190aefbca244771f13be3df4bf616e1a96a 100644 --- a/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java +++ b/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java @@ -65,7 +65,6 @@ import sun.awt.shell.ShellFolder; // PENDING(jeff) - need to provide a specification for // how Mac/OS2/BeOS/etc file systems can modify FileSystemView // to handle their particular type of file system. -@SuppressWarnings("doclint:missing") public abstract class FileSystemView { static FileSystemView windowsFileSystemView = null; @@ -348,13 +347,14 @@ public abstract class FileSystemView { } /** + * Returns a File object which is normally constructed with new + * File(parent, fileName) except when the parent and child are both + * special folders, in which case the File is a wrapper containing + * a ShellFolder object. * * @param parent a File object representing a directory or special folder * @param fileName a name of a file or folder which exists in parent - * @return a File object. This is normally constructed with new - * File(parent, fileName) except when parent and child are both - * special folders, in which case the File is a wrapper containing - * a ShellFolder object. + * @return a File object. * @since 1.4 */ public File getChild(File parent, String fileName) { diff --git a/src/java.desktop/share/classes/javax/swing/package-info.java b/src/java.desktop/share/classes/javax/swing/package-info.java index 29509af1f4c15dee235be48f78085cb6872c3079..a75e62ebf4a720ad314f60eec97a22e82f0dae9b 100644 --- a/src/java.desktop/share/classes/javax/swing/package-info.java +++ b/src/java.desktop/share/classes/javax/swing/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -132,15 +132,12 @@ * For overviews, tutorials, examples, guides, and other documentation, * please see: *

      * * @serial exclude diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java index 33f42da00f8270734d2f2d52bc82f4a8e476a79f..439101c0ef28af39685a98ea00f449a9913592e3 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,21 +25,58 @@ package javax.swing.plaf.basic; -import javax.swing.*; -import javax.swing.filechooser.*; -import javax.swing.filechooser.FileFilter; -import javax.swing.event.*; -import javax.swing.plaf.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.datatransfer.*; -import java.beans.*; -import java.io.*; -import java.util.*; +import java.awt.BorderLayout; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Hashtable; import java.util.List; -import java.util.regex.*; +import java.util.Locale; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.Icon; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFileChooser; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; +import javax.swing.TransferHandler; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileSystemView; +import javax.swing.filechooser.FileView; +import javax.swing.plaf.ActionMapUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.FileChooserUI; +import javax.swing.plaf.UIResource; + import sun.awt.shell.ShellFolder; -import sun.swing.*; +import sun.swing.DefaultLookup; +import sun.swing.FilePane; +import sun.swing.SwingUtilities2; +import sun.swing.UIAction; /** * Basic L&F implementation of a FileChooser. @@ -723,11 +760,12 @@ public class BasicFileChooserUI extends FileChooserUI { // new functionality add it to the Handler, but make sure this // class calls into the Handler. Handler handler; + /** - * Constucts a {@code DoubleClickListener}. - * @param list the lsit + * Constructs a {@code DoubleClickListener}. + * @param list the list */ - public DoubleClickListener(JList list) { + public DoubleClickListener(JList list) { handler = new Handler(list); } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java index fa6a531276715b58591f6b1544670e847f83d5fe..db9eee52f1f86cc70cbe3727cd53fac289b990d2 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -45,7 +45,6 @@ import sun.swing.*; * @author Arnaud Weber * @author Fredrik Lagerblad */ -@SuppressWarnings("doclint:missing") public class BasicMenuItemUI extends MenuItemUI { /** @@ -257,6 +256,7 @@ public class BasicMenuItemUI extends MenuItemUI } /** + * Registers the subcomponents of the menu. * * @param menuItem a menu item * @since 1.3 diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java index 78727a729c4228066672f8b20c3e3a019aafcee5..0d2b0fde15e9c1897743b8d541e9088da5771665 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java @@ -46,7 +46,6 @@ import java.util.ArrayList; * @author David Karlton * @author Arnaud Weber */ -@SuppressWarnings("doclint:missing") public class BasicMenuUI extends BasicMenuItemUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java index afb2d58b88519950d977639147fed2e80ad57587..8c7f348097e09fa510993276190579ccef3717c2 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,18 +25,47 @@ package javax.swing.plaf.basic; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.BoundedRangeModel; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; +import javax.swing.JViewport; +import javax.swing.LookAndFeel; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.ScrollBarUI; +import javax.swing.plaf.UIResource; + import sun.swing.DefaultLookup; import sun.swing.UIAction; -import java.awt.*; -import java.awt.event.*; - -import java.beans.*; - -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.plaf.*; - import static sun.swing.SwingUtilities2.drawHLine; import static sun.swing.SwingUtilities2.drawRect; import static sun.swing.SwingUtilities2.drawVLine; @@ -754,7 +783,7 @@ public class BasicScrollBarUI } /** - * Laysouts a vertical scroll bar. + * Lays out a vertical scroll bar. * @param sb the scroll bar */ protected void layoutVScrollbar(JScrollBar sb) @@ -856,7 +885,7 @@ public class BasicScrollBarUI } /** - * Laysouts a vertical scroll bar. + * Lays out a horizontal scroll bar. * @param sb the scroll bar */ protected void layoutHScrollbar(JScrollBar sb) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java index c9e5fd51f7fe194eeeb2165141d1174e9eb5830e..360e98eee7af162de68e894798021356165e92ff 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,21 +25,60 @@ package javax.swing.plaf.basic; -import sun.swing.SwingUtilities2; - -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.plaf.*; -import javax.swing.text.View; - -import java.awt.*; -import java.awt.event.*; -import java.beans.PropertyChangeListener; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Point; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; import java.beans.PropertyChangeEvent; -import java.util.Vector; +import java.beans.PropertyChangeListener; import java.util.Hashtable; +import java.util.Vector; + +import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.Icon; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.JViewport; +import javax.swing.KeyStroke; +import javax.swing.LookAndFeel; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.ComponentInputMapUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.TabbedPaneUI; +import javax.swing.plaf.UIResource; +import javax.swing.text.View; import sun.swing.DefaultLookup; +import sun.swing.SwingUtilities2; import sun.swing.UIAction; /** @@ -216,7 +255,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { public BasicTabbedPaneUI() {} /** - * Create a UI. + * Creates a UI. * @param c a component * @return a UI */ @@ -386,7 +425,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Install the defaults. + * Installs the defaults. */ protected void installDefaults() { LookAndFeel.installColorsAndFont(tabPane, "TabbedPane.background", @@ -423,7 +462,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Uninstall the defaults. + * Uninstalls the defaults. */ protected void uninstallDefaults() { highlight = null; @@ -438,7 +477,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Install the listeners. + * Installs the listeners. */ protected void installListeners() { if ((propertyChangeListener = createPropertyChangeListener()) != null) { @@ -461,7 +500,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Uninstall the listeners. + * Uninstalls the listeners. */ protected void uninstallListeners() { if (mouseListener != null) { @@ -916,7 +955,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { * Paints a tab. * @param g the graphics * @param tabPlacement the tab placement - * @param rects rectangles + * @param rects the tab rectangles * @param tabIndex the tab index * @param iconRect the icon rectangle * @param textRect the text rectangle @@ -1090,9 +1129,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Laysout a label. + * Lays out a label. * @param tabPlacement the tab placement - * @param metrics the font metric + * @param metrics the font metrics * @param tabIndex the tab index * @param title the title * @param icon the icon @@ -1262,7 +1301,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { * Paints the focus indicator. * @param g the graphics * @param tabPlacement the tab placement - * @param rects rectangles + * @param rects the tab rectangles * @param tabIndex the tab index * @param iconRect the icon rectangle * @param textRect the text rectangle @@ -1307,9 +1346,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * this function draws the border around each tab - * note that this function does now draw the background of the tab. - * that is done elsewhere + * Paints the border around a tab. + * Note that this function does not paint the background of the tab, + * that is done elsewhere. * * @param g the graphics context in which to paint * @param tabPlacement the placement (left, right, bottom, top) of the tab @@ -1839,7 +1878,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Assure the rectangles are created. + * Assures the tab rectangles are created. * @param tabCount the tab count */ protected void assureRectsCreated(int tabCount) { @@ -2144,7 +2183,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { // Tab Navigation methods /** - * Navigate the selected tab. + * Navigates the selected tab. * @param direction the direction */ protected void navigateSelectedTab(int direction) { @@ -2226,7 +2265,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Select the next tab in the run. + * Selects the next tab in the run. * @param current the current tab */ protected void selectNextTabInRun(int current) { @@ -2240,7 +2279,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Select the previous tab in the run. + * Selects the previous tab in the run. * @param current the current tab */ protected void selectPreviousTabInRun(int current) { @@ -2254,7 +2293,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Select the next tab. + * Selects the next tab. * @param current the current tab */ protected void selectNextTab(int current) { @@ -2267,7 +2306,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Select the previous tab. + * Selects the previous tab. * @param current the current tab */ protected void selectPreviousTab(int current) { @@ -2772,7 +2811,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { * Returns the preferred tab area width. * @param tabPlacement the tab placement * @param height the height - * @return the preferred tab area widty + * @return the preferred tab area width */ protected int preferredTabAreaWidth(int tabPlacement, int height) { FontMetrics metrics = getFontMetrics(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java index c4ec26c56325bcb43f707332243348eccc7d6919..37ebb12823cd71ddd5f1429481a5908fbb06b595 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java @@ -27,16 +27,11 @@ package javax.swing.plaf.basic; import java.awt.*; import java.awt.datatransfer.*; -import java.awt.dnd.*; import java.awt.event.*; import java.util.Enumeration; -import java.util.EventObject; -import java.util.Hashtable; -import java.util.TooManyListenersException; import javax.swing.*; import javax.swing.event.*; import javax.swing.plaf.*; -import javax.swing.text.*; import javax.swing.table.*; import javax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag; import sun.swing.SwingUtilities2; @@ -221,8 +216,8 @@ public class BasicTableUI extends TableUI this.inSelection = true; // look at the sign of dx and dy only - dx = sign(dx); - dy = sign(dy); + dx = Integer.signum(dx); + dy = Integer.signum(dy); // make sure one is zero, but not both assert (dx == 0 || dy == 0) && !(dx == 0 && dy == 0); @@ -250,10 +245,6 @@ public class BasicTableUI extends TableUI leadColumn = clipToRange(leadColumn+dx, 0, table.getColumnCount()); } - private static int sign(int num) { - return (num < 0) ? -1 : ((num == 0) ? 0 : 1); - } - /** * Called to move within the selected range of the given JTable. * This method uses the table's notion of selection, which is diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java index 9513b723490f18a03c51cfd4b2272d06dacd0a29..d43dd59544a752f9145b65298a66912d81983736 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java @@ -47,7 +47,6 @@ import sun.swing.SwingUtilities2; * Factory object that can vend Borders appropriate for the metal L & F. * @author Steve Wilson */ -@SuppressWarnings("doclint:missing") public class MetalBorders { /** @@ -926,7 +925,7 @@ public class MetalBorders { } /** - * The class represents the border of a {@code JTestField}. + * Border for a {@code JTextField}. */ @SuppressWarnings("serial") // Superclass is not serializable across versions public static class TextFieldBorder extends Flush3DBorder { @@ -1027,6 +1026,8 @@ public class MetalBorders { } /** + * Border for a {@code JToggleButton}. + * * @since 1.3 */ @SuppressWarnings("serial") // Superclass is not serializable across versions diff --git a/src/java.desktop/share/classes/javax/swing/table/TableCellEditor.java b/src/java.desktop/share/classes/javax/swing/table/TableCellEditor.java index a0bcb391ba3eb9569815106563fb580f0e33e8bb..21b7034a55c4071eedb6a8a3246177743c51e36e 100644 --- a/src/java.desktop/share/classes/javax/swing/table/TableCellEditor.java +++ b/src/java.desktop/share/classes/javax/swing/table/TableCellEditor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,13 +27,11 @@ package javax.swing.table; import java.awt.Component; import javax.swing.CellEditor; -import javax.swing.*; +import javax.swing.JTable; /** - * This interface defines the method any object that would like to be - * an editor of values for components such as JListBox, - * JComboBox, JTree, or JTable - * needs to implement. + * This interface must be implemented to provide an editor of cell values + * for a {@code JTable}. * * @author Alan Chung */ diff --git a/src/java.desktop/share/classes/javax/swing/text/GapContent.java b/src/java.desktop/share/classes/javax/swing/text/GapContent.java index 0f377c5059a7ff00ff265794f5511e8818742eda..c59c350541b117fad90cd1c992cb4d5fe88d5836 100644 --- a/src/java.desktop/share/classes/javax/swing/text/GapContent.java +++ b/src/java.desktop/share/classes/javax/swing/text/GapContent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -504,13 +504,7 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S * @return < 0 if o1 < o2, 0 if the same, > 0 if o1 > o2 */ final int compare(MarkData o1, MarkData o2) { - if (o1.index < o2.index) { - return -1; - } else if (o1.index > o2.index) { - return 1; - } else { - return 0; - } + return Integer.compare(o1.index, o2.index); } /** diff --git a/src/java.desktop/share/classes/javax/swing/text/LayeredHighlighter.java b/src/java.desktop/share/classes/javax/swing/text/LayeredHighlighter.java index c50710233fcc561cb0e22844c18e7f84148d3205..e484a0d9af29a46bd538f4c9efe882ba520521da 100644 --- a/src/java.desktop/share/classes/javax/swing/text/LayeredHighlighter.java +++ b/src/java.desktop/share/classes/javax/swing/text/LayeredHighlighter.java @@ -28,12 +28,13 @@ import java.awt.Graphics; import java.awt.Shape; /** + * Implementation of {@code Highlighter} interface to mark up the + * background of leaf views with colored areas. * * @author Scott Violet * @author Timothy Prinzing * @see Highlighter */ -@SuppressWarnings("doclint:missing") public abstract class LayeredHighlighter implements Highlighter { /** * Constructor for subclasses to call. @@ -68,6 +69,8 @@ public abstract class LayeredHighlighter implements Highlighter { protected LayerPainter() {} /** + * Paints a portion of a highlight. + * * @return a shape * @param g Graphics used to draw * @param p0 starting offset of view diff --git a/src/java.desktop/share/classes/javax/swing/text/MaskFormatter.java b/src/java.desktop/share/classes/javax/swing/text/MaskFormatter.java index 017787dd4258185b5ad7fd6737650bad9f13b9d3..0377b328b791d33b403dedbcee50a94938eb0c6a 100644 --- a/src/java.desktop/share/classes/javax/swing/text/MaskFormatter.java +++ b/src/java.desktop/share/classes/javax/swing/text/MaskFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,13 @@ package javax.swing.text; -import java.io.*; -import java.text.*; -import java.util.*; -import javax.swing.*; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serial; +import java.text.ParseException; +import java.util.ArrayList; +import javax.swing.JFormattedTextField; +import javax.swing.text.DefaultFormatter; /** * MaskFormatter is used to format and edit strings. The behavior @@ -100,7 +103,7 @@ import javax.swing.*; *
        *   MaskFormatter formatter = new MaskFormatter("###-####");
        *   formatter.setPlaceholderCharacter('_');
      - *   formatter.getDisplayValue(tf, "123");
      + *   System.out.println(formatter.valueToString("123"));
        * 
      *

      * Would result in the string '123-____'. If diff --git a/src/java.desktop/share/classes/javax/swing/text/StringContent.java b/src/java.desktop/share/classes/javax/swing/text/StringContent.java index c66156a39f202898a3a39734e94e0823aedc690e..7f154df38edffce7203667f93ff9980c0c6268ba 100644 --- a/src/java.desktop/share/classes/javax/swing/text/StringContent.java +++ b/src/java.desktop/share/classes/javax/swing/text/StringContent.java @@ -350,7 +350,7 @@ public final class StringContent implements AbstractDocument.Content, Serializab return rec.offset; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { // schedule the record to be removed later // on another thread. diff --git a/src/java.desktop/share/classes/javax/swing/text/html/AccessibleHTML.java b/src/java.desktop/share/classes/javax/swing/text/html/AccessibleHTML.java index ba8465d45704185ab7a86a6afa6973cd6a8eed42..12cd5a74a721795e3814091d2bdd31621d3491e9 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/AccessibleHTML.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/AccessibleHTML.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -464,7 +464,7 @@ class AccessibleHTML implements Accessible { /** * Gets the Font of this object. * - * @return the Font,if supported, for the object; otherwise, null + * @return the Font, if supported, for the object; otherwise, null * @see #setFont */ public Font getFont() { diff --git a/src/java.desktop/share/classes/javax/swing/text/html/HTML.java b/src/java.desktop/share/classes/javax/swing/text/html/HTML.java index a27893d9fccbc241289f82fa3ffd2a6d244e91e2..23e3f089b732120b50a92d2cd05e7066e1aa086f 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/HTML.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/HTML.java @@ -43,7 +43,6 @@ import javax.swing.text.StyleContext; * @author Sunita Mani * */ -@SuppressWarnings("doclint:missing") public class HTML { /** @@ -60,7 +59,11 @@ public class HTML { */ public static class Tag { - /** @since 1.3 */ + /** + * Constructs a {@code Tag}. + * + * @since 1.3 + */ public Tag() {} /** diff --git a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java index c85989533f2b8fce1b5438a4e4bbd34b764d8d02..8d78819b0e8d4e169bf6894804976c50fcf784e2 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java @@ -216,8 +216,7 @@ import static java.nio.charset.StandardCharsets.ISO_8859_1; * * @author Timothy Prinzing */ -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public class HTMLEditorKit extends StyledEditorKit implements Accessible { private JEditorPane theEditor; @@ -456,12 +455,11 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { if (defaultStyles == null) { defaultStyles = new StyleSheet(); appContext.put(DEFAULT_STYLES_KEY, defaultStyles); - try { - InputStream is = HTMLEditorKit.getResourceAsStream(DEFAULT_CSS); - Reader r = new BufferedReader( - new InputStreamReader(is, ISO_8859_1)); + try (InputStream is = HTMLEditorKit.getResourceAsStream(DEFAULT_CSS); + InputStreamReader isr = new InputStreamReader(is, ISO_8859_1); + Reader r = new BufferedReader(isr)) + { defaultStyles.loadRules(r, null); - r.close(); } catch (Throwable e) { // on error we simply have no styles... the html // will look mighty wrong but still function. @@ -1685,6 +1683,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { } /** + * Returns HTMLDocument of the given JEditorPane. + * * @param e the JEditorPane * @return HTMLDocument of e. */ @@ -1697,6 +1697,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { } /** + * Returns HTMLEditorKit of the given JEditorPane. + * * @param e the JEditorPane * @return HTMLEditorKit for e. */ diff --git a/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java b/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java index 9fb2ff25d63923725ceb6b8bc1ecfb753bb1e333..9ce35f47ee9eb420129ac6aef21a54da87209670 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java @@ -478,15 +478,12 @@ public class StyleSheet extends StyleContext { * @since 1.3 */ public void importStyleSheet(URL url) { - try { - InputStream is; - - is = url.openStream(); - Reader r = new BufferedReader(new InputStreamReader(is)); + try (InputStream is = url.openStream(); + InputStreamReader isr = new InputStreamReader(is); + Reader r = new BufferedReader(isr)) + { CssParser parser = new CssParser(); parser.parse(url, r, false, true); - r.close(); - is.close(); } catch (Throwable e) { // on error we simply have no styles... the html // will look mighty wrong but still function. diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/AttributeList.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/AttributeList.java index f57a7f2a9174a9c41fe3d1c9a4f3517c4fd5a41a..36d1d0087c5a353609b3e6bbbc3acf72e4507eb7 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/AttributeList.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/AttributeList.java @@ -44,8 +44,7 @@ import java.io.*; * @author Arthur Van Hoff * */ -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public final class AttributeList implements DTDConstants, Serializable { @@ -111,14 +110,14 @@ class AttributeList implements DTDConstants, Serializable { } /** - * @return attribute name + * {@return the attribute name} */ public String getName() { return name; } /** - * @return attribute type + * {@return the attribute type} * @see DTDConstants */ public int getType() { @@ -126,7 +125,7 @@ class AttributeList implements DTDConstants, Serializable { } /** - * @return attribute modifier + * {@return the attribute modifier} * @see DTDConstants */ public int getModifier() { @@ -134,21 +133,21 @@ class AttributeList implements DTDConstants, Serializable { } /** - * @return possible attribute values + * {@return possible attribute values} */ public Enumeration getValues() { return (values != null) ? values.elements() : null; } /** - * @return default attribute value + * {@return default attribute value} */ public String getValue() { return value; } /** - * @return the next attribute in the list + * {@return the next attribute in the list} */ public AttributeList getNext() { return next; diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java index fc7cac3cdc17f79882e1ea1602c244a73fc24b75..f8a78440fbaa8883436856fced79420cd91c082b 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java @@ -75,7 +75,6 @@ import java.net.URL; * @author Arthur van Hoff * @author Sunita Mani */ -@SuppressWarnings("doclint:missing") public class Parser implements DTDConstants { @@ -211,6 +210,8 @@ class Parser implements DTDConstants { /** + * Returns the line number of the line currently being parsed. + * * @return the line number of the line currently being parsed */ protected int getCurrentLine() { diff --git a/src/java.desktop/share/classes/javax/swing/undo/UndoableEditSupport.java b/src/java.desktop/share/classes/javax/swing/undo/UndoableEditSupport.java index 5646222ecb11f1ce7ba8b2df4c2075bab49bb94c..f7228d4dc42cee52bc21f7e8e2019e6e91ab9f35 100644 --- a/src/java.desktop/share/classes/javax/swing/undo/UndoableEditSupport.java +++ b/src/java.desktop/share/classes/javax/swing/undo/UndoableEditSupport.java @@ -33,7 +33,6 @@ import java.util.*; * * @author Ray Ryan */ -@SuppressWarnings("doclint:missing") public class UndoableEditSupport { /** * The update level. @@ -148,7 +147,7 @@ public class UndoableEditSupport { } /** - * + * Starts a compound edit update. */ public synchronized void beginUpdate() { if (updateLevel == 0) { diff --git a/src/java.desktop/share/classes/sun/awt/DebugSettings.java b/src/java.desktop/share/classes/sun/awt/DebugSettings.java index 6883fda1b2684aa463287c9264d48ff1164cd872..9d89b6519b7ed81ca37a87a3f4862b2c62fb9c72 100644 --- a/src/java.desktop/share/classes/sun/awt/DebugSettings.java +++ b/src/java.desktop/share/classes/sun/awt/DebugSettings.java @@ -173,9 +173,9 @@ public final class DebugSettings { File propFile = new File(propPath); try { println("Reading debug settings from '" + propFile.getCanonicalPath() + "'..."); - FileInputStream fin = new FileInputStream(propFile); - props.load(fin); - fin.close(); + try (FileInputStream fin = new FileInputStream(propFile)) { + props.load(fin); + } } catch ( FileNotFoundException fne ) { println("Did not find settings file."); } catch ( IOException ioe ) { diff --git a/src/java.desktop/share/classes/sun/awt/FontConfiguration.java b/src/java.desktop/share/classes/sun/awt/FontConfiguration.java index 782b9d25641cc2c140eba336c5d86841bda03a4a..e2e7ab3e5ae1bf488d9728a6c05c7e35b7e40e60 100644 --- a/src/java.desktop/share/classes/sun/awt/FontConfiguration.java +++ b/src/java.desktop/share/classes/sun/awt/FontConfiguration.java @@ -48,7 +48,6 @@ import java.util.Set; import java.util.Vector; import sun.font.CompositeFontDescriptor; import sun.font.SunFontManager; -import sun.font.FontManagerFactory; import sun.font.FontUtilities; import sun.util.logging.PlatformLogger; @@ -204,14 +203,12 @@ public abstract class FontConfiguration { getInstalledFallbackFonts(javaLib); if (f != null) { - try { - FileInputStream in = new FileInputStream(f.getPath()); + try (FileInputStream in = new FileInputStream(f.getPath())) { if (isProperties) { loadProperties(in); } else { loadBinary(in); } - in.close(); if (FontUtilities.debugFonts()) { logger.config("Read logical font configuration from " + f); } diff --git a/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/src/java.desktop/share/classes/sun/awt/SunToolkit.java index dfc3d24c579640cda58ee584bf1af628d713c480..380a5e4db017e29a66f329891bc075786e04dfa4 100644 --- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -204,7 +204,7 @@ public abstract class SunToolkit extends Toolkit * access to Xlib, OpenGL, etc. However, these methods are implemented * in SunToolkit so that they can be called from shared code (e.g. * from the OGL pipeline) or from the X11 pipeline regardless of whether - * XToolkit or MToolkit is currently in use. There are native macros + * XToolkit is currently in use. There are native macros * (such as AWT_LOCK) defined in awt.h, so if the implementation of these * methods is changed, make sure it is compatible with the native macros. * diff --git a/src/java.desktop/share/classes/sun/awt/geom/Curve.java b/src/java.desktop/share/classes/sun/awt/geom/Curve.java index 0396ffc5d03998f65d818bb6d9781169458e467f..a59793d434988a7d95e2abfc2234693a6b31d686 100644 --- a/src/java.desktop/share/classes/sun/awt/geom/Curve.java +++ b/src/java.desktop/share/classes/sun/awt/geom/Curve.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -731,12 +731,12 @@ public abstract class Curve { public static int orderof(double x1, double x2) { if (x1 < x2) { - return -1; - } - if (x1 > x2) { - return 1; - } - return 0; + return -1; + } + if (x1 > x2) { + return 1; + } + return 0; } public static long signeddiffbits(double y1, double y2) { diff --git a/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java b/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java index 0c375a900a0aae852f1e1edbc5a5e60319b357ff..3aa91dcb6006f31bb0e7ed32719098c4b69407a8 100644 --- a/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java +++ b/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java @@ -41,6 +41,7 @@ import java.util.List; import java.util.concurrent.Callable; import javax.swing.SwingConstants; +import sun.awt.OSInfo; /** * @author Michael Martak @@ -295,7 +296,7 @@ public abstract class ShellFolder extends File { */ public static File getNormalizedFile(File f) throws IOException { File canonical = f.getCanonicalFile(); - if (f.equals(canonical)) { + if (f.equals(canonical) || OSInfo.getOSType() == OSInfo.OSType.WINDOWS) { // path of f doesn't contain symbolic links return canonical; } diff --git a/src/java.desktop/share/classes/sun/awt/util/IdentityArrayList.java b/src/java.desktop/share/classes/sun/awt/util/IdentityArrayList.java index 8f1bbdc4714d178fc47645d576c4f0502685be28..98f93cc3ec7027fa9942a230d7889addeb9ea0df 100644 --- a/src/java.desktop/share/classes/sun/awt/util/IdentityArrayList.java +++ b/src/java.desktop/share/classes/sun/awt/util/IdentityArrayList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -203,7 +203,7 @@ public class IdentityArrayList extends AbstractList * Returns {@code true} if this list contains the specified element. * More formally, returns {@code true} if and only if this list contains * at least one element {@code e} such that - * {@code Objects.equals(o, e)}. + * {@code o == e}. * * @param o element whose presence in this list is to be tested * @return {@code true} if this list contains the specified element @@ -216,8 +216,12 @@ public class IdentityArrayList extends AbstractList * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the lowest index {@code i} such that - * {@code Objects.equals(o, get(i))}, + * {@code get(i) == o}, * or -1 if there is no such index. + * + * @param o element to search for + * @return the index of the first occurrence of the specified element in + * this list, or -1 if this list does not contain the element */ public int indexOf(Object o) { for (int i = 0; i < size; i++) { @@ -232,8 +236,12 @@ public class IdentityArrayList extends AbstractList * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the highest index {@code i} such that - * {@code Objects.equals(o, get(i))}, + * {@code get(i) == o}, * or -1 if there is no such index. + * + * @param o element to search for + * @return the index of the last occurrence of the specified element in + * this list, or -1 if this list does not contain the element */ public int lastIndexOf(Object o) { for (int i = size-1; i >= 0; i--) { @@ -390,9 +398,9 @@ public class IdentityArrayList extends AbstractList /** * Removes the first occurrence of the specified element from this list, - * if it is present. If the list does not contain the element, it is + * if it is present. If this list does not contain the element, the list is * unchanged. More formally, removes the element with the lowest index - * {@code i} such that {@code Objects.equals(o, get(i))} + * {@code i} such that {@code get(i) == o} * (if such an element exists). Returns {@code true} if this list * contained the specified element (or equivalently, if this list * changed as a result of the call). diff --git a/src/java.desktop/share/classes/sun/awt/util/IdentityLinkedList.java b/src/java.desktop/share/classes/sun/awt/util/IdentityLinkedList.java index 21474bafcfdb5aed89b172cb09f236180994d41a..fef09665bc0788650a1685a108042c3b8f50e539 100644 --- a/src/java.desktop/share/classes/sun/awt/util/IdentityLinkedList.java +++ b/src/java.desktop/share/classes/sun/awt/util/IdentityLinkedList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -183,7 +183,7 @@ public class IdentityLinkedList * Returns {@code true} if this list contains the specified element. * More formally, returns {@code true} if and only if this list contains * at least one element {@code e} such that - * {@code Objects.equals(o, e)}. + * {@code o == e}. * * @param o element whose presence in this list is to be tested * @return {@code true} if this list contains the specified element @@ -218,7 +218,7 @@ public class IdentityLinkedList * Removes the first occurrence of the specified element from this list, * if it is present. If this list does not contain the element, it is * unchanged. More formally, removes the element with the lowest index - * {@code i} such that {@code get(i)==o} + * {@code i} such that {@code get(i) == o} * (if such an element exists). Returns {@code true} if this list * contained the specified element (or equivalently, if this list * changed as a result of the call). @@ -389,7 +389,7 @@ public class IdentityLinkedList * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the lowest index {@code i} such that - * {@code get(i)==o}, + * {@code get(i) == o}, * or -1 if there is no such index. * * @param o element to search for @@ -411,7 +411,7 @@ public class IdentityLinkedList * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the highest index {@code i} such that - * {@code get(i)==o}, + * {@code get(i) == o}, * or -1 if there is no such index. * * @param o element to search for diff --git a/src/java.desktop/share/classes/sun/font/TrueTypeFont.java b/src/java.desktop/share/classes/sun/font/TrueTypeFont.java index b3afe089132a8ac878f9773f84ac525b131ef3f7..856297643cf63eeee242c212b788db661b8ab0f0 100644 --- a/src/java.desktop/share/classes/sun/font/TrueTypeFont.java +++ b/src/java.desktop/share/classes/sun/font/TrueTypeFont.java @@ -503,7 +503,9 @@ public class TrueTypeFont extends FileFont { /* checksum */ ibuffer.get(); table.offset = ibuffer.get() & 0x7FFFFFFF; table.length = ibuffer.get() & 0x7FFFFFFF; - if (table.offset + table.length > fileSize) { + if ((table.offset + table.length < table.length) || + (table.offset + table.length > fileSize)) + { throw new FontFormatException("bad table, tag="+table.tag); } } @@ -798,8 +800,11 @@ public class TrueTypeFont extends FileFont { break; } } + if (entry == null || entry.length == 0 || - entry.offset+entry.length > fileSize) { + (entry.offset + entry.length < entry.length) || + (entry.offset + entry.length > fileSize)) + { return null; } @@ -888,6 +893,9 @@ public class TrueTypeFont extends FileFont { return false; } ByteBuffer eblcTable = getTableBuffer(EBLCTag); + if (eblcTable == null) { + return false; + } int numSizes = eblcTable.getInt(4); /* The bitmapSizeTable's start at offset of 8. * Each bitmapSizeTable entry is 48 bytes. diff --git a/src/java.desktop/share/classes/sun/java2d/Spans.java b/src/java.desktop/share/classes/sun/java2d/Spans.java index c7be5d5ab360eaa0ef3711d03bc968a0251a8eba..98d2aaf9e99d5e003f5f9800f3a74485b7cf18ab 100644 --- a/src/java.desktop/share/classes/sun/java2d/Spans.java +++ b/src/java.desktop/share/classes/sun/java2d/Spans.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -315,6 +315,7 @@ public class Spans { * position. The end position is ignored * in this ranking. */ + @Override public int compareTo(Span otherSpan) { float otherStart = otherSpan.getStart(); int result; diff --git a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java index 15db79d69d2f95219f648049ba5459949c55bef8..b5b5225938b3a441dd24f0b125751933f2963f41 100644 --- a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java +++ b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java @@ -3656,7 +3656,7 @@ public final class SunGraphics2D * enough to know that if our override is empty then it should not * mark us as finalizeable. */ - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") public void finalize() { // DO NOT REMOVE THIS METHOD } diff --git a/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java b/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java index dadfbeb540c0d1ca4d02fa20db6203dd98fd1b86..8c2fb00d7b7abd7784bc87092872b8d4534f24a6 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,7 +79,7 @@ public final class GraphicsPrimitiveMgr { int id1 = o1.getUniqueID(); int id2 = o2.getUniqueID(); - return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); + return Integer.compare(id1, id2); } }; @@ -88,7 +88,7 @@ public final class GraphicsPrimitiveMgr { int id1 = ((GraphicsPrimitive) o1).getUniqueID(); int id2 = ((PrimitiveSpec) o2).uniqueID; - return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); + return Integer.compare(id1, id2); } }; diff --git a/src/java.desktop/share/classes/sun/print/PSPrinterJob.java b/src/java.desktop/share/classes/sun/print/PSPrinterJob.java index e90b0b586c82c63f49d9e8d5260f202df71366a4..61450e49553f7c788d39ebe30da208ac6cbeba84 100644 --- a/src/java.desktop/share/classes/sun/print/PSPrinterJob.java +++ b/src/java.desktop/share/classes/sun/print/PSPrinterJob.java @@ -393,11 +393,10 @@ public class PSPrinterJob extends RasterPrinterJob { } // Load property file - InputStream in = - new BufferedInputStream(new FileInputStream(f.getPath())); Properties props = new Properties(); - props.load(in); - in.close(); + try (FileInputStream in = new FileInputStream(f.getPath())) { + props.load(in); + } return props; } catch (Exception e){ return (Properties)null; diff --git a/src/java.desktop/share/classes/sun/print/PSStreamPrintService.java b/src/java.desktop/share/classes/sun/print/PSStreamPrintService.java index 62a28e0505261c016118840db40be102a7838136..e1594e051f5c31996c75ba21ec1acc3dc0eb7938 100644 --- a/src/java.desktop/share/classes/sun/print/PSStreamPrintService.java +++ b/src/java.desktop/share/classes/sun/print/PSStreamPrintService.java @@ -427,7 +427,17 @@ public class PSStreamPrintService extends StreamPrintService if (attr == OrientationRequested.REVERSE_PORTRAIT || (flavor != null) && !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || - flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) { + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) || + flavor.equals(DocFlavor.INPUT_STREAM.GIF) || + flavor.equals(DocFlavor.INPUT_STREAM.JPEG) || + flavor.equals(DocFlavor.INPUT_STREAM.PNG) || + flavor.equals(DocFlavor.BYTE_ARRAY.GIF) || + flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) || + flavor.equals(DocFlavor.BYTE_ARRAY.PNG) || + flavor.equals(DocFlavor.URL.GIF) || + flavor.equals(DocFlavor.URL.JPEG) || + flavor.equals(DocFlavor.URL.PNG))) + { return false; } } else if (attr.getCategory() == PageRanges.class) { @@ -440,7 +450,7 @@ public class PSStreamPrintService extends StreamPrintService if (flavor != null && !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) { - return false; + return attr == SheetCollate.UNCOLLATED; } } else if (attr.getCategory() == Sides.class) { if (flavor != null && diff --git a/src/java.desktop/share/classes/sun/print/PeekGraphics.java b/src/java.desktop/share/classes/sun/print/PeekGraphics.java index c400ad59ca2b59b3f8da2ca70b72f469b355ae5c..b5eabc847739d312604b46d002b96f97af76e925 100644 --- a/src/java.desktop/share/classes/sun/print/PeekGraphics.java +++ b/src/java.desktop/share/classes/sun/print/PeekGraphics.java @@ -1336,7 +1336,7 @@ public class PeekGraphics extends Graphics2D /** * Empty finalizer as no clean up needed here. */ - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") public void finalize() { } diff --git a/src/java.desktop/share/classes/sun/print/PrintJob2D.java b/src/java.desktop/share/classes/sun/print/PrintJob2D.java index 323cb0cc84e5536fb17c87023fbf1506c14b4e52..9083bd3e26965be3ba66460049c4f645a5dc2b7b 100644 --- a/src/java.desktop/share/classes/sun/print/PrintJob2D.java +++ b/src/java.desktop/share/classes/sun/print/PrintJob2D.java @@ -940,7 +940,7 @@ public class PrintJob2D extends PrintJob implements Printable, Runnable { * Ends this print job once it is no longer referenced. * @see #end */ - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") public void finalize() { end(); } diff --git a/src/java.desktop/share/classes/sun/print/ProxyGraphics.java b/src/java.desktop/share/classes/sun/print/ProxyGraphics.java index 124a7a487f62d1f789119376d24271526d732ea8..c6c0615c3439d8b6fed7d7aad8d00c997bac87e4 100644 --- a/src/java.desktop/share/classes/sun/print/ProxyGraphics.java +++ b/src/java.desktop/share/classes/sun/print/ProxyGraphics.java @@ -1099,7 +1099,7 @@ public class ProxyGraphics extends Graphics { /** * Empty finalizer as no clean up needed here. */ - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") public void finalize() { } diff --git a/src/java.desktop/share/classes/sun/print/ProxyGraphics2D.java b/src/java.desktop/share/classes/sun/print/ProxyGraphics2D.java index fc1c0e768108fc602ed53e27f58a997ac4d04373..c05ba9a6188e4bf2924b343a62882e2514956828 100644 --- a/src/java.desktop/share/classes/sun/print/ProxyGraphics2D.java +++ b/src/java.desktop/share/classes/sun/print/ProxyGraphics2D.java @@ -1264,7 +1264,7 @@ public class ProxyGraphics2D extends Graphics2D implements PrinterGraphics { /** * Empty finalizer as no clean up needed here. */ - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") public void finalize() { } diff --git a/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java b/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java index e8cff0a28e93dd3c332c866fbe243ebdb54eb62b..5c9d2a1b69570215721360e343ca2c8b2b96b32e 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java +++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ public final class X11GraphicsEnvironment extends SunGraphicsEnvironment { System.loadLibrary("awt"); /* - * Note: The MToolkit object depends on the static initializer + * Note: The XToolkit object depends on the static initializer * of X11GraphicsEnvironment to initialize the connection to * the X11 server. */ diff --git a/src/java.desktop/unix/classes/sun/awt/X11InputMethodBase.java b/src/java.desktop/unix/classes/sun/awt/X11InputMethodBase.java index 671df20d1dbeb6a6bc62130e1c14d4e56cc5e53c..eb71b7a59729cc3939deecb3a341ff3ffe1797cc 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11InputMethodBase.java +++ b/src/java.desktop/unix/classes/sun/awt/X11InputMethodBase.java @@ -172,7 +172,7 @@ public abstract class X11InputMethodBase extends InputMethodAdapter { } } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { dispose(); super.finalize(); diff --git a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java index 87c7907441bcee26f3743cf2ab25dca3bafc85a9..24eafee31a5c33bdc33020b6d3d263c6d5bd1374 100644 --- a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java +++ b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -295,6 +295,12 @@ public class FcFontConfiguration extends FontConfiguration { return null; } + private String extractOsInfo(String s) { + if (s.startsWith("\"")) s = s.substring(1); + if (s.endsWith("\"")) s = s.substring(0, s.length()-1); + return s; + } + /** * Sets the OS name and version from environment information. */ @@ -314,7 +320,9 @@ public class FcFontConfiguration extends FontConfiguration { * For Ubuntu the ID is "Ubuntu". */ Properties props = new Properties(); - props.load(new FileInputStream(f)); + try (FileInputStream fis = new FileInputStream(f)) { + props.load(fis); + } osName = props.getProperty("DISTRIB_ID"); osVersion = props.getProperty("DISTRIB_RELEASE"); } else if ((f = new File("/etc/redhat-release")).canRead()) { @@ -329,6 +337,16 @@ public class FcFontConfiguration extends FontConfiguration { } else if ((f = new File("/etc/fedora-release")).canRead()) { osName = "Fedora"; osVersion = getVersionString(f); + } else if ((f = new File("/etc/os-release")).canRead()) { + Properties props = new Properties(); + try (FileInputStream fis = new FileInputStream(f)) { + props.load(fis); + } + osName = props.getProperty("NAME"); + osVersion = props.getProperty("VERSION_ID"); + osName = extractOsInfo(osName); + if (osName.equals("SLES")) osName = "SuSE"; + osVersion = extractOsInfo(osVersion); } } catch (Exception e) { if (FontUtilities.debugFonts()) { @@ -401,10 +419,9 @@ public class FcFontConfiguration extends FontConfiguration { File dir = fcInfoFile.getParentFile(); dir.mkdirs(); File tempFile = Files.createTempFile(dir.toPath(), "fcinfo", null).toFile(); - FileOutputStream fos = new FileOutputStream(tempFile); - props.store(fos, - "JDK Font Configuration Generated File: *Do Not Edit*"); - fos.close(); + try (FileOutputStream fos = new FileOutputStream(tempFile)) { + props.store(fos, "JDK Font Configuration Generated File: *Do Not Edit*"); + } boolean renamed = tempFile.renameTo(fcInfoFile); if (!renamed && FontUtilities.debugFonts()) { System.out.println("rename failed"); diff --git a/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java b/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java index 89212a210169aa373c86037ef4fa1e5c5c1e05a1..73c6142805931de65e961a649465b423cee26f77 100644 --- a/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java +++ b/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ package sun.font; import sun.awt.FontConfiguration; import sun.awt.X11FontManager; -import sun.font.FontUtilities; -import sun.font.SunFontManager; import sun.util.logging.PlatformLogger; import java.io.File; @@ -111,9 +109,21 @@ public class MFontConfiguration extends FontConfiguration { * For Ubuntu the ID is "Ubuntu". */ Properties props = new Properties(); - props.load(new FileInputStream(f)); + try (FileInputStream fis = new FileInputStream(f)) { + props.load(fis); + } osName = props.getProperty("DISTRIB_ID"); osVersion = props.getProperty("DISTRIB_RELEASE"); + } else if ((f = new File("/etc/os-release")).canRead()) { + Properties props = new Properties(); + try (FileInputStream fis = new FileInputStream(f)) { + props.load(fis); + } + osName = props.getProperty("NAME"); + osVersion = props.getProperty("VERSION_ID"); + osName = extractOsInfo(osName); + if (osName.equals("SLES")) osName = "SuSE"; + osVersion = extractOsInfo(osVersion); } } catch (Exception e) { } @@ -134,6 +144,12 @@ public class MFontConfiguration extends FontConfiguration { return null; } + private String extractOsInfo(String s) { + if (s.startsWith("\"")) s = s.substring(1); + if (s.endsWith("\"")) s = s.substring(0, s.length()-1); + return s; + } + private static final String fontsDirPrefix = "$JRE_LIB_FONTS"; protected String mapFileName(String fileName) { diff --git a/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java b/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java index 536962bd82030e87cb085fcdcb63687cc571ac20..588dfbf882aef65ba91d5a2568caf592e1e92732 100644 --- a/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java +++ b/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -216,7 +216,7 @@ public final class GLXGraphicsConfig } /** - * The following methods are invoked from MToolkit or XToolkit.java and + * The following methods are invoked from XToolkit.java and * X11ComponentPeer.java rather than having the X11-dependent * implementations hardcoded in those classes. This way the appropriate * actions are taken based on the peer's GraphicsConfig, whether it is diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java index f41f3778da46cb35f92963e6b123c5ab15d01785..b40d1d0ffa1a6ed334dbe7888ee5c018b2a89453 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java @@ -25,15 +25,18 @@ package sun.java2d.xr; -import java.awt.*; -import java.awt.geom.*; - +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Paint; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; import java.security.AccessController; import java.security.PrivilegedAction; -import sun.font.*; -import sun.java2d.*; -import sun.java2d.loops.*; +import sun.awt.image.PixelConverter; +import sun.font.XRTextRenderer; +import sun.java2d.SunGraphics2D; +import sun.java2d.loops.XORComposite; /** * Manages per-application resources, e.g. the 1x1 pixmap used for solid color @@ -68,6 +71,7 @@ public class XRCompositeManager { int gradCachePicture; boolean xorEnabled = false; + int eargb; int validatedPixel = 0; Composite validatedComp; Paint validatedPaint; @@ -170,8 +174,10 @@ public class XRCompositeManager { validatedComp = comp; } - if (sg2d != null && (validatedPixel != sg2d.pixel || updatePaint)) { - validatedPixel = sg2d.pixel; + if (sg2d != null && (eargb != sg2d.eargb || updatePaint)) { + eargb = sg2d.eargb; + validatedPixel = PixelConverter.ArgbPre.instance + .rgbToPixel(eargb, null); setForeground(validatedPixel); } diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRGraphicsConfig.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRGraphicsConfig.java index 680e634cce85ac65c0de165a2b80c22cc6f040c1..7483128bec6476024bb8b4a702e7500827963b7d 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRGraphicsConfig.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRGraphicsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,14 +25,12 @@ package sun.java2d.xr; -import java.awt.Transparency; -import sun.awt.X11GraphicsConfig; import sun.awt.X11ComponentPeer; +import sun.awt.X11GraphicsConfig; import sun.awt.X11GraphicsDevice; import sun.awt.X11GraphicsEnvironment; import sun.awt.image.SurfaceManager; import sun.java2d.SurfaceData; -import sun.java2d.loops.SurfaceType; public class XRGraphicsConfig extends X11GraphicsConfig implements SurfaceManager.ProxiedGraphicsConfig { @@ -58,14 +56,4 @@ public class XRGraphicsConfig extends X11GraphicsConfig implements public Object getProxyKey() { return this; } - - public synchronized SurfaceType getSurfaceType() { - if (surfaceType != null) { - return surfaceType; - } - - surfaceType = XRSurfaceData.getSurfaceType(this, Transparency.OPAQUE); - return surfaceType; - } - } diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java index 4d4a04af937aad52fd18f019b47b12a3678c3e23..7a0f8d1bb29d3ccf35b7237b66bbb04de138d6df 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java @@ -36,10 +36,12 @@ import java.awt.geom.AffineTransform; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; import java.awt.image.Raster; + import sun.awt.SunHints; import sun.awt.SunToolkit; import sun.awt.X11ComponentPeer; import sun.awt.image.PixelConverter; +import sun.font.FontManagerNativeLibrary; import sun.java2d.InvalidPipeException; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; @@ -55,7 +57,6 @@ import sun.java2d.pipe.ShapeDrawPipe; import sun.java2d.pipe.TextPipe; import sun.java2d.pipe.ValidatePipe; import sun.java2d.x11.XSurfaceData; -import sun.font.FontManagerNativeLibrary; public abstract class XRSurfaceData extends XSurfaceData { X11ComponentPeer peer; @@ -276,7 +277,7 @@ public abstract class XRSurfaceData extends XSurfaceData { } return new XRPixmapSurfaceData - (gc, width, height, image, getSurfaceType(gc, transparency), + (gc, width, height, image, getPixmapSurfaceType(transparency), cm, drawable, transparency, XRUtils.getPictureFormatForTransparency(transparency), depth, isTexture); } @@ -395,8 +396,7 @@ public abstract class XRSurfaceData extends XSurfaceData { * Returns the XRender SurfaceType which is able to fullfill the specified * transparency requirement. */ - public static SurfaceType getSurfaceType(XRGraphicsConfig gc, - int transparency) { + public static SurfaceType getPixmapSurfaceType(int transparency) { SurfaceType sType = null; switch (transparency) { diff --git a/src/java.desktop/unix/native/common/awt/awt.h b/src/java.desktop/unix/native/common/awt/awt.h index 18a6dee275b27c891254e8ee5aabd6f83b67a356..5c71431f03374c0fbd9016ee8584b0b87443934e 100644 --- a/src/java.desktop/unix/native/common/awt/awt.h +++ b/src/java.desktop/unix/native/common/awt/awt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ typedef char Boolean; #endif /* !HEADLESS && !MACOSX */ -/* The JVM instance: defined in awt_MToolkit.c */ +/* The JVM instance: defined in awt_LoadLibrary.c */ extern JavaVM *jvm; extern jclass tkClass; diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java b/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java index 9ad52ba7111c0b697fc58a92ace475c54ffaed33..681662032e147799bc0ae20c38f703ed0da634e3 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java @@ -133,7 +133,7 @@ final class WInputMethod extends InputMethodAdapter } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { // Release the resources used by the native input context. diff --git a/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp b/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp index bc0c27d069a55478870da585b2c88c5a4faf1708..124efa09be148b08e457eee889c018b9ee1ec541 100644 --- a/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp +++ b/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp @@ -1056,38 +1056,57 @@ JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits bmi.bmiHeader.biCompression = BI_RGB; // Extract the color bitmap int nBits = iconSize * iconSize; - long colorBits[MAX_ICON_SIZE * MAX_ICON_SIZE]; - GetDIBits(dc, iconInfo.hbmColor, 0, iconSize, colorBits, &bmi, DIB_RGB_COLORS); - // XP supports alpha in some icons, and depending on device. - // This should take precedence over the icon mask bits. - BOOL hasAlpha = FALSE; - if (IS_WINXP) { - for (int i = 0; i < nBits; i++) { - if ((colorBits[i] & 0xff000000) != 0) { - hasAlpha = TRUE; - break; + + long *colorBits = NULL; + long *maskBits = NULL; + + try { + entry_point(); + colorBits = (long*)safe_Malloc(MAX_ICON_SIZE * MAX_ICON_SIZE * sizeof(long)); + GetDIBits(dc, iconInfo.hbmColor, 0, iconSize, colorBits, &bmi, DIB_RGB_COLORS); + // XP supports alpha in some icons, and depending on device. + // This should take precedence over the icon mask bits. + BOOL hasAlpha = FALSE; + if (IS_WINXP) { + for (int i = 0; i < nBits; i++) { + if ((colorBits[i] & 0xff000000) != 0) { + hasAlpha = TRUE; + break; + } } } - } - if (!hasAlpha) { - // Extract the mask bitmap - long maskBits[MAX_ICON_SIZE * MAX_ICON_SIZE]; - GetDIBits(dc, iconInfo.hbmMask, 0, iconSize, maskBits, &bmi, DIB_RGB_COLORS); - // Copy the mask alphas into the color bits - for (int i = 0; i < nBits; i++) { - if (maskBits[i] == 0) { - colorBits[i] |= 0xff000000; + if (!hasAlpha) { + // Extract the mask bitmap + maskBits = (long*)safe_Malloc(MAX_ICON_SIZE * MAX_ICON_SIZE * sizeof(long)); + GetDIBits(dc, iconInfo.hbmMask, 0, iconSize, maskBits, &bmi, DIB_RGB_COLORS); + // Copy the mask alphas into the color bits + for (int i = 0; i < nBits; i++) { + if (maskBits[i] == 0) { + colorBits[i] |= 0xff000000; + } } } + // Create java array + iconBits = env->NewIntArray(nBits); + if (!(env->ExceptionCheck())) { + // Copy values to java array + env->SetIntArrayRegion(iconBits, 0, nBits, colorBits); + } + } catch(std::bad_alloc&) { + handle_bad_alloc(); } + // Release DC ReleaseDC(NULL, dc); - // Create java array - iconBits = env->NewIntArray(nBits); - if (!(env->ExceptionCheck())) { - // Copy values to java array - env->SetIntArrayRegion(iconBits, 0, nBits, colorBits); - } + + // Free bitmap buffers if they were allocated + if (colorBits != NULL) { + free(colorBits); + } + + if (maskBits != NULL) { + free(maskBits); + } } // Fix 4745575 GDI Resource Leak // MSDN diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp index 8db02f9aee485ce89f2cfc3d03e02e7b867d7c6a..2dadde0548063d3d2de29e22c54ee8cd119092fc 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3917,11 +3917,11 @@ void AwtComponent::SetCandidateWindow(int iCandType, int x, int y) HIMC hIMC = ImmGetContext(hwnd); if (hIMC) { CANDIDATEFORM cf; - cf.dwStyle = CFS_POINT; + cf.dwStyle = CFS_CANDIDATEPOS; ImmGetCandidateWindow(hIMC, 0, &cf); if (x != cf.ptCurrentPos.x || y != cf.ptCurrentPos.y) { cf.dwIndex = iCandType; - cf.dwStyle = CFS_POINT; + cf.dwStyle = CFS_CANDIDATEPOS; cf.ptCurrentPos = {x, y}; cf.rcArea = {0, 0, 0, 0}; ImmSetCandidateWindow(hIMC, &cf); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp b/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp index 0f9fb662bbf5c85b779a8032225c0194dc568ed5..8146d62c4a7dd4d31dd5bd7c6ab827d176f1db87 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -267,13 +267,13 @@ void AwtDragSource::_DoDragDrop(void* param) { dragSource->Signal(); AwtToolkit &toolkit = AwtToolkit::GetInstance(); - toolkit.isInDoDragDropLoop = TRUE; + toolkit.isDnDSourceActive = TRUE; res = ::DoDragDrop(dragSource, dragSource, convertActionsToDROPEFFECT(dragSource->m_actions), &effects ); - toolkit.isInDoDragDropLoop = FALSE; + toolkit.isDnDSourceActive = FALSE; if (effects == DROPEFFECT_NONE && dragSource->m_dwPerformedDropEffect != DROPEFFECT_NONE) { effects = dragSource->m_dwPerformedDropEffect; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp b/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp index 126e7194f865eaa70db07d109cb69891c59ca574..ed41af9d6bfc8e6f880e29cc0c0e781113da5802 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,7 +141,7 @@ static void ScaleDown(POINT &cp, HWND m_window) { HRESULT __stdcall AwtDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect) { TRY; - AwtToolkit::GetInstance().isInDoDragDropLoop = TRUE; + AwtToolkit::GetInstance().isDnDTargetActive = TRUE; if (NULL != m_pIDropTargetHelper) { m_pIDropTargetHelper->DragEnter( m_window, @@ -161,7 +161,7 @@ HRESULT __stdcall AwtDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWOR (IsLocalDnD() && !IsLocalDataObject(pDataObj))) { *pdwEffect = retEffect; - AwtToolkit::GetInstance().isInDoDragDropLoop = FALSE; + AwtToolkit::GetInstance().isDnDTargetActive = FALSE; return ret; } @@ -173,7 +173,7 @@ HRESULT __stdcall AwtDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWOR } if (JNU_IsNull(env, m_dtcp) || !JNU_IsNull(env, safe_ExceptionOccurred(env))) { - AwtToolkit::GetInstance().isInDoDragDropLoop = FALSE; + AwtToolkit::GetInstance().isDnDTargetActive = FALSE; return ret; } @@ -200,12 +200,12 @@ HRESULT __stdcall AwtDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWOR env->ExceptionDescribe(); env->ExceptionClear(); actions = java_awt_dnd_DnDConstants_ACTION_NONE; - AwtToolkit::GetInstance().isInDoDragDropLoop = FALSE; + AwtToolkit::GetInstance().isDnDTargetActive = FALSE; } } catch (std::bad_alloc&) { retEffect = ::convertActionsToDROPEFFECT(actions); *pdwEffect = retEffect; - AwtToolkit::GetInstance().isInDoDragDropLoop = FALSE; + AwtToolkit::GetInstance().isDnDTargetActive = FALSE; throw; } @@ -421,7 +421,7 @@ void AwtDropTarget::DropDone(jboolean success, jint action) { m_dropSuccess = success; m_dropActions = action; AwtToolkit::GetInstance().QuitMessageLoop(AwtToolkit::EXIT_ENCLOSING_LOOP); - AwtToolkit::GetInstance().isInDoDragDropLoop = FALSE; + AwtToolkit::GetInstance().isDnDTargetActive = FALSE; } /** @@ -1136,7 +1136,7 @@ void AwtDropTarget::UnloadCache() { void AwtDropTarget::DragCleanup(void) { UnloadCache(); - AwtToolkit::GetInstance().isInDoDragDropLoop = FALSE; + AwtToolkit::GetInstance().isDnDTargetActive = FALSE; } BOOL AwtDropTarget::IsLocalDataObject(IDataObject __RPC_FAR *pDataObject) { diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp index 355d32072730feee2b0f6d3aba28c8d9c5d6343e..17e69d70b15bd3375b530bd712e10582d8951185 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -344,7 +344,8 @@ AwtToolkit::AwtToolkit() { m_waitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); m_inputMethodWaitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); - isInDoDragDropLoop = FALSE; + isDnDSourceActive = FALSE; + isDnDTargetActive = FALSE; eventNumber = 0; } @@ -3012,7 +3013,7 @@ Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong t tk.PostMessage(WM_SYNC_WAIT, 0, 0); for(long t = 2; t < timeout && WAIT_TIMEOUT == ::WaitForSingleObject(tk.m_waitEvent, 2); t+=2) { - if (tk.isInDoDragDropLoop) { + if (tk.isDnDSourceActive || tk.isDnDTargetActive) { break; } } @@ -3216,7 +3217,7 @@ LRESULT AwtToolkit::InvokeInputMethodFunction(UINT msg, WPARAM wParam, LPARAM lP * the IME completion. */ CriticalSection::Lock lock(m_inputMethodLock); - if (isInDoDragDropLoop) { + if (isDnDSourceActive || isDnDTargetActive) { SendMessage(msg, wParam, lParam); ::ResetEvent(m_inputMethodWaitEvent); return m_inputMethodData; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h index a148001842d568a58aaba6eac1793362d851e8ee..ff9baf6464a630c05fccebbd45d83a10e92bf1b6 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -441,7 +441,8 @@ public: HANDLE m_waitEvent; volatile DWORD eventNumber; - volatile BOOL isInDoDragDropLoop; + volatile BOOL isDnDSourceActive; + volatile BOOL isDnDTargetActive; private: HWND CreateToolkitWnd(LPCTSTR name); diff --git a/src/java.logging/share/classes/java/util/logging/LogManager.java b/src/java.logging/share/classes/java/util/logging/LogManager.java index a6d11b64517952a9aeb868941a6c5e0ce6f51bf7..2d277602a4aceccf96d25ea774183205c291b2a1 100644 --- a/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1381,8 +1381,7 @@ public class LogManager { String fname = getConfigurationFileName(); try (final InputStream in = new FileInputStream(fname)) { - final BufferedInputStream bin = new BufferedInputStream(in); - readConfiguration(bin); + readConfiguration(in); } } @@ -1877,8 +1876,7 @@ public class LogManager { String fname = getConfigurationFileName(); try (final InputStream in = new FileInputStream(fname)) { - final BufferedInputStream bin = new BufferedInputStream(in); - updateConfiguration(bin, mapper); + updateConfiguration(in, mapper); } } @@ -2558,13 +2556,14 @@ public class LogManager { /** * String representation of the - * {@link javax.management.ObjectName} for the management interface + * {@link java.management/javax.management.ObjectName} for the management interface * for the logging facility. * - * @see java.lang.management.PlatformLoggingMXBean + * @see java.management/java.lang.management.PlatformLoggingMXBean * * @since 1.5 */ + @SuppressWarnings("doclint:reference") public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"; @@ -2575,14 +2574,15 @@ public class LogManager { * * @deprecated {@code java.util.logging.LoggingMXBean} is deprecated and * replaced with {@code java.lang.management.PlatformLoggingMXBean}. Use - * {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) + * {@link java.management/java.lang.management.ManagementFactory#getPlatformMXBean(Class) * ManagementFactory.getPlatformMXBean}(PlatformLoggingMXBean.class) * instead. * - * @see java.lang.management.PlatformLoggingMXBean + * @see java.management/java.lang.management.PlatformLoggingMXBean * @since 1.5 */ @Deprecated(since="9") + @SuppressWarnings("doclint:reference") public static synchronized LoggingMXBean getLoggingMXBean() { return Logging.getInstance(); } diff --git a/src/java.logging/share/classes/java/util/logging/LogRecord.java b/src/java.logging/share/classes/java/util/logging/LogRecord.java index 5549789664af3fd7c391a9dab2b91a9b79570155..6d680d7f6065ca8336d7da67c60758adbb286132 100644 --- a/src/java.logging/share/classes/java/util/logging/LogRecord.java +++ b/src/java.logging/share/classes/java/util/logging/LogRecord.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -179,7 +179,7 @@ public class LogRecord implements java.io.Serializable { /** * Synthesizes a pseudo unique integer value from a long {@code id} value. - * For backward compatibility with previous releases,the returned integer is + * For backward compatibility with previous releases, the returned integer is * such that for any positive long less than or equals to {@code Integer.MAX_VALUE}, * the returned integer is equal to the original value. * Otherwise - it is synthesized with a best effort hashing algorithm, diff --git a/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java b/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java index 812eb36622d2814a985a624b9b11f31753759c4d..01eea1d0e1e123467f468264110ca7ee20ad7fbe 100644 --- a/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java +++ b/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,18 +29,18 @@ package java.util.logging; /** * The management interface for the logging facility. * - * {@link java.lang.management.PlatformLoggingMXBean + * {@link java.management/java.lang.management.PlatformLoggingMXBean * java.lang.management.PlatformLoggingMXBean} is the management interface * for logging facility registered in the {@link - * java.lang.management.ManagementFactory#getPlatformMBeanServer() + * java.management/java.lang.management.ManagementFactory#getPlatformMBeanServer() * platform MBeanServer}. * It is recommended to use the {@code PlatformLoggingMXBean} obtained via - * the {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) + * the {@link java.management/java.lang.management.ManagementFactory#getPlatformMXBean(Class) * ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class)} method. * * @deprecated {@code LoggingMXBean} is no longer a {@link - * java.lang.management.PlatformManagedObject platform MXBean} and is replaced - * with {@link java.lang.management.PlatformLoggingMXBean}. + * java.management/java.lang.management.PlatformManagedObject platform MXBean} and is replaced + * with {@link java.management/java.lang.management.PlatformLoggingMXBean}. * It will not register in the platform {@code MBeanServer}. * Use {@code ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class)} * instead. @@ -49,9 +49,10 @@ package java.util.logging; * @author Mandy Chung * @since 1.5 * - * @see java.lang.management.PlatformLoggingMXBean + * @see java.management/java.lang.management.PlatformLoggingMXBean */ @Deprecated(since="9") +@SuppressWarnings("doclint:reference") public interface LoggingMXBean { /** diff --git a/src/java.management/share/classes/java/lang/management/ManagementFactory.java b/src/java.management/share/classes/java/lang/management/ManagementFactory.java index cba413ccf63942c537588196c3c2bf3720df66de..13db85d0f094cc3b10e07d40500a662f15981cb2 100644 --- a/src/java.management/share/classes/java/lang/management/ManagementFactory.java +++ b/src/java.management/share/classes/java/lang/management/ManagementFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -176,7 +176,7 @@ import sun.management.spi.PlatformMBeanProvider.PlatformComponent; * * * {@link PlatformLoggingMXBean} - * {@link java.util.logging.LogManager#LOGGING_MXBEAN_NAME + * {@link java.logging/java.util.logging.LogManager#LOGGING_MXBEAN_NAME * java.util.logging:type=Logging} * * @@ -246,7 +246,8 @@ import sun.management.spi.PlatformMBeanProvider.PlatformComponent; * @author Mandy Chung * @since 1.5 */ -@SuppressWarnings("removal") +@SuppressWarnings({"removal", + "doclint:reference"}) // cross-module links public class ManagementFactory { // A class with only static fields and methods. private ManagementFactory() {}; diff --git a/src/java.management/share/classes/java/lang/management/MemoryMXBean.java b/src/java.management/share/classes/java/lang/management/MemoryMXBean.java index 716d2bcefca02a4c752b0f622147625f7850b7ee..f17e5e8077a86c5c947ab6d55458701e6c938d00 100644 --- a/src/java.management/share/classes/java/lang/management/MemoryMXBean.java +++ b/src/java.management/share/classes/java/lang/management/MemoryMXBean.java @@ -207,9 +207,15 @@ public interface MemoryMXBean extends PlatformManagedObject { * Returns the approximate number of objects for which * finalization is pending. * + * @deprecated Finalization has been deprecated for removal. See + * {@link java.lang.Object#finalize} for details. + * * @return the approximate number objects for which finalization - * is pending. + * is pending. If this MemoryMXBean contains information about a JVM in + * which finalization has been disabled or removed, this method always + * returns zero. */ + @Deprecated(since="18") public int getObjectPendingFinalizationCount(); /** diff --git a/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java b/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java index 80595dd75d6de9b57b81295fc053dd85c487e3ec..3a50dc20958785b066dd94a778abba8c320b2659 100644 --- a/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java +++ b/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ package java.lang.management; /** - * The management interface for the {@linkplain java.util.logging logging} facility. + * The management interface for the {@linkplain java.logging/java.util.logging logging} facility. * *

      There is a single global instance of the {@code PlatformLoggingMXBean}. * The {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) @@ -41,17 +41,18 @@ package java.lang.management; * The {@link javax.management.ObjectName ObjectName} for uniquely * identifying the {@code PlatformLoggingMXBean} within an MBeanServer is: *

      - *      {@link java.util.logging.LogManager#LOGGING_MXBEAN_NAME java.util.logging:type=Logging}
      + *      {@link java.logging/java.util.logging.LogManager#LOGGING_MXBEAN_NAME java.util.logging:type=Logging}
        * 
      * * @since 1.7 */ +@SuppressWarnings("doclint:reference") // cross-module links public interface PlatformLoggingMXBean extends PlatformManagedObject { /** * Returns the list of the currently registered - * {@linkplain java.util.logging.Logger logger} names. This method - * calls {@link java.util.logging.LogManager#getLoggerNames} and + * {@linkplain java.logging/java.util.logging.Logger logger} names. This method + * calls {@link java.logging/java.util.logging.LogManager#getLoggerNames} and * returns a list of the logger names. * * @return A list of {@code String} each of which is a @@ -60,15 +61,15 @@ public interface PlatformLoggingMXBean extends PlatformManagedObject { java.util.List getLoggerNames(); /** - * Gets the name of the log {@linkplain java.util.logging.Logger#getLevel + * Gets the name of the log {@linkplain java.logging/java.util.logging.Logger#getLevel * level} associated with the specified logger. * If the specified logger does not exist, {@code null} * is returned. * This method first finds the logger of the given name and * then returns the name of the log level by calling: *
      - * {@link java.util.logging.Logger#getLevel - * Logger.getLevel()}.{@link java.util.logging.Level#getName getName()}; + * {@link java.logging/java.util.logging.Logger#getLevel + * Logger.getLevel()}.{@link java.logging/java.util.logging.Level#getName getName()}; *
      * *

      @@ -83,16 +84,16 @@ public interface PlatformLoggingMXBean extends PlatformManagedObject { * is {@code null}. If the specified logger does not * exist, {@code null} is returned. * - * @see java.util.logging.Logger#getLevel + * @see java.logging/java.util.logging.Logger#getLevel */ String getLoggerLevel(String loggerName); /** * Sets the specified logger to the specified new - * {@linkplain java.util.logging.Logger#setLevel level}. + * {@linkplain java.logging/java.util.logging.Logger#setLevel level}. * If the {@code levelName} is not {@code null}, the level * of the specified logger is set to the parsed - * {@link java.util.logging.Level Level} + * {@link java.logging/java.util.logging.Level Level} * matching the {@code levelName}. * If the {@code levelName} is {@code null}, the level * of the specified logger is set to {@code null} and @@ -111,13 +112,13 @@ public interface PlatformLoggingMXBean extends PlatformManagedObject { * @throws SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). * - * @see java.util.logging.Logger#setLevel + * @see java.logging/java.util.logging.Logger#setLevel */ void setLoggerLevel(String loggerName, String levelName); /** * Returns the name of the - * {@linkplain java.util.logging.Logger#getParent parent} + * {@linkplain java.logging/java.util.logging.Logger#getParent parent} * for the specified logger. * If the specified logger does not exist, {@code null} is returned. * If the specified logger is the root {@code Logger} in the namespace, diff --git a/src/java.management/share/classes/javax/management/MXBean.java b/src/java.management/share/classes/javax/management/MXBean.java index f583ba62eaa23fe7a891672d7c9c0d7d47321f79..e1d740d39be734ea4cec09540a33cba71792ba3e 100644 --- a/src/java.management/share/classes/javax/management/MXBean.java +++ b/src/java.management/share/classes/javax/management/MXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -929,7 +929,7 @@ public interface ModuleMXBean {

    • Otherwise, if J has at least one public constructor with either {@link javax.management.ConstructorParameters @javax.management.ConstructorParameters} or - {@code @java.beans.ConstructoProperties} annotation, then one of those + {@code @java.beans.ConstructorProperties} annotation, then one of those constructors (not necessarily always the same one) will be called to reconstruct an instance of J. If a constructor is annotated with both diff --git a/src/java.management/share/classes/javax/management/remote/JMXAddressable.java b/src/java.management/share/classes/javax/management/remote/JMXAddressable.java index cc770b75194fc02d93a497ed7ef2b8b51682d6eb..b100004d51ed160c19ea5d4ff289b73b6d54fb6c 100644 --- a/src/java.management/share/classes/javax/management/remote/JMXAddressable.java +++ b/src/java.management/share/classes/javax/management/remote/JMXAddressable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * 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 @@ package javax.management.remote; * Depending on the connector implementation, a {@link JMXConnector} * object may implement this interface too. {@code JMXConnector} * objects for the RMI Connector are instances of - * {@link javax.management.remote.rmi.RMIConnector RMIConnector} which + * {@link java.management.rmi/javax.management.remote.rmi.RMIConnector RMIConnector} which * implements this interface.

      * *

      An object implementing this interface might not have an address @@ -41,6 +41,7 @@ package javax.management.remote; * * @since 1.6 */ +@SuppressWarnings("doclint:reference") // cross-module links public interface JMXAddressable { /** *

      The address of this object.

      diff --git a/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java b/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java index a8bf827fd3e778ea58a783e81760d9bb143dffe0..185912c6b660aeaadd08fbf00c14b6c0586c197a 100644 --- a/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java +++ b/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,9 +38,10 @@ import javax.management.MBeanServer; * JMXServerErrorException instance contains the original * Error that occurred as its cause. * - * @see java.rmi.ServerError + * @see java.rmi/java.rmi.ServerError * @since 1.5 */ +@SuppressWarnings("doclint:reference") // cross-module links public class JMXServerErrorException extends IOException { private static final long serialVersionUID = 3996732239558744666L; diff --git a/src/java.management/share/classes/sun/management/LockInfoCompositeData.java b/src/java.management/share/classes/sun/management/LockInfoCompositeData.java index 087ce3d780e17b162812015802044cd4e5a93cc2..bafdff2dbfb1f71d9dcd08d3c169ad8f7ce664d0 100644 --- a/src/java.management/share/classes/sun/management/LockInfoCompositeData.java +++ b/src/java.management/share/classes/sun/management/LockInfoCompositeData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ public class LockInfoCompositeData extends LazyCompositeData { return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE, items); } catch (OpenDataException e) { // Should never reach here - throw Util.newException(e); + throw new RuntimeException(e); } } @@ -79,7 +79,7 @@ public class LockInfoCompositeData extends LazyCompositeData { MappedMXBeanType.toOpenType(LockInfo.class); } catch (OpenDataException e) { // Should never reach here - throw Util.newException(e); + throw new RuntimeException(e); } } diff --git a/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java b/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java index 7e5c1d8764020de4a28ecf7c4194e5f1bd7ab5ef..3746cd311b2801b27560506fff1f044c216518dd 100644 --- a/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java +++ b/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -482,7 +482,7 @@ public class ManagementFactoryHelper { } }); } catch (PrivilegedActionException e) { - throw Util.newException(e.getException()); + throw new RuntimeException(e.getException()); } } @@ -540,7 +540,7 @@ public class ManagementFactoryHelper { } }); } catch (PrivilegedActionException e) { - throw Util.newException(e.getException()); + throw new RuntimeException(e.getException()); } } diff --git a/src/java.management/share/classes/sun/management/MemoryImpl.java b/src/java.management/share/classes/sun/management/MemoryImpl.java index 7850b90e7838c5a98e85ba2614505835ea8ff6d5..5bdbe7b63499bd516fa6042b940feeec0f31bcff 100644 --- a/src/java.management/share/classes/sun/management/MemoryImpl.java +++ b/src/java.management/share/classes/sun/management/MemoryImpl.java @@ -58,6 +58,7 @@ class MemoryImpl extends NotificationEmitterSupport this.jvm = vm; } + @SuppressWarnings("deprecation") public int getObjectPendingFinalizationCount() { return jdk.internal.misc.VM.getFinalRefCount(); } diff --git a/src/java.management/share/classes/sun/management/Util.java b/src/java.management/share/classes/sun/management/Util.java index 9ce1a5d31ee8be89e40a4b1204406b3c88a964bf..94bab86140cf7f214f4b2abae08336c6059d86ee 100644 --- a/src/java.management/share/classes/sun/management/Util.java +++ b/src/java.management/share/classes/sun/management/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,10 +34,6 @@ import javax.management.MalformedObjectNameException; public class Util { private Util() {} // there are no instances of this class - static RuntimeException newException(Exception e) { - throw new RuntimeException(e); - } - private static final String[] EMPTY_STRING_ARRAY = new String[0]; static String[] toStringArray(List list) { return list.toArray(EMPTY_STRING_ARRAY); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java b/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java index 94c15c09d11cd9ac9788a82656f1445c194432eb..5c7644212f979674ffc08774a0c8fcfdc5cb686a 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java @@ -383,7 +383,7 @@ abstract class AbstractLdapNamingEnumeration listArg = ne.listArg; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected final void finalize() { cleanup(); } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClient.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClient.java index d972766dc118c75a662d2a96a203e1eb63eefcfb..4834b6e530aec1bc71a22fcd2151c19a4766b5d5 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClient.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClient.java @@ -477,7 +477,7 @@ public final class LdapClient implements PooledConnection { } } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { if (debug > 0) System.err.println("LdapClient: finalize " + this); forceClose(pooled); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java index af94713155fab52e3e2d9be7b32b0cfda7c7ae55..eaaccac2ffe3552f5ed21acaf5cf7514507786f4 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java @@ -65,7 +65,23 @@ final class LdapClientFactory implements PooledConnectionFactory { connTimeout, readTimeout, trace, pcb); } + public PooledConnection createPooledConnection(PoolCallback pcb, long timeout) + throws NamingException { + return new LdapClient(host, port, socketFactory, + guardedIntegerCast(timeout), + readTimeout, trace, pcb); + } + public String toString() { return host + ":" + port; } + + private int guardedIntegerCast(long timeout) { + if (timeout < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } else if (timeout > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + return (int) timeout; + } } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java index 059b654f5818f534ff5ca6037cc3d4a7b6db9093..9a918edf0c3dd5451a86c41d1ba1bf4e2355c7ee 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java @@ -2639,7 +2639,7 @@ public final class LdapCtx extends ComponentDirContext // ----------------- Connection --------------------- - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { try { close(); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java index f64769ad51a0577d48d7609f3735b71b074a5c21..d485288ccac940baf3f5a3d5cf042f6b0e23c32f 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java @@ -27,6 +27,9 @@ package com.sun.jndi.ldap.pool; import java.util.ArrayList; // JDK 1.2 import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -68,13 +71,19 @@ final class Connections implements PoolCallback { com.sun.jndi.ldap.LdapPoolManager.trace; private static final int DEFAULT_SIZE = 10; + final private int initSize; private final int maxSize; private final int prefSize; private final List conns; + final private PooledConnectionFactory factory; private boolean closed = false; // Closed for business private Reference ref; // maintains reference to id to prevent premature GC + private boolean initialized = false; + private final ReentrantLock lock; + private final Condition connectionsAvailable; + /** * @param id the identity (connection request) of the connections in the list * @param initSize the number of connections to create initially @@ -87,105 +96,73 @@ final class Connections implements PoolCallback { * when one is removed. * @param factory The factory responsible for creating a connection */ - Connections(Object id, int initSize, int prefSize, int maxSize, - PooledConnectionFactory factory) throws NamingException { - + Connections(Object id, int initSize, int prefSize, int maxSize, PooledConnectionFactory factory, + ReentrantLock lock) throws NamingException { this.maxSize = maxSize; + this.lock = lock; + this.connectionsAvailable = lock.newCondition(); + this.factory = factory; + if (maxSize > 0) { // prefSize and initSize cannot exceed specified maxSize this.prefSize = Math.min(prefSize, maxSize); - initSize = Math.min(initSize, maxSize); + this.initSize = Math.min(initSize, maxSize); } else { this.prefSize = prefSize; + this.initSize = initSize; } - conns = new ArrayList<>(maxSize > 0 ? maxSize : DEFAULT_SIZE); + this.conns = new ArrayList<>(maxSize > 0 ? maxSize : DEFAULT_SIZE); + this.initialized = initSize <= 0; // Maintain soft ref to id so that this Connections' entry in // Pool doesn't get GC'ed prematurely - ref = new SoftReference<>(id); + this.ref = new SoftReference<>(id); d("init size=", initSize); d("max size=", maxSize); d("preferred size=", prefSize); + } - // Create initial connections - PooledConnection conn; - for (int i = 0; i < initSize; i++) { - conn = factory.createPooledConnection(this); - td("Create ", conn ,factory); - conns.add(new ConnectionDesc(conn)); // Add new idle conn to pool + void waitForAvailableConnection() throws InterruptedNamingException { + try { + d("get(): waiting"); + connectionsAvailable.await(); + } catch (InterruptedException e) { + throw new InterruptedNamingException( + "Interrupted while waiting for a connection"); } } - /** - * Retrieves a PooledConnection from this list of connections. - * Use an existing one if one is idle, or create one if the list's - * max size hasn't been reached. If max size has been reached, wait - * for a PooledConnection to be returned, or one to be removed (thus - * not reaching the max size any longer). - * - * @param timeout if > 0, msec to wait until connection is available - * @param factory creates the PooledConnection if one needs to be created - * - * @return A non-null PooledConnection - * @throws NamingException PooledConnection cannot be created, because this - * thread was interrupted while it waited for an available connection, - * or if it timed out while waiting, or the creation of a connection - * resulted in an error. - */ - synchronized PooledConnection get(long timeout, - PooledConnectionFactory factory) throws NamingException { - PooledConnection conn; - long start = (timeout > 0 ? System.currentTimeMillis() : 0); - long waittime = timeout; - - d("get(): before"); - while ((conn = getOrCreateConnection(factory)) == null) { - if (timeout > 0 && waittime <= 0) { - throw new CommunicationException( - "Timeout exceeded while waiting for a connection: " + - timeout + "ms"); - } - try { - d("get(): waiting"); - if (waittime > 0) { - wait(waittime); // Wait until one is released or removed - } else { - wait(); - } - } catch (InterruptedException e) { - throw new InterruptedNamingException( + void waitForAvailableConnection(long waitTime) throws InterruptedNamingException { + try { + d("get(): waiting"); + connectionsAvailable.await(waitTime, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + throw new InterruptedNamingException( "Interrupted while waiting for a connection"); - } - // Check whether we timed out - if (timeout > 0) { - long now = System.currentTimeMillis(); - waittime = timeout - (now - start); - } } - - d("get(): after"); - return conn; } /** * Retrieves an idle connection from this list if one is available. - * If none is available, create a new one if maxSize hasn't been reached. - * If maxSize has been reached, return null. - * Always called from a synchronized method. */ - private PooledConnection getOrCreateConnection( - PooledConnectionFactory factory) throws NamingException { - + PooledConnection getAvailableConnection(long timeout) throws NamingException { + if (!initialized) { + PooledConnection conn = createConnection(factory, timeout); + if (conns.size() >= initSize) { + this.initialized = true; + } + return conn; + } int size = conns.size(); // Current number of idle/nonidle conns - PooledConnection conn = null; if (prefSize <= 0 || size >= prefSize) { // If no prefSize specified, or list size already meets or // exceeds prefSize, then first look for an idle connection ConnectionDesc entry; - for (int i = 0; i < size; i++) { - entry = conns.get(i); + for (ConnectionDesc connectionDesc : conns) { + PooledConnection conn; + entry = connectionDesc; if ((conn = entry.tryUse()) != null) { d("get(): use ", conn); td("Use ", conn); @@ -193,17 +170,25 @@ final class Connections implements PoolCallback { } } } + return null; + } - // Check if list size already at maxSize specified - if (maxSize > 0 && size >= maxSize) { - return null; // List size is at limit; cannot create any more + /* + * Creates a new Connection if maxSize hasn't been reached. + * If maxSize has been reached, return null. + * Caller must hold the ReentrantLock. + */ + PooledConnection createConnection(PooledConnectionFactory factory, long timeout) + throws NamingException { + int size = conns.size(); // Current number of idle/non-idle connections + if (maxSize == 0 || size < maxSize) { + PooledConnection conn = factory.createPooledConnection(this, timeout); + td("Create and use ", conn, factory); + conns.add(new ConnectionDesc(conn, true)); // Add new conn to pool + return conn; } - conn = factory.createPooledConnection(this); - td("Create and use ", conn, factory); - conns.add(new ConnectionDesc(conn, true)); // Add new conn to pool - - return conn; + return null; } /** @@ -211,43 +196,45 @@ final class Connections implements PoolCallback { * If the list size is below prefSize, the connection may be reused. * If the list size exceeds prefSize, then the connection is closed * and removed from the list. - * + *

      * public because implemented as part of PoolCallback. */ - public synchronized boolean releasePooledConnection(PooledConnection conn) { - ConnectionDesc entry; - int loc = conns.indexOf(entry=new ConnectionDesc(conn)); - - d("release(): ", conn); - - if (loc >= 0) { - // Found entry + public boolean releasePooledConnection(PooledConnection conn) { + lock.lock(); + try { + ConnectionDesc entry; + int loc = conns.indexOf(entry = new ConnectionDesc(conn)); - if (closed || (prefSize > 0 && conns.size() > prefSize)) { - // If list size exceeds prefSize, close connection + d("release(): ", conn); - d("release(): closing ", conn); - td("Close ", conn); + if (loc >= 0) { + // Found entry - // size must be >= 2 so don't worry about empty list - conns.remove(entry); - conn.closeConnection(); + if (closed || (prefSize > 0 && conns.size() > prefSize)) { + // If list size exceeds prefSize, close connection - } else { - d("release(): release ", conn); - td("Release ", conn); + d("release(): closing ", conn); + td("Close ", conn); - // Get ConnectionDesc from list to get correct state info - entry = conns.get(loc); - // Return connection to list, ready for reuse - entry.release(); + // size must be >= 2 so don't worry about empty list + conns.remove(entry); + conn.closeConnection(); + } else { + d("release(): release ", conn); + td("Release ", conn); + // Get ConnectionDesc from list to get correct state info + entry = conns.get(loc); + // Return connection to list, ready for reuse + entry.release(); + } + connectionsAvailable.signalAll(); + d("release(): notify"); + return true; } - notifyAll(); - d("release(): notify"); - return true; - } else { - return false; + } finally { + lock.unlock(); } + return false; } /** @@ -257,29 +244,34 @@ final class Connections implements PoolCallback { * when using the connection and wants it removed from the pool. * * @return true if conn removed; false if it was not in pool - * + *

      * public because implemented as part of PoolCallback. */ - public synchronized boolean removePooledConnection(PooledConnection conn) { - if (conns.remove(new ConnectionDesc(conn))) { - d("remove(): ", conn); + public boolean removePooledConnection(PooledConnection conn) { + lock.lock(); + try { + if (conns.remove(new ConnectionDesc(conn))) { + d("remove(): ", conn); - notifyAll(); + connectionsAvailable.signalAll(); - d("remove(): notify"); - td("Remove ", conn); + d("remove(): notify"); + td("Remove ", conn); - if (conns.isEmpty()) { - // Remove softref to make pool entry eligible for GC. - // Once ref has been removed, it cannot be reinstated. - ref = null; - } + if (conns.isEmpty()) { + // Remove softref to make pool entry eligible for GC. + // Once ref has been removed, it cannot be reinstated. + ref = null; + } - return true; - } else { - d("remove(): not found ", conn); - return false; + return true; + } else { + d("remove(): not found ", conn); + } + } finally { + lock.unlock(); } + return false; } /** @@ -291,8 +283,11 @@ final class Connections implements PoolCallback { */ boolean expire(long threshold) { List clonedConns; - synchronized(this) { + lock.lock(); + try { clonedConns = new ArrayList<>(conns); + } finally { + lock.unlock(); } List expired = new ArrayList<>(); @@ -304,12 +299,15 @@ final class Connections implements PoolCallback { } } - synchronized (this) { + lock.lock(); + try { conns.removeAll(expired); // Don't need to call notify() because we're // removing only idle connections. If there were // idle connections, then there should be no waiters. return conns.isEmpty(); // whether whole list has 'expired' + } finally { + lock.unlock(); } } @@ -355,6 +353,29 @@ final class Connections implements PoolCallback { + "; idle=" + idle + "; expired=" + expired; } + boolean grabLock(long timeout) throws InterruptedNamingException { + final long start = System.nanoTime(); + long current = start; + long remaining = timeout; + boolean locked = false; + while (!locked && remaining > 0) { + try { + locked = lock.tryLock(remaining, TimeUnit.MILLISECONDS); + remaining -= TimeUnit.NANOSECONDS.toMillis(current - start); + } catch (InterruptedException ignore) { + throw new InterruptedNamingException( + "Interrupted while waiting for the connection pool lock"); + } + current = System.nanoTime(); + remaining -= TimeUnit.NANOSECONDS.toMillis(current - start); + } + return locked; + } + + void unlock() { + lock.unlock(); + } + private void d(String msg, Object o1) { if (debug) { d(msg + o1); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java index 24700cbdd1331a970e9fba2dcdf378a81cdad495..b7bc3ba98bfa9b7d76b93a79baeec154a74c6c18 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java @@ -31,10 +31,13 @@ import java.util.WeakHashMap; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; import java.io.PrintStream; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; +import javax.naming.CommunicationException; import javax.naming.NamingException; /** @@ -117,45 +120,109 @@ public final class Pool { public PooledConnection getPooledConnection(Object id, long timeout, PooledConnectionFactory factory) throws NamingException { + final long start = System.nanoTime(); + long remaining = timeout; + d("get(): ", id); if (debug) { synchronized (map) { d("size: ", map.size()); } + remaining = checkRemaining(start, remaining); } expungeStaleConnections(); + Connections conns = getOrCreateConnections(factory, id); + d("get(): size after: ", map.size()); + remaining = checkRemaining(start, remaining); + + if (!conns.grabLock(remaining)) { + throw new CommunicationException("Timed out waiting for lock"); + } + + try { + remaining = checkRemaining(start, remaining); + PooledConnection conn = null; + while (remaining > 0 && conn == null) { + conn = getOrCreatePooledConnection(factory, conns, start, remaining); + // don't loop if the timeout has expired + remaining = checkRemaining(start, timeout); + } + return conn; + } finally { + conns.unlock(); + } + } + + private Connections getOrCreateConnections(PooledConnectionFactory factory, Object id) + throws NamingException { + Connections conns; synchronized (map) { - conns = getConnections(id); - if (conns == null) { - d("get(): creating new connections list for ", id); - - // No connections for this id so create a new list - conns = new Connections(id, initSize, prefSize, maxSize, - factory); - ConnectionsRef connsRef = new ConnectionsRef(conns); - map.put(id, connsRef); - - // Create a weak reference to ConnectionsRef - Reference weakRef = - new ConnectionsWeakRef(connsRef, queue); - - // Keep the weak reference through the element of a linked list - weakRefs.add(weakRef); + ConnectionsRef ref = map.get(id); + if (ref != null) { + return ref.getConnections(); } - d("get(): size after: ", map.size()); + + d("get(): creating new connections list for ", id); + + // No connections for this id so create a new list + conns = new Connections(id, initSize, prefSize, maxSize, + factory, new ReentrantLock()); + + ConnectionsRef connsRef = new ConnectionsRef(conns); + map.put(id, connsRef); + + // Create a weak reference to ConnectionsRef + Reference weakRef = new ConnectionsWeakRef(connsRef, queue); + + // Keep the weak reference through the element of a linked list + weakRefs.add(weakRef); } + return conns; + } - return conns.get(timeout, factory); // get one connection from list + private PooledConnection getOrCreatePooledConnection( + PooledConnectionFactory factory, Connections conns, long start, long timeout) + throws NamingException { + PooledConnection conn = conns.getAvailableConnection(timeout); + if (conn != null) { + return conn; + } + // no available cached connection + // check if list size already at maxSize before creating a new one + conn = conns.createConnection(factory, timeout); + if (conn != null) { + return conn; + } + // max number of connections already created, + // try waiting around for one to become available + if (timeout <= 0) { + conns.waitForAvailableConnection(); + } else { + long remaining = checkRemaining(start, timeout); + conns.waitForAvailableConnection(remaining); + } + return null; } - private Connections getConnections(Object id) { - ConnectionsRef ref = map.get(id); - return (ref != null) ? ref.getConnections() : null; + // Check whether we timed out + private long checkRemaining(long start, long timeout) throws CommunicationException { + if (timeout > 0) { + long current = System.nanoTime(); + long remaining = timeout - TimeUnit.NANOSECONDS.toMillis(current - start); + if (remaining <= 0) { + throw new CommunicationException( + "Timeout exceeded while waiting for a connection: " + + timeout + "ms"); + } + return remaining; + } + return Long.MAX_VALUE; } + /** * Goes through the connections in this Pool and expires ones that * have been idle before 'threshold'. An expired connection is closed diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java index 3aa41769d4aba2625c5ec5d1f3794cac41aaf5aa..3f2944979682ad1fabf7c1db70a5460d50776ce5 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java @@ -44,4 +44,13 @@ public interface PooledConnectionFactory { */ public abstract PooledConnection createPooledConnection(PoolCallback pcb) throws NamingException; + + /** + * Creates a pooled connection. + * @param pcb callback responsible for removing and releasing the pooled + * connection from the pool. + * @param timeout the connection timeout + */ + public abstract PooledConnection createPooledConnection(PoolCallback pcb, long timeout) + throws NamingException; }; diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/DefaultCallbackHandler.java b/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/DefaultCallbackHandler.java index 2a782c0e9cc5442930c6193ceb4e00defe09e2e8..b6388915840b2d4df99c259f4b102b82acd67aa3 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/DefaultCallbackHandler.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/DefaultCallbackHandler.java @@ -131,7 +131,7 @@ final class DefaultCallbackHandler implements CallbackHandler { } } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { clearPassword(); } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/LdapSasl.java b/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/LdapSasl.java index bc557bfaa3564af50093c6dcdcdefbe221e09eeb..23be470604143677c22300e52df20e3d910024ea 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/LdapSasl.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/LdapSasl.java @@ -42,7 +42,9 @@ import javax.security.sasl.*; import com.sun.jndi.ldap.Connection; import com.sun.jndi.ldap.LdapClient; import com.sun.jndi.ldap.LdapResult; -import com.sun.jndi.ldap.sasl.TlsChannelBinding.TlsChannelBindingType; +import sun.security.util.ChannelBindingException; +import sun.security.util.TlsChannelBinding; +import sun.security.util.TlsChannelBinding.TlsChannelBindingType; /** * Handles SASL support. @@ -62,6 +64,14 @@ public final class LdapSasl { private static final int LDAP_SUCCESS = 0; private static final int LDAP_SASL_BIND_IN_PROGRESS = 14; // LDAPv3 + // TLS channel binding type property + private static final String CHANNEL_BINDING_TYPE = + "com.sun.jndi.ldap.tls.cbtype"; + + // internal TLS channel binding property + private static final String CHANNEL_BINDING = + "jdk.internal.sasl.tlschannelbinding"; + private LdapSasl() { } @@ -113,8 +123,8 @@ public final class LdapSasl { String[] mechs = getSaslMechanismNames(authMech); // Internal TLS Channel Binding property cannot be set explicitly - if (env.get(TlsChannelBinding.CHANNEL_BINDING) != null) { - throw new NamingException(TlsChannelBinding.CHANNEL_BINDING + + if (env.get(CHANNEL_BINDING) != null) { + throw new NamingException(CHANNEL_BINDING + " property cannot be set explicitly"); } @@ -123,17 +133,24 @@ public final class LdapSasl { try { // Prepare TLS Channel Binding data if (conn.isTlsConnection()) { - TlsChannelBindingType cbType = - TlsChannelBinding.parseType( - (String)env.get(TlsChannelBinding.CHANNEL_BINDING_TYPE)); + TlsChannelBindingType cbType; + try { + cbType = TlsChannelBinding.parseType((String)env.get(CHANNEL_BINDING_TYPE)); + } catch (ChannelBindingException e) { + throw wrapInNamingException(e); + } if (cbType == TlsChannelBindingType.TLS_SERVER_END_POINT) { // set tls-server-end-point channel binding X509Certificate cert = conn.getTlsServerCertificate(); if (cert != null) { - TlsChannelBinding tlsCB = - TlsChannelBinding.create(cert); + TlsChannelBinding tlsCB; + try { + tlsCB = TlsChannelBinding.create(cert); + } catch (ChannelBindingException e) { + throw wrapInNamingException(e); + } envProps = (Hashtable) env.clone(); - envProps.put(TlsChannelBinding.CHANNEL_BINDING, tlsCB.getData()); + envProps.put(CHANNEL_BINDING, tlsCB.getData()); } else { throw new SaslException("No suitable certificate to generate " + "TLS Channel Binding data"); @@ -227,5 +244,11 @@ public final class LdapSasl { return mechNames; } + private static NamingException wrapInNamingException(Exception e) { + NamingException ne = new NamingException(); + ne.setRootCause(e); + return ne; + } + private static final byte[] NO_BYTES = new byte[0]; } diff --git a/src/java.naming/share/classes/module-info.java b/src/java.naming/share/classes/module-info.java index f7d0ace806d12d21493002845d4412228743333f..43be8eb62991df6b57da5d35ed7117d230c6bf51 100644 --- a/src/java.naming/share/classes/module-info.java +++ b/src/java.naming/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,9 +104,11 @@ *

    • DNS Naming Provider
    • *
    • RMI Naming Provider
    • * - * @provides javax.naming.ldap.spi.LdapDnsProvider + * @provides java.security.Provider * + * @uses javax.naming.ldap.StartTlsResponse * @uses javax.naming.ldap.spi.LdapDnsProvider + * @uses javax.naming.spi.InitialContextFactory * * @moduleGraph * @since 9 diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java b/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java index 2561afd645d07ceff8c4ce329efd2fb60915f7ca..6e6182a1fb2a2eefc5c30ca754ec65c6da6cbb7d 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java @@ -305,7 +305,7 @@ class AuthenticationFilter implements HeaderFilter { AuthInfo au = proxy ? exchange.proxyauth : exchange.serverauth; if (au == null) { // if no authenticator, let the user deal with 407/401 - if (!exchange.client().authenticator().isPresent()) return null; + if (exchange.client().authenticator().isEmpty()) return null; PasswordAuthentication pw = getCredentials(authval, proxy, req); if (pw == null) { @@ -331,7 +331,7 @@ class AuthenticationFilter implements HeaderFilter { } // if no authenticator, let the user deal with 407/401 - if (!exchange.client().authenticator().isPresent()) return null; + if (exchange.client().authenticator().isEmpty()) return null; // try again PasswordAuthentication pw = getCredentials(authval, proxy, req); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java index a04ded70480a03b3a739e8b59d9c54bc0e61d307..3e5da6d4c147452217fdbd46c98dab23fb5578c8 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java @@ -124,7 +124,7 @@ public class HttpRequestImpl extends HttpRequest implements WebSocketRequest { checkTimeout(timeout); this.systemHeadersBuilder = new HttpHeadersBuilder(); } - if (!userHeaders.firstValue("User-Agent").isPresent()) { + if (userHeaders.firstValue("User-Agent").isEmpty()) { this.systemHeadersBuilder.setHeader("User-Agent", USER_AGENT); } this.uri = requestURI; @@ -182,7 +182,7 @@ public class HttpRequestImpl extends HttpRequest implements WebSocketRequest { this.userHeaders = other.userHeaders; this.isWebSocket = other.isWebSocket; this.systemHeadersBuilder = new HttpHeadersBuilder(); - if (!userHeaders.firstValue("User-Agent").isPresent()) { + if (userHeaders.firstValue("User-Agent").isEmpty()) { this.systemHeadersBuilder.setHeader("User-Agent", USER_AGENT); } this.uri = uri; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java index c22c36a1eb3bcc07346e36eebfadf206ff4bb613..09457b795b4b647fd58a234a596eb06ebdce0083 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java @@ -175,7 +175,7 @@ public final class Utils { // used by caller. public static final BiPredicate CONTEXT_RESTRICTED(HttpClient client) { - return (k, v) -> !client.authenticator().isPresent() || + return (k, v) -> client.authenticator().isEmpty() || (!k.equalsIgnoreCase("Authorization") && !k.equalsIgnoreCase("Proxy-Authorization")); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/BuilderImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/BuilderImpl.java index 7a8a540d2b3f55c0ad4c432dfec26561b4804b3a..452e83206f4bdff86572c7c8bbb4839932682706 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/BuilderImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/BuilderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,7 +72,7 @@ public final class BuilderImpl implements Builder { this.proxySelector = proxySelector; // If a proxy selector was supplied by the user, it should be present // on the client and should be the same that what we got as an argument - assert !client.proxy().isPresent() + assert client.proxy().isEmpty() || client.proxy().equals(proxySelector); this.headers = headers; this.subprotocols = subprotocols; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java index b4d456b76469849287b2af8bea8e9a224273b051..dd60bd621b798f9d5c5c90c748b58a6e6fd10ea8 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java @@ -28,7 +28,6 @@ package jdk.internal.net.http.websocket; import java.net.http.HttpClient; import java.net.http.HttpClient.Version; import java.net.http.HttpHeaders; -import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.net.http.WebSocketHandshakeException; @@ -62,7 +61,6 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; import java.util.stream.Stream; import static java.lang.String.format; @@ -281,7 +279,7 @@ public class OpeningHandshake { throws CheckFailedException { Optional opt = responseHeaders.firstValue(HEADER_PROTOCOL); - if (!opt.isPresent()) { + if (opt.isEmpty()) { // If there is no such header in the response, then the server // doesn't want to use any subprotocol return ""; @@ -363,7 +361,7 @@ public class OpeningHandshake { * or {@code null} if none is required or applicable. */ private static Proxy proxyFor(Optional selector, URI uri) { - if (!selector.isPresent()) { + if (selector.isEmpty()) { return null; } URI requestURI = createRequestURI(uri); // Based on the HTTP scheme diff --git a/src/java.rmi/share/classes/sun/rmi/log/LogInputStream.java b/src/java.rmi/share/classes/sun/rmi/log/LogInputStream.java index 649fa22516d43c991c3ae459c11937d2243d9f07..1dbdd3064bcf4ae06a911bc4ad8a8b8da0c72f58 100644 --- a/src/java.rmi/share/classes/sun/rmi/log/LogInputStream.java +++ b/src/java.rmi/share/classes/sun/rmi/log/LogInputStream.java @@ -128,7 +128,7 @@ class LogInputStream extends InputStream { /** * Closes the stream when garbage is collected. */ - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws IOException { close(); } diff --git a/src/java.rmi/share/man/rmiregistry.1 b/src/java.rmi/share/man/rmiregistry.1 index d4c84ea58c2e10e29887d482b18a07253dd11da2..d6e27ceec1ca1bfda4031284e2ed76f9cfca7b0d 100644 --- a/src/java.rmi/share/man/rmiregistry.1 +++ b/src/java.rmi/share/man/rmiregistry.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "RMIREGISTRY" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "RMIREGISTRY" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/java.scripting/share/man/jrunscript.1 b/src/java.scripting/share/man/jrunscript.1 index 2c7ac2d40bc8ac73e0a1043d71df7c36a0336d05..727f6d2cece36df01cf8c91d23b481ec9c110ac0 100644 --- a/src/java.scripting/share/man/jrunscript.1 +++ b/src/java.scripting/share/man/jrunscript.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JRUNSCRIPT" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JRUNSCRIPT" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java b/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java index c17b54dd3358da9718d96f7e2fd1ee0dc1d05c00..82f2391816bc2a8973537a72f485cf6d28bc0818 100644 --- a/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java +++ b/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java @@ -40,6 +40,9 @@ import sun.security.jgss.GSSManagerImpl; import sun.security.jgss.GSSContextImpl; import sun.security.jgss.GSSUtil; import sun.security.jgss.HttpCaller; +import sun.security.jgss.krb5.internal.TlsChannelBindingImpl; +import sun.security.util.ChannelBindingException; +import sun.security.util.TlsChannelBinding; /** * This class encapsulates all JAAS and JGSS API calls in a separate class @@ -65,7 +68,7 @@ public class NegotiatorImpl extends Negotiator { *
    • Creating GSSContext *
    • A first call to initSecContext */ - private void init(HttpCallerInfo hci) throws GSSException { + private void init(HttpCallerInfo hci) throws GSSException, ChannelBindingException { final Oid oid; if (hci.scheme.equalsIgnoreCase("Kerberos")) { @@ -100,6 +103,14 @@ public class NegotiatorImpl extends Negotiator { if (context instanceof GSSContextImpl) { ((GSSContextImpl)context).requestDelegPolicy(true); } + if (hci.serverCert != null) { + if (DEBUG) { + System.out.println("Negotiate: Setting CBT"); + } + // set the channel binding token + TlsChannelBinding b = TlsChannelBinding.create(hci.serverCert); + context.setChannelBinding(new TlsChannelBindingImpl(b.getData())); + } oneToken = context.initSecContext(new byte[0], 0, 0); } @@ -110,7 +121,7 @@ public class NegotiatorImpl extends Negotiator { public NegotiatorImpl(HttpCallerInfo hci) throws IOException { try { init(hci); - } catch (GSSException e) { + } catch (GSSException | ChannelBindingException e) { if (DEBUG) { System.out.println("Negotiate support not initiated, will " + "fallback to other scheme if allowed. Reason:"); diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java index f698d3b0e27da43eab550bbf638efb33e4b022fd..21b48d58fc226816f5d0e8dd8d200acda5a7ee16 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java @@ -154,7 +154,7 @@ public final class Krb5MechFactory implements MechanismFactory { sm.checkPermission(perm); } catch (SecurityException e) { if (DEBUG) { - System.out.println("Permission to initiate" + + System.out.println("Permission to initiate " + "kerberos init credential" + e.getMessage()); } throw e; diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java b/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java index 311dfadbdd7db0ef6a74a11e682bae7662aa1729..61a5d34186dd54d1e48441b46b2e762af1c2f311 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -866,6 +866,7 @@ public class SpNegoContext implements GSSContextSpi { mechContext.requestMutualAuth(mutualAuthState); mechContext.requestReplayDet(replayDetState); mechContext.requestSequenceDet(sequenceDetState); + mechContext.setChannelBinding(channelBinding); if (mechContext instanceof GSSContextImpl) { ((GSSContextImpl)mechContext).requestDelegPolicy( delegPolicyState); @@ -899,6 +900,7 @@ public class SpNegoContext implements GSSContextSpi { myCred.getInternalCred()); } mechContext = factory.manager.createContext(cred); + mechContext.setChannelBinding(channelBinding); } // pass token to mechanism acceptSecContext diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSCredElement.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSCredElement.java index bfe1807935a9ac556d5500b297d43f8fedf4c1df..447b6c947e9c73b4b0ae317e93e676c7d138502c 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSCredElement.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSCredElement.java @@ -132,7 +132,7 @@ public class GSSCredElement implements GSSCredentialSpi { return "N/A"; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { dispose(); } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java index 54641f2f6e6a7ac00066f40cfa30796d80fa1f9e..b449169c441600952c5cd2b105b91a8bae3093b6 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java @@ -290,7 +290,7 @@ public class GSSNameElement implements GSSNameSpi { } } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { dispose(); } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java index e89b109250e5ea9878d690c8d0d63a848a799fa3..61640be3507d91ccaa05d672e64457dd20a7610a 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java @@ -639,7 +639,7 @@ class NativeGSSContext implements GSSContextSpi { return isInitiator; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { dispose(); } diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ktab/KeyTab.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ktab/KeyTab.java index a2d2c683b97ad67ff9293ef8c396a0269f459445..e7d3ebdfda6cae737df6d90e9ae94f0dc0da4277 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ktab/KeyTab.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ktab/KeyTab.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -376,12 +376,33 @@ public class KeyTab implements KeyTabConstants { addEntry(service, service.getSalt(), psswd, kvno, append); } - // Called by KDC test + /** + * Adds a new entry in the key table. + * @param service the service which will have a new entry in the key table. + * @param salt specified non default salt, cannot be null + * @param psswd the password which generates the key. + * @param kvno the kvno to use, -1 means automatic increasing + * @param append false if entries with old kvno would be removed. + * Note: if kvno is not -1, entries with the same kvno are always removed + */ public void addEntry(PrincipalName service, String salt, char[] psswd, int kvno, boolean append) throws KrbException { EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys( - psswd, salt); + psswd, salt); + addEntry(service, encKeys, kvno, append); + } + + /** + * Adds a new entry in the key table. + * @param service the service which will have a new entry in the key table. + * @param encKeys the keys to be added + * @param kvno the kvno to use, -1 means automatic increasing + * @param append false if entries with old kvno would be removed. + * Note: if kvno is not -1, entries with the same kvno are always removed + */ + public void addEntry(PrincipalName service, EncryptionKey[] encKeys, + int kvno, boolean append) throws KrbException { // There should be only one maximum KVNO value for all etypes, so that // all added keys can have the same KVNO. diff --git a/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Ktab.java b/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Ktab.java index d09e4665b08b95439cc76cad0c9ca57e78b35484..108cd4c24bb45fff2e4df3595af63dd11c90d60d 100644 --- a/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Ktab.java +++ b/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Ktab.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ import sun.security.krb5.internal.ktab.*; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; -import java.io.File; import java.text.DateFormat; import java.util.Arrays; import java.util.Date; @@ -61,10 +60,12 @@ public class Ktab { int etype = -1; char[] password = null; - boolean forced = false; // true if delete without prompt. Default false + boolean fopt = false; // true if delete without prompt or + // add by contacting KDC. Default false boolean append = false; // true if new keys are appended. Default false int vDel = -1; // kvno to delete, -1 all, -2 old. Default -1 int vAdd = -1; // kvno to add. Default -1, means auto incremented + String salt = null; // salt to use. Default null, means default salt /** * The main program that can be invoked at command line. @@ -186,6 +187,12 @@ public class Ktab { error(args[i] + " is not valid after -" + action); } break; + case "-s": // salt for -a + if (++i >= args.length || args[i].startsWith("-")) { + error("A salt string must be specified after -s"); + } + salt = args[i]; + break; case "-n": // kvno for -a if (++i >= args.length || args[i].startsWith("-")) { error("A KVNO must be specified after -n"); @@ -213,8 +220,8 @@ public class Ktab { case "-t": // list timestamps showTime = true; break; - case "-f": // force delete, no prompt - forced = true; + case "-f": // force delete or get salt from KDC + fopt = true; break; case "-append": // -a, new keys append to file append = true; @@ -258,6 +265,10 @@ public class Ktab { * a new key table. */ void addEntry() { + if (salt != null && fopt) { + System.err.println("-s and -f cannot coexist when adding a keytab entry."); + System.exit(-1); + } PrincipalName pname = null; try { pname = new PrincipalName(principal); @@ -283,7 +294,15 @@ public class Ktab { } try { // admin.addEntry(pname, password); - table.addEntry(pname, password, vAdd, append); + if (fopt) { + KrbAsReqBuilder builder = new KrbAsReqBuilder(pname, password); + builder.action(); + table.addEntry(pname, builder.getKeys(true), vAdd, append); + } else if (salt != null) { + table.addEntry(pname, salt, password, vAdd, append); + } else { + table.addEntry(pname, password, vAdd, append); + } Arrays.fill(password, '0'); // clear password // admin.save(); table.save(); @@ -367,7 +386,7 @@ public class Ktab { PrincipalName pname = null; try { pname = new PrincipalName(principal); - if (!forced) { + if (!fopt) { String answer; BufferedReader cis = new BufferedReader(new InputStreamReader(System.in)); @@ -424,6 +443,7 @@ public class Ktab { printHelp(); System.exit(-1); } + /** * Prints out the help information. */ @@ -434,11 +454,13 @@ public class Ktab { System.out.println(); System.out.println("-l [-e] [-t]\n" + " list the keytab name and entries. -e with etype, -t with timestamp."); - System.out.println("-a [] [-n ] [-append]\n" + System.out.println("-a [] [-n ] [-f | -s ] [-append]\n" + " add new key entries to the keytab for the given principal name with\n" + " optional . If a is specified, new keys' Key Version\n" + " Numbers equal to the value, otherwise, automatically incrementing\n" - + " the Key Version Numbers. If -append is specified, new keys are\n" + + " the Key Version Numbers. If is specified, it will be used\n" + + " instead of the default salt. If -f is specified, the KDC will be\n" + + " contacted to fetch the salt. If -append is specified, new keys are\n" + " appended to the keytab, otherwise, old keys for the\n" + " same principal are removed."); System.out.println("-d [-f] [-e ] [ | all | old]\n" diff --git a/src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp b/src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp index 2f359a84e7be6a10f5aa00914a58dc465915e403..aa673367607484c082fbebf19d7ebd91eb6dec7e 100644 --- a/src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp +++ b/src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1043,6 +1043,10 @@ gss_accept_sec_context(OM_uint32 *minor_status, { PP(">>>> Calling UNIMPLEMENTED gss_accept_sec_context..."); PP("gss_accept_sec_context is not supported in this initiator-only library"); + if (output_token) { + output_token->length = 0; + output_token->value = NULL; + } return GSS_S_FAILURE; } diff --git a/src/java.security.sasl/share/classes/com/sun/security/sasl/CramMD5Base.java b/src/java.security.sasl/share/classes/com/sun/security/sasl/CramMD5Base.java index bbbe88a71e4e1001bbd4bdd92682700600f30137..b59b449e3c5f3136555eab52f5b6dbb695d910e2 100644 --- a/src/java.security.sasl/share/classes/com/sun/security/sasl/CramMD5Base.java +++ b/src/java.security.sasl/share/classes/com/sun/security/sasl/CramMD5Base.java @@ -136,7 +136,7 @@ abstract class CramMD5Base { } } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { clearPassword(); } diff --git a/src/java.security.sasl/share/classes/com/sun/security/sasl/PlainClient.java b/src/java.security.sasl/share/classes/com/sun/security/sasl/PlainClient.java index e365e772e6e0547df5f44c9eee4e8de9fe85dce3..04a8d9856c2c6611175621a43fa7570d5158cb85 100644 --- a/src/java.security.sasl/share/classes/com/sun/security/sasl/PlainClient.java +++ b/src/java.security.sasl/share/classes/com/sun/security/sasl/PlainClient.java @@ -195,7 +195,7 @@ final class PlainClient implements SaslClient { } } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { clearPassword(); } diff --git a/src/java.security.sasl/share/classes/com/sun/security/sasl/digest/DigestMD5Base.java b/src/java.security.sasl/share/classes/com/sun/security/sasl/digest/DigestMD5Base.java index 5e26277136ba8c276163eb10479f864470ed6a10..956a079ae996c8cb5c3e0e9815a8ffe9fefb21f9 100644 --- a/src/java.security.sasl/share/classes/com/sun/security/sasl/digest/DigestMD5Base.java +++ b/src/java.security.sasl/share/classes/com/sun/security/sasl/digest/DigestMD5Base.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,7 +158,7 @@ abstract class DigestMD5Base extends AbstractSaslImpl { protected String authzid; // authzid or canonicalized authzid /** - * Constucts an instance of DigestMD5Base. Calls super constructor + * Constructs an instance of DigestMD5Base. Calls super constructor * to parse properties for mechanism. * * @param props A map of property/value pairs diff --git a/src/java.security.sasl/share/classes/javax/security/sasl/SaslServer.java b/src/java.security.sasl/share/classes/javax/security/sasl/SaslServer.java index 697b790deed97fe9cc1f6a8af0de2970a6586218..1e2d08aa8a1481e8c4f4a1a1f6b74fbcf3a03b18 100644 --- a/src/java.security.sasl/share/classes/javax/security/sasl/SaslServer.java +++ b/src/java.security.sasl/share/classes/javax/security/sasl/SaslServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,7 +105,7 @@ public abstract interface SaslServer { * by sending a challenge to the client, or if the authentication has * succeeded but challenge data needs to be processed by the client. * {@code isComplete()} should be called - * after each call to {@code evaluateResponse()},to determine if any further + * after each call to {@code evaluateResponse()}, to determine if any further * response is needed from the client. * * @param response The non-null (but possibly empty) response sent diff --git a/src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java b/src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java index 576333a1421cacd83ba74fdb0980a805d6e6edda..b982df5dd07237b66d24b2b553558789213d4e65 100644 --- a/src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java +++ b/src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java @@ -276,7 +276,7 @@ final class CardImpl extends Card { + ", protocol " + getProtocol() + ", state " + state; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { try { if (state == State.OK) { diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle.properties index 47ad98d28aec6157e89526bd35796ee0f79a0612..f84ede5eb41b3274fb496db71111b3078994a947 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow : no meta data cachedrowsetimpl.movetoins2 = moveToInsertRow : invalid number of columns cachedrowsetimpl.tablename = Table name cannot be null cachedrowsetimpl.keycols = Invalid key columns -cachedrowsetimpl.invalidcol = Invalid column index cachedrowsetimpl.opnotsupp = Operation not supported by Database cachedrowsetimpl.matchcols = Match columns are not the same as those set cachedrowsetimpl.setmatchcols = Set Match columns before getting them diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties index fe9d17299e7c561f575625bfd17e7fba4e803b5f..e1e43a16010cecd4df619ec025dcbaf7fe090f40 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: keine Metadaten cachedrowsetimpl.movetoins2 = moveToInsertRow: ung\u00FCltige Spaltenanzahl cachedrowsetimpl.tablename = Tabellenname darf nicht null sein cachedrowsetimpl.keycols = Ung\u00FCltige Schl\u00FCsselspalten -cachedrowsetimpl.invalidcol = Ung\u00FCltiger Spaltenindex cachedrowsetimpl.opnotsupp = Vorgang nicht von Datenbank unterst\u00FCtzt cachedrowsetimpl.matchcols = \u00DCbereinstimmungsspalten entsprechen nicht den festgelegten Spalten cachedrowsetimpl.setmatchcols = \u00DCbereinstimmungsspalten m\u00FCssen vor dem Abrufen festgelegt werden diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties index 8f9cb1f2392543f5735d322ee58c1b88ec4014b5..a07408974a35a5dd1edbc63d0d527084cc221d0b 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: no hay metadatos cachedrowsetimpl.movetoins2 = moveToInsertRow: n\u00FAmero de columnas no v\u00E1lido cachedrowsetimpl.tablename = El nombre de la tabla no puede ser nulo cachedrowsetimpl.keycols = Columnas clave no v\u00E1lidas -cachedrowsetimpl.invalidcol = \u00CDndice de columnas no v\u00E1lido cachedrowsetimpl.opnotsupp = La base de datos no admite esta operaci\u00F3n cachedrowsetimpl.matchcols = Las columnas coincidentes no concuerdan con las definidas cachedrowsetimpl.setmatchcols = Defina las columnas coincidentes antes de obtenerlas diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties index 4beab2bf8f1552904e7d8a0e8d15753b153a70da..585ed33b035115b0ebd140ee98b1bba4d654c271 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow : aucune m\u00E9tadonn\u00E9e cachedrowsetimpl.movetoins2 = moveToInsertRow : nombre de colonnes non valide cachedrowsetimpl.tablename = Le nom de la table ne peut pas \u00EAtre NULL cachedrowsetimpl.keycols = Colonnes de cl\u00E9 non valides -cachedrowsetimpl.invalidcol = Index de colonne non valide cachedrowsetimpl.opnotsupp = Op\u00E9ration non prise en charge par la base de donn\u00E9es cachedrowsetimpl.matchcols = Les colonnes correspondantes ne sont pas les m\u00EAmes que les colonnes d\u00E9finies cachedrowsetimpl.setmatchcols = D\u00E9finir les colonnes correspondantes avant de les prendre diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties index 4261aedea70c0e920e9fc838932c08aeadaf67ab..f971660d290084ba8711e8a50cf094fc982c6ec1 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: nessun metadato cachedrowsetimpl.movetoins2 = moveToInsertRow: numero di colonne non valido cachedrowsetimpl.tablename = Il nome di tabella non pu\u00F2 essere nullo cachedrowsetimpl.keycols = Colonne chiave non valide -cachedrowsetimpl.invalidcol = Indice di colonna non valido cachedrowsetimpl.opnotsupp = Operazione non supportata dal database cachedrowsetimpl.matchcols = Le colonne di corrispondenza non coincidono con le colonne impostate cachedrowsetimpl.setmatchcols = Impostare le colonne di corrispondenza prima di recuperarle diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties index 3192a22063e67b6733b9ada25d63e5dc7b3f9937..cd40ad2ef42837884eabb474a0044fe4eea56c98 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: \u30E1\u30BF\u30C7\u30FC\u30BF\u3 cachedrowsetimpl.movetoins2 = moveToInsertRow: \u7121\u52B9\u306A\u5217\u6570 cachedrowsetimpl.tablename = \u8868\u540D\u306Bnull\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093 cachedrowsetimpl.keycols = \u7121\u52B9\u306A\u30AD\u30FC\u5217 -cachedrowsetimpl.invalidcol = \u7121\u52B9\u306A\u5217\u7D22\u5F15 cachedrowsetimpl.opnotsupp = \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u306A\u3044\u64CD\u4F5C cachedrowsetimpl.matchcols = \u4E00\u81F4\u5217\u304C\u5217\u306E\u30BB\u30C3\u30C8\u3068\u540C\u3058\u3067\u306F\u3042\u308A\u307E\u305B\u3093 cachedrowsetimpl.setmatchcols = \u4E00\u81F4\u5217\u3092\u53D6\u5F97\u3059\u308B\u524D\u306B\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties index 81e468eeb1d9fde5d7478741c214cd4fb72af300..9041d6714838330ea4893b70612c9bee0943c1e0 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: \uBA54\uD0C0\uB370\uC774\uD130\uA cachedrowsetimpl.movetoins2 = moveToInsertRow: \uC5F4 \uC218\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. cachedrowsetimpl.tablename = \uD14C\uC774\uBE14 \uC774\uB984\uC740 \uB110\uC77C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.keycols = \uD0A4 \uC5F4\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. -cachedrowsetimpl.invalidcol = \uC5F4 \uC778\uB371\uC2A4\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. cachedrowsetimpl.opnotsupp = \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0\uC11C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC791\uC5C5\uC785\uB2C8\uB2E4. cachedrowsetimpl.matchcols = \uC77C\uCE58 \uC5F4\uC774 \uC124\uC815\uB41C \uC5F4\uACFC \uB3D9\uC77C\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.setmatchcols = \uC77C\uCE58 \uC5F4\uC744 \uC124\uC815\uD55C \uD6C4 \uAC00\uC838\uC624\uC2ED\uC2DC\uC624. diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_pt_BR.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_pt_BR.properties index 6a2ebe4fa312c8a7322d5def237bb1e63fd428fc..05a783ee8fc5e3256808532ee4122a7a95f87e7e 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_pt_BR.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_pt_BR.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow : sem metadados cachedrowsetimpl.movetoins2 = moveToInsertRow : n\u00FAmero de colunas inv\u00E1lido cachedrowsetimpl.tablename = O nome da tabela n\u00E3o pode ser nulo cachedrowsetimpl.keycols = Colunas de chaves inv\u00E1lidas -cachedrowsetimpl.invalidcol = \u00CDndice de coluna inv\u00E1lido cachedrowsetimpl.opnotsupp = Opera\u00E7\u00E3o n\u00E3o suportada pelo Banco de Dados cachedrowsetimpl.matchcols = As colunas correspondentes n\u00E3o s\u00E3o iguais \u00E0s colunas definidas cachedrowsetimpl.setmatchcols = Definir Colunas correspondentes antes de obt\u00EA-las diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties index 912dc2572196cd1952633e068c08649f062a0f9e..5cac0f3c502ca13d357fe089f5e945acba6484d0 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: inga metadata cachedrowsetimpl.movetoins2 = moveToInsertRow: ogiltigt antal kolumner cachedrowsetimpl.tablename = Tabellnamnet kan inte vara null cachedrowsetimpl.keycols = Ogiltiga nyckelkolumner -cachedrowsetimpl.invalidcol = Ogiltigt kolumnindex cachedrowsetimpl.opnotsupp = Databasen har inte st\u00F6d f\u00F6r denna \u00E5tg\u00E4rd cachedrowsetimpl.matchcols = Matchningskolumnerna \u00E4r inte samma som de som st\u00E4llts in cachedrowsetimpl.setmatchcols = St\u00E4ll in matchningskolumnerna innan du h\u00E4mtar dem diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties index adb91c4e8d85a186e392b498debb64fcb1e1c947..a9f1203518caa09600b935d8d034bb505bc43db4 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: \u65E0\u5143\u6570\u636E cachedrowsetimpl.movetoins2 = moveToInsertRow: \u5217\u6570\u65E0\u6548 cachedrowsetimpl.tablename = \u8868\u540D\u4E0D\u80FD\u4E3A\u7A7A\u503C cachedrowsetimpl.keycols = \u5173\u952E\u5B57\u5217\u65E0\u6548 -cachedrowsetimpl.invalidcol = \u5217\u7D22\u5F15\u65E0\u6548 cachedrowsetimpl.opnotsupp = \u64CD\u4F5C\u4E0D\u53D7\u6570\u636E\u5E93\u652F\u6301 cachedrowsetimpl.matchcols = \u5339\u914D\u5217\u4E0E\u8BBE\u7F6E\u7684\u90A3\u4E9B\u5339\u914D\u5217\u4E0D\u540C cachedrowsetimpl.setmatchcols = \u5728\u83B7\u53D6\u5339\u914D\u5217\u4E4B\u524D\u5148\u8BBE\u7F6E\u5339\u914D\u5217 diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties index dba19053aee8877fbbbe6c9583cd8f667901255c..d42340d39e4fb8f5d4a279cda72d0970d81de675 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: \u6C92\u6709\u63CF\u8FF0\u8CC7\u6 cachedrowsetimpl.movetoins2 = moveToInsertRow: \u6B04\u6578\u7121\u6548 cachedrowsetimpl.tablename = \u8868\u683C\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A\u503C cachedrowsetimpl.keycols = \u95DC\u9375\u6B04\u7121\u6548 -cachedrowsetimpl.invalidcol = \u6B04\u7D22\u5F15\u7121\u6548 cachedrowsetimpl.opnotsupp = \u8CC7\u6599\u5EAB\u4E0D\u652F\u63F4\u4F5C\u696D cachedrowsetimpl.matchcols = \u5339\u914D\u6B04\u548C\u8A2D\u5B9A\u7684\u6B04\u4E0D\u540C cachedrowsetimpl.setmatchcols = \u5728\u53D6\u5F97\u5339\u914D\u6B04\u4E4B\u524D\u8A2D\u5B9A\u5B83\u5011 diff --git a/src/java.sql/share/classes/java/sql/BatchUpdateException.java b/src/java.sql/share/classes/java/sql/BatchUpdateException.java index c94f0788e1179a650b3025349e1c5a161d0a9d19..3e480102952da835dc6ec0caaf20a97dbffae252 100644 --- a/src/java.sql/share/classes/java/sql/BatchUpdateException.java +++ b/src/java.sql/share/classes/java/sql/BatchUpdateException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ import java.util.Arrays; *

      * A JDBC driver implementation should use * the constructor {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) } instead of + * int vendorCode, long []updateCounts, Throwable cause) } instead of * constructors that take {@code int[]} for the update counts to avoid the * possibility of overflow. *

      @@ -78,7 +78,7 @@ public class BatchUpdateException extends SQLException { * Note: There is no validation of {@code updateCounts} for * overflow and because of this it is recommended that you use the constructor * {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) }. + * int vendorCode, long []updateCounts, Throwable cause) }. *

      * @param reason a description of the error * @param SQLState an XOPEN or SQL:2003 code identifying the exception @@ -115,7 +115,7 @@ public class BatchUpdateException extends SQLException { * Note: There is no validation of {@code updateCounts} for * overflow and because of this it is recommended that you use the constructor * {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) }. + * int vendorCode, long []updateCounts, Throwable cause) }. *

      * @param reason a description of the exception * @param SQLState an XOPEN or SQL:2003 code identifying the exception @@ -148,7 +148,7 @@ public class BatchUpdateException extends SQLException { * Note: There is no validation of {@code updateCounts} for * overflow and because of this it is recommended that you use the constructor * {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) }. + * int vendorCode, long []updateCounts, Throwable cause) }. *

      * @param reason a description of the exception * @param updateCounts an array of {@code int}, with each element @@ -178,7 +178,7 @@ public class BatchUpdateException extends SQLException { * Note: There is no validation of {@code updateCounts} for * overflow and because of this it is recommended that you use the constructor * {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) }. + * int vendorCode, long []updateCounts, Throwable cause) }. *

      * @param updateCounts an array of {@code int}, with each element * indicating the update count, {@code Statement.SUCCESS_NO_INFO} or @@ -244,7 +244,7 @@ public class BatchUpdateException extends SQLException { * Note: There is no validation of {@code updateCounts} for * overflow and because of this it is recommended that you use the constructor * {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) }. + * int vendorCode, long []updateCounts, Throwable cause) }. *

      * @param updateCounts an array of {@code int}, with each element * indicating the update count, {@code Statement.SUCCESS_NO_INFO} or @@ -274,7 +274,7 @@ public class BatchUpdateException extends SQLException { * Note: There is no validation of {@code updateCounts} for * overflow and because of this it is recommended that you use the constructor * {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) }. + * int vendorCode, long []updateCounts, Throwable cause) }. *

      * @param reason a description of the exception * @param updateCounts an array of {@code int}, with each element @@ -315,7 +315,7 @@ public class BatchUpdateException extends SQLException { * Note: There is no validation of {@code updateCounts} for * overflow and because of this it is recommended that you use the constructor * {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) }. + * int vendorCode, long []updateCounts, Throwable cause) }. *

      * @param cause the underlying reason for this {@code SQLException} * (which is saved for later retrieval by the {@code getCause()} method); @@ -351,7 +351,7 @@ public class BatchUpdateException extends SQLException { * Note: There is no validation of {@code updateCounts} for * overflow and because of this it is recommended that you use the constructor * {@code BatchUpdateException(String reason, String SQLState, - * int vendorCode, long []updateCounts,Throwable cause) }. + * int vendorCode, long []updateCounts, Throwable cause) }. *

      * @param cause the underlying reason for this {@code SQLException} (which is saved for later retrieval by the {@code getCause()} method); * may be null indicating diff --git a/src/java.sql/share/classes/java/sql/Connection.java b/src/java.sql/share/classes/java/sql/Connection.java index 0221696ee8fa9727854a1c3135e1ef9d3477bea5..0a5429d302f1594a8d559dbb9de1cf94e587e305 100644 --- a/src/java.sql/share/classes/java/sql/Connection.java +++ b/src/java.sql/share/classes/java/sql/Connection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -634,7 +634,7 @@ public interface Connection extends Wrapper, AutoCloseable { * custom mapping of SQL structured types and distinct types. *

      * You must set the values for the {@code TypeMap} prior to - * callng {@code setMap} as a JDBC driver may create an internal copy + * calling {@code setMap} as a JDBC driver may create an internal copy * of the {@code TypeMap}: * *

      @@ -1594,7 +1594,7 @@ throws SQLException;
           /**
            * Sets and validates the sharding keys for this connection. A {@code null}
            * value may be specified for the sharding Key. The validity
      -     * of a {@code null} sharding key is vendor-specific. Consult your vendor's
      +     * of a {@code null} sharding key is vendor-specific. Consult your vendor's
            * documentation for additional information.
            * @implSpec
            * The default implementation will throw a
      @@ -1616,7 +1616,7 @@ throws SQLException;
            * and set on this connection; false if the sharding keys are not valid or
            * the timeout period expires before the operation completes.
            * @throws SQLException if an error occurs while performing this validation;
      -     * a {@code superSharedingKey} is specified
      +     * a {@code superShardingKey} is specified
            * without a {@code shardingKey};
            * this method is called on a closed {@code connection}; or
            * the {@code timeout} value is negative.
      @@ -1634,7 +1634,7 @@ throws SQLException;
           /**
            * Sets and validates the sharding key for this connection. A {@code null}
            * value may be specified for the sharding Key. The validity
      -     * of a {@code null} sharding key is vendor-specific. Consult your vendor's
      +     * of a {@code null} sharding key is vendor-specific. Consult your vendor's
            * documentation for additional information.
            * @implSpec
            * The default implementation will throw a
      @@ -1680,7 +1680,7 @@ throws SQLException;
            * The super sharding key may be {@code null}
            * @throws SQLException if an error  occurs setting the sharding keys;
            * this method is called on a closed {@code connection}; or
      -     * a {@code superSharedingKey} is specified without a {@code shardingKey}
      +     * a {@code superShardingKey} is specified without a {@code shardingKey}
            * @throws SQLFeatureNotSupportedException if the driver does not support sharding
            * @since 9
            * @see ShardingKey
      diff --git a/src/java.sql/share/classes/java/sql/DatabaseMetaData.java b/src/java.sql/share/classes/java/sql/DatabaseMetaData.java
      index 532c37ee4bb3a1cf422391a83f9666f7fe59b1c5..6f63c2989b80aa27ed05586c0e5c2fcdb6342b55 100644
      --- a/src/java.sql/share/classes/java/sql/DatabaseMetaData.java
      +++ b/src/java.sql/share/classes/java/sql/DatabaseMetaData.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * This code is free software; you can redistribute it and/or modify it
      @@ -1513,7 +1513,7 @@ public interface DatabaseMetaData extends Wrapper {
            * @param tableNamePattern a table name pattern; must match the
            *        table name as it is stored in the database
            * @param types a list of table types, which must be from the list of table types
      -     *         returned from {@link #getTableTypes},to include; {@code null} returns
      +     *         returned from {@link #getTableTypes}, to include; {@code null} returns
            * all types
            * @return {@code ResultSet} - each row is a table description
            * @throws SQLException if a database access error occurs
      @@ -3044,7 +3044,7 @@ public interface DatabaseMetaData extends Wrapper {
            *  
    • SCOPE_TABLE String {@code =>} table name that is the scope of a * reference attribute ({@code null} if the DATA_TYPE isn't REF) *
    • SOURCE_DATA_TYPE short {@code =>} source type of a distinct type or user-generated - * Ref type,SQL type from java.sql.Types ({@code null} if DATA_TYPE + * Ref type, SQL type from java.sql.Types ({@code null} if DATA_TYPE * isn't DISTINCT or user-generated REF) * * @param catalog a catalog name; must match the catalog name as it diff --git a/src/java.sql/share/classes/java/sql/Statement.java b/src/java.sql/share/classes/java/sql/Statement.java index 10c8d9e12c6a92b8f690083d82fff3bfc4054dd4..bb5a5cfd64d963379652b1f03dff3f5d143639c9 100644 --- a/src/java.sql/share/classes/java/sql/Statement.java +++ b/src/java.sql/share/classes/java/sql/Statement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -779,7 +779,7 @@ public interface Statement extends Wrapper, AutoCloseable { * * @throws SQLException if a database access error occurs, * this method is called on a closed {@code Statement}, the SQL - * statement returns a {@code ResultSet} object,the second argument + * statement returns a {@code ResultSet} object, the second argument * supplied to this method is not an * {@code int} array whose elements are valid column indexes, the method is called on a * {@code PreparedStatement} or {@code CallableStatement} @@ -960,7 +960,7 @@ public interface Statement extends Wrapper, AutoCloseable { * object; {@code false} if it is an update count or there * are no more results * @throws SQLException if a database access error occurs, - * this method is called on a closed {@code Statement},the + * this method is called on a closed {@code Statement}, the * elements of the {@code String} array passed to this * method are not valid column names, the method is called on a * {@code PreparedStatement} or {@code CallableStatement} diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java index 4c51e7b5e8397d771f6eda8ec826a6d415335cbe..a35a4699d82a4aee7da45a9882350a95abdf7fba 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java @@ -84,7 +84,7 @@ public class Init { } @SuppressWarnings("removal") - InputStream is = + InputStream is = //NOPMD AccessController.doPrivileged( (PrivilegedAction) () -> { @@ -351,6 +351,9 @@ public class Init { * @param callingClass The Class object of the calling object */ public static URL getResource(String resourceName, Class callingClass) { + if (resourceName == null) { + throw new NullPointerException(); + } URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName); if (url == null && resourceName.charAt(0) == '/') { //certain classloaders need it without the leading / @@ -404,6 +407,9 @@ public class Init { * @param callingClass The Class object of the calling object */ private static List getResources(String resourceName, Class callingClass) { + if (resourceName == null) { + throw new NullPointerException(); + } List ret = new ArrayList<>(); Enumeration urls = new Enumeration() { public boolean hasMoreElements() { @@ -479,7 +485,7 @@ public class Init { } - if (ret.isEmpty() && resourceName != null && resourceName.charAt(0) != '/') { + if (ret.isEmpty() && resourceName.charAt(0) != '/') { return getResources('/' + resourceName, callingClass); } return ret; diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java index 90302d478446dc9cd6cdbc19bbfcf39418972b3d..fdaf8643279c8d57aa4684cef02007a0fc8dfb6c 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java @@ -309,7 +309,7 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { Node n = XMLUtils.selectDsNode(element.getFirstChild(), Constants._TAG_HMACOUTPUTLENGTH, 0); if (n != null) { String hmacLength = XMLUtils.getFullTextChildrenFromNode(n); - if (hmacLength != null && !"".equals(hmacLength)) { + if (hmacLength != null && hmacLength.length() != 0) { this.hmacOutputLength = new HMACOutputLength(Integer.parseInt(hmacLength)); } } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java index 1ed26fea60bc84ef4a6a6372bd496efb3106a6a2..f0cd610b3209a06fa3aa83eb02844c94e867861f 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java @@ -125,7 +125,7 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase { * Output the Attr[]s for the given element. *
      * The code of this method is a copy of - * {@link #outputAttributes(Element, NameSpaceSymbTable, Map)}, + * {@link #outputAttributes(Element, NameSpaceSymbTable, Map, OutputStream)}, * whereas it takes into account that subtree-c14n is -- well -- subtree-based. * So if the element in question isRoot of c14n, it's parent is not in the * node set, as well as all other ancestors. diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java index d3b972c95f853ea3ac48db2e1447ca511ff126ba..ce971a45a98101196cd9112dfc4c041021cc64a2 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java @@ -211,7 +211,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { Node sibling = null; Node parentNode = null; Map cache = new HashMap<>(); - do { + do { //NOPMD switch (currentNode.getNodeType()) { case Node.ENTITY_NODE : @@ -338,7 +338,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { Node parentNode = null; int documentLevel = NODE_BEFORE_DOCUMENT_ELEMENT; Map cache = new HashMap<>(); - do { + do { //NOPMD switch (currentNode.getNodeType()) { case Node.ENTITY_NODE : @@ -560,7 +560,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi { } parents.clear(); Attr nsprefix = ns.getMappingWithoutRendered(XMLNS); - if (nsprefix != null && "".equals(nsprefix.getValue())) { + if (nsprefix != null && nsprefix.getValue().length() == 0) { ns.addMappingAndRender( XMLNS, "", getNullNode(nsprefix.getOwnerDocument())); } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java index 4b2333938f5cc7335735420f6da4d9955d136bbf..66ad12029fc0d29f78edff7254c759e711445dd3 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java @@ -110,7 +110,7 @@ public class CanonicalizerPhysical extends CanonicalizerBase { * Output the Attr[]s for the given element. *
      * The code of this method is a copy of - * {@link #outputAttributes(Element, NameSpaceSymbTable, Map)}, + * {@link #outputAttributes(Element, NameSpaceSymbTable, Map, OutputStream)}, * whereas it takes into account that subtree-c14n is -- well -- subtree-based. * So if the element in question isRoot of c14n, it's parent is not in the * node set, as well as all other ancestors. diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java index 2fc853fe6901806728b4ffdab78203b2abae77c1..f0b1903accdcdba0933aa17efb819007fb4bb1e0 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java @@ -348,7 +348,7 @@ class SymbMap implements Cloneable { List entrySet() { List a = new ArrayList<>(); for (int i = 0;i < entries.length;i++) { - if (entries[i] != null && !"".equals(entries[i].uri)) { + if (entries[i] != null && entries[i].uri.length() != 0) { a.add(entries[i]); } } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityRuntimeException.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityRuntimeException.java deleted file mode 100644 index 7d17fe867e1ac1d7380b20feae5e24055cb55085..0000000000000000000000000000000000000000 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityRuntimeException.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package com.sun.org.apache.xml.internal.security.exceptions; - -import java.text.MessageFormat; - -import com.sun.org.apache.xml.internal.security.utils.Constants; -import com.sun.org.apache.xml.internal.security.utils.I18n; - -/** - * The mother of all runtime Exceptions in this bundle. It allows exceptions to have - * their messages translated to the different locales. - * - * The {@code xmlsecurity_en.properties} file contains this line: - *
      - * xml.WrongElement = Can't create a {0} from a {1} element
      - * 
      - * - * Usage in the Java source is: - *
      - * {
      - *    Object[] exArgs = { Constants._TAG_TRANSFORMS, "BadElement" };
      - *
      - *    throw new XMLSecurityException("xml.WrongElement", exArgs);
      - * }
      - * 
      - * - * Additionally, if another Exception has been caught, we can supply it, too - *
      - * try {
      - *    ...
      - * } catch (Exception oldEx) {
      - *    Object[] exArgs = { Constants._TAG_TRANSFORMS, "BadElement" };
      - *
      - *    throw new XMLSecurityException("xml.WrongElement", exArgs, oldEx);
      - * }
      - * 
      - * - * - */ -public class XMLSecurityRuntimeException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - /** Field msgID */ - protected String msgID; - - /** - * Constructor XMLSecurityRuntimeException - * - */ - public XMLSecurityRuntimeException() { - super("Missing message string"); - - this.msgID = null; - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param msgID - */ - public XMLSecurityRuntimeException(String msgID) { - super(I18n.getExceptionMessage(msgID)); - - this.msgID = msgID; - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param msgID - * @param exArgs - */ - public XMLSecurityRuntimeException(String msgID, Object[] exArgs) { - super(MessageFormat.format(I18n.getExceptionMessage(msgID), exArgs)); - - this.msgID = msgID; - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param originalException - */ - public XMLSecurityRuntimeException(Exception originalException) { - super("Missing message ID to locate message string in resource bundle \"" - + Constants.exceptionMessagesResourceBundleBase - + "\". Original Exception was a " - + originalException.getClass().getName() + " and message " - + originalException.getMessage(), originalException); - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param msgID - * @param originalException - */ - public XMLSecurityRuntimeException(String msgID, Exception originalException) { - super(I18n.getExceptionMessage(msgID, originalException), originalException); - - this.msgID = msgID; - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param msgID - * @param exArgs - * @param originalException - */ - public XMLSecurityRuntimeException(String msgID, Object[] exArgs, Exception originalException) { - super(MessageFormat.format(I18n.getExceptionMessage(msgID), exArgs), originalException); - - this.msgID = msgID; - } - - /** - * Method getMsgID - * - * @return the messageId - */ - public String getMsgID() { - if (msgID == null) { - return "Missing message ID"; - } - return msgID; - } - - /** {@inheritDoc} */ - public String toString() { - String s = this.getClass().getName(); - String message = super.getLocalizedMessage(); - - if (message != null) { - message = s + ": " + message; - } else { - message = s; - } - - if (this.getCause() != null) { - message = message + "\nOriginal Exception was " + this.getCause().toString(); - } - - return message; - } - - /** - * Method getOriginalException - * - * @return the original exception - */ - public Exception getOriginalException() { - if (this.getCause() instanceof Exception) { - return (Exception)this.getCause(); - } - return null; - } - -} diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java index 7aa9a30128ab7e08850e9faf60bbc2fe0239c9a4..7445013e9cbcc2d7080c123a63258dee02f7a14d 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java @@ -170,8 +170,8 @@ public class KeyResolver { ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException { JavaUtils.checkRegisterPermission(); - KeyResolverSpi keyResolverSpi = - (KeyResolverSpi) JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); + KeyResolverSpi keyResolverSpi = (KeyResolverSpi) + JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); register(keyResolverSpi, false); } @@ -193,8 +193,8 @@ public class KeyResolver { KeyResolverSpi keyResolverSpi = null; Exception ex = null; try { - keyResolverSpi = (KeyResolverSpi) JavaUtils.newInstanceWithEmptyConstructor( - ClassLoaderUtils.loadClass(className, KeyResolver.class)); + keyResolverSpi = (KeyResolverSpi) + JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); register(keyResolverSpi, true); } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e) { ex = e; @@ -253,8 +253,8 @@ public class KeyResolver { JavaUtils.checkRegisterPermission(); List keyResolverList = new ArrayList<>(classNames.size()); for (String className : classNames) { - KeyResolverSpi keyResolverSpi = (KeyResolverSpi)JavaUtils - .newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); + KeyResolverSpi keyResolverSpi = (KeyResolverSpi) + JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); keyResolverList.add(keyResolverSpi); } resolverList.addAll(keyResolverList); diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java index fb32875c1b15fcc607ee0180a59d8dddd7425965..101fd2d12a554529d993329d75ffbb9ee41488bb 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java @@ -162,6 +162,7 @@ public class KeyInfoReferenceResolver extends KeyResolverSpi { validateReference(referentElement, secureValidation); KeyInfo referent = new KeyInfo(referentElement, baseURI); + referent.setSecureValidation(secureValidation); referent.addStorageResolver(storage); return referent; } @@ -181,7 +182,7 @@ public class KeyInfoReferenceResolver extends KeyResolverSpi { } KeyInfo referent = new KeyInfo(referentElement, ""); - if (referent.containsKeyInfoReference()) { + if (referent.containsKeyInfoReference() || referent.containsRetrievalMethod()) { if (secureValidation) { throw new XMLSecurityException("KeyInfoReferenceResolver.InvalidReferentElement.ReferenceWithSecure"); } else { diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml index 603d49e0ad5a4229ec3414f234ce00e238c03bfe..bbd26a399ca5cda99bf767690201f0bfccc2b8ff 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml @@ -96,8 +96,6 @@ - all his descendants in the output. + * method included the node and all its descendants in the output. * * @param rootNode */ @@ -528,7 +527,7 @@ public class XMLSignatureInput { if (inputOctetStreamProxy == null) { return null; } - try { + try { //NOPMD bytes = JavaUtils.getBytesFromStream(inputOctetStreamProxy); } finally { inputOctetStreamProxy.close(); @@ -539,15 +538,9 @@ public class XMLSignatureInput { /** * @param filter */ - public void addNodeFilter(NodeFilter filter) { + public void addNodeFilter(NodeFilter filter) throws XMLParserException, IOException { if (isOctetStream()) { - try { - convertToNodes(); - } catch (Exception e) { - throw new XMLSecurityRuntimeException( - "signature.XMLSignatureInput.nodesetReference", e - ); - } + convertToNodes(); } nodeFilters.add(filter); } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java index e0f9b4faa1e3535c088b37363b567abb8ba44d42..6337bc2c201dbe09b54d60a74caddfa9baa693f1 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java @@ -60,7 +60,7 @@ public class TransformC14N extends TransformSpi { Canonicalizer20010315 c14n = getCanonicalizer(); - if (os == null) { + if (os == null && (input.isOctetStream() || input.isElement() || input.isNodeSet())) { try (ByteArrayOutputStream writer = new ByteArrayOutputStream()) { c14n.engineCanonicalize(input, writer, secureValidation); writer.flush(); diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java index 5393fa99ac3024f2d67b50b4ce594be3a5802d83..eca648267e1e69ccfaba8c657932e2bfbd3c4e0f 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java @@ -82,7 +82,7 @@ public class TransformC14NExclusive extends TransformSpi { Canonicalizer20010315Excl c14n = getCanonicalizer(); - if (os == null) { + if (os == null && (input.isOctetStream() || input.isElement() || input.isNodeSet())) { try (ByteArrayOutputStream writer = new ByteArrayOutputStream()) { c14n.engineCanonicalize(input, inclusiveNamespaces, writer, secureValidation); writer.flush(); diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java index 539590cc84c742d3405598f128a1bd264bfb4efb..030d7063cc30073e8e67397397c305a48386329e 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java @@ -22,8 +22,10 @@ */ package com.sun.org.apache.xml.internal.security.transforms.implementations; +import java.io.IOException; import java.io.OutputStream; +import com.sun.org.apache.xml.internal.security.parser.XMLParserException; import com.sun.org.apache.xml.internal.security.signature.NodeFilter; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.transforms.TransformSpi; @@ -71,7 +73,11 @@ public class TransformEnvelopedSignature extends TransformSpi { Node signatureElement = searchSignatureElement(transformElement); input.setExcludeNode(signatureElement); - input.addNodeFilter(new EnvelopedNodeFilter(signatureElement)); + try { + input.addNodeFilter(new EnvelopedNodeFilter(signatureElement)); + } catch (XMLParserException | IOException ex) { + throw new TransformationException(ex); + } return input; } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java index cdde27c6834c1840286868733249185e21de0dfb..ca844c0068256d628eeeb56000e90d216a24156d 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java @@ -22,11 +22,12 @@ */ package com.sun.org.apache.xml.internal.security.transforms.implementations; +import java.io.IOException; import java.io.OutputStream; import javax.xml.transform.TransformerException; -import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityRuntimeException; +import com.sun.org.apache.xml.internal.security.parser.XMLParserException; import com.sun.org.apache.xml.internal.security.signature.NodeFilter; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.transforms.TransformSpi; @@ -51,6 +52,9 @@ import org.w3c.dom.Node; */ public class TransformXPath extends TransformSpi { + private static final com.sun.org.slf4j.internal.Logger LOG = + com.sun.org.slf4j.internal.LoggerFactory.getLogger(TransformXPath.class); + /** * {@inheritDoc} */ @@ -102,7 +106,7 @@ public class TransformXPath extends TransformSpi { input.addNodeFilter(new XPathNodeFilter(xpathElement, xpathnode, str, xpathAPIInstance)); input.setNodeSet(true); return input; - } catch (DOMException ex) { + } catch (XMLParserException | IOException | DOMException ex) { throw new TransformationException(ex); } } @@ -144,11 +148,8 @@ public class TransformXPath extends TransformSpi { } return 0; } catch (TransformerException e) { - Object[] eArgs = {currentNode}; - throw new XMLSecurityRuntimeException("signature.Transform.node", eArgs, e); - } catch (Exception e) { - Object[] eArgs = {currentNode, currentNode.getNodeType()}; - throw new XMLSecurityRuntimeException("signature.Transform.nodeAndType",eArgs, e); + LOG.debug("Error evaluating XPath expression", e); + return 0; } } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java index d9d0e761468f4f67f2b113bd8d82b7e3c8e85446..0534fff3844b90c882ae371df5d20b7a3058fd69 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java @@ -43,6 +43,7 @@ import org.w3c.dom.Text; * @see com.sun.org.apache.xml.internal.security.transforms.implementations.TransformBase64Decode */ @Deprecated +@SuppressWarnings("PMD") public final class Base64 { /** Field BASE64DEFAULTLENGTH */ diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java index 116e868834228a1980c8e759c81d520eb767300a..6a2f5d5af260e9cfe3d637a422eb01a50c021707 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java @@ -127,11 +127,11 @@ public class DOMNamespaceContext implements NamespaceContext { return DEFAULT_NS_PREFIX; } } - if (namespaceURI == null) { + if (namespaceURI == null && context != null) { return context.lookupNamespaceURI(null) != null ? null : DEFAULT_NS_PREFIX; - } else if (namespaceURI.equals(XML_NS_URI)) { + } else if (XML_NS_URI.equals(namespaceURI)) { return XML_NS_PREFIX; - } else if (namespaceURI.equals(XMLNS_ATTRIBUTE_NS_URI)) { + } else if (XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)) { return XMLNS_ATTRIBUTE; } return null; diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java index 4574e35f76a5d9a193055765c405edadc5cb33d3..552d1330a3f22aa5d87c27b7108354fe3bd7e67b 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java @@ -190,20 +190,21 @@ public class RFC2253Parser { if (value.startsWith("\"")) { StringBuilder sb = new StringBuilder(); - StringReader sr = new StringReader(value.substring(1, value.length() - 1)); - int i = 0; - char c; + try (StringReader sr = new StringReader(value.substring(1, value.length() - 1))) { + int i = 0; + char c; - while ((i = sr.read()) > -1) { - c = (char) i; + while ((i = sr.read()) > -1) { + c = (char) i; - //the following char is defined at 4.Relationship with RFC1779 and LDAPv2 inrfc2253 - if (c == ',' || c == '=' || c == '+' || c == '<' - || c == '>' || c == '#' || c == ';') { - sb.append('\\'); - } + //the following char is defined at 4.Relationship with RFC1779 and LDAPv2 inrfc2253 + if (c == ',' || c == '=' || c == '+' || c == '<' + || c == '>' || c == '#' || c == ';') { + sb.append('\\'); + } - sb.append(c); + sb.append(c); + } } value = trim(sb.toString()); @@ -263,37 +264,38 @@ public class RFC2253Parser { */ static String changeLess32toRFC(String string) throws IOException { StringBuilder sb = new StringBuilder(); - StringReader sr = new StringReader(string); int i = 0; char c; - while ((i = sr.read()) > -1) { - c = (char) i; - - if (c == '\\') { - sb.append(c); - - char c1 = (char) sr.read(); - char c2 = (char) sr.read(); - - //65 (A) 97 (a) - if ((c1 >= 48 && c1 <= 57 || c1 >= 65 && c1 <= 70 || c1 >= 97 && c1 <= 102) - && (c2 >= 48 && c2 <= 57 - || c2 >= 65 && c2 <= 70 - || c2 >= 97 && c2 <= 102)) { - try { - char ch = (char) Byte.parseByte("" + c1 + c2, 16); + try (StringReader sr = new StringReader(string)) { + while ((i = sr.read()) > -1) { + c = (char) i; - sb.append(ch); - } catch (NumberFormatException ex) { - throw new IOException(ex); + if (c == '\\') { + sb.append(c); + + char c1 = (char) sr.read(); + char c2 = (char) sr.read(); + + //65 (A) 97 (a) + if ((c1 >= 48 && c1 <= 57 || c1 >= 65 && c1 <= 70 || c1 >= 97 && c1 <= 102) + && (c2 >= 48 && c2 <= 57 + || c2 >= 65 && c2 <= 70 + || c2 >= 97 && c2 <= 102)) { + try { + char ch = (char) Byte.parseByte("" + c1 + c2, 16); + + sb.append(ch); + } catch (NumberFormatException ex) { + throw new IOException(ex); + } + } else { + sb.append(c1); + sb.append(c2); } } else { - sb.append(c1); - sb.append(c2); + sb.append(c); } - } else { - sb.append(c); } } @@ -309,15 +311,16 @@ public class RFC2253Parser { */ static String changeLess32toXML(String string) throws IOException { StringBuilder sb = new StringBuilder(); - StringReader sr = new StringReader(string); int i = 0; - while ((i = sr.read()) > -1) { - if (i < 32) { - sb.append('\\'); - sb.append(Integer.toHexString(i)); - } else { - sb.append((char) i); + try (StringReader sr = new StringReader(string)) { + while ((i = sr.read()) > -1) { + if (i < 32) { + sb.append('\\'); + sb.append(Integer.toHexString(i)); + } else { + sb.append((char) i); + } } } @@ -333,28 +336,29 @@ public class RFC2253Parser { */ static String changeWStoXML(String string) throws IOException { StringBuilder sb = new StringBuilder(); - StringReader sr = new StringReader(string); int i = 0; char c; - while ((i = sr.read()) > -1) { - c = (char) i; + try (StringReader sr = new StringReader(string)) { + while ((i = sr.read()) > -1) { + c = (char) i; - if (c == '\\') { - char c1 = (char) sr.read(); + if (c == '\\') { + char c1 = (char) sr.read(); - if (c1 == ' ') { - sb.append('\\'); + if (c1 == ' ') { + sb.append('\\'); - String s = "20"; + String s = "20"; - sb.append(s); + sb.append(s); + } else { + sb.append('\\'); + sb.append(c1); + } } else { - sb.append('\\'); - sb.append(c1); + sb.append(c); } - } else { - sb.append(c); } } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java index 5eaeda3b5f07d0b0dcebe5706c6615cdd6df60fd..446d640194e0969a147b13d2930e20a66eed8e69 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java @@ -583,7 +583,7 @@ public final class XMLUtils { Node parent = null; Node sibling = null; final String namespaceNs = Constants.NamespaceSpecNS; - do { + do { //NOPMD switch (node.getNodeType()) { case Node.ELEMENT_NODE : Element element = (Element) node; diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java index 1b3f2be87cb216790434c2a09075177b195ec181..42271aa0128951bab1955264353e1a3ed0e0c146 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java @@ -122,8 +122,8 @@ public class ResourceResolver { List resourceResolversToAdd = new ArrayList<>(classNames.size()); for (String className : classNames) { - ResourceResolverSpi resourceResolverSpi = (ResourceResolverSpi)JavaUtils - .newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, ResourceResolver.class)); + ResourceResolverSpi resourceResolverSpi = (ResourceResolverSpi) + JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, ResourceResolver.class)); resourceResolversToAdd.add(resourceResolverSpi); } resolverList.addAll(resourceResolversToAdd); @@ -159,15 +159,6 @@ public class ResourceResolver { LOG.debug("check resolvability by class {}", resolver.getClass().getName()); if (resolver.engineCanResolveURI(context)) { - // Check to see whether the Resolver is allowed - if (context.secureValidation - && (resolver instanceof ResolverLocalFilesystem - || resolver instanceof ResolverDirectHTTP)) { - Object[] exArgs = { resolver.getClass().getName() }; - throw new ResourceResolverException( - "signature.Reference.ForbiddenResolver", exArgs, context.uriToResolve, context.baseUri - ); - } return resolver.engineResolveURI(context); } } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverContext.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverContext.java index 47d0dbb87a8e4438723c41b228828c3d47642ccf..ef56d435dde2a1a70060ce047651b756fc9e003d 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverContext.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverContext.java @@ -54,5 +54,4 @@ public class ResourceResolverContext { public Map getProperties() { return properties; } - } diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java index 955a42a01cff16c674d151f700d926197d052a7c..c1f9e199fb2c8764b625143e51c36ce4d0c0e165 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java @@ -219,7 +219,8 @@ public class ResolverDirectHTTP extends ResourceResolverSpi { LOG.debug("I was asked whether I can resolve {}", context.uriToResolve); if (context.uriToResolve.startsWith("http:") || - context.baseUri != null && context.baseUri.startsWith("http:")) { + context.uriToResolve.startsWith("https:") || + context.baseUri != null && (context.baseUri.startsWith("http:") || context.baseUri.startsWith("https:"))) { LOG.debug("I state that I can resolve {}", context.uriToResolve); return true; } @@ -231,7 +232,7 @@ public class ResolverDirectHTTP extends ResourceResolverSpi { private static URI getNewURI(String uri, String baseURI) throws URISyntaxException { URI newUri = null; - if (baseURI == null || "".equals(baseURI)) { + if (baseURI == null || baseURI.length() == 0) { newUri = new URI(uri); } else { newUri = new URI(baseURI).resolve(uri); diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java index 7e73ace1b2acdb496b7f62e7b58b011ff11a56d5..9d7e00bdbd6bd5fe6002676933fe0b9fc66cf687 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java @@ -38,8 +38,6 @@ import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverS */ public class ResolverLocalFilesystem extends ResourceResolverSpi { - private static final int FILE_URI_LENGTH = "file:/".length(); - private static final com.sun.org.slf4j.internal.Logger LOG = com.sun.org.slf4j.internal.LoggerFactory.getLogger(ResolverLocalFilesystem.class); @@ -53,9 +51,7 @@ public class ResolverLocalFilesystem extends ResourceResolverSpi { // calculate new URI URI uriNew = getNewURI(context.uriToResolve, context.baseUri); - String fileName = - ResolverLocalFilesystem.translateUriToFilename(uriNew.toString()); - InputStream inputStream = Files.newInputStream(Paths.get(fileName)); + InputStream inputStream = Files.newInputStream(Paths.get(uriNew)); //NOPMD XMLSignatureInput result = new XMLSignatureInput(inputStream); result.setSecureValidation(context.secureValidation); @@ -67,41 +63,6 @@ public class ResolverLocalFilesystem extends ResourceResolverSpi { } } - /** - * Method translateUriToFilename - * - * @param uri - * @return the string of the filename - */ - private static String translateUriToFilename(String uri) { - - String subStr = uri.substring(FILE_URI_LENGTH); - - if (subStr.indexOf("%20") > -1) { - int offset = 0; - int index = 0; - StringBuilder temp = new StringBuilder(subStr.length()); - do { - index = subStr.indexOf("%20",offset); - if (index == -1) { - temp.append(subStr.substring(offset)); - } else { - temp.append(subStr.substring(offset, index)); - temp.append(' '); - offset = index + 3; - } - } while(index != -1); - subStr = temp.toString(); - } - - if (subStr.charAt(1) == ':') { - // we're running M$ Windows, so this works fine - return subStr; - } - // we're running some UNIX, so we have to prepend a slash - return "/" + subStr; - } - /** * {@inheritDoc} */ @@ -111,7 +72,7 @@ public class ResolverLocalFilesystem extends ResourceResolverSpi { } if (context.uriToResolve.isEmpty() || context.uriToResolve.charAt(0) == '#' || - context.uriToResolve.startsWith("http:")) { + context.uriToResolve.startsWith("http:") || context.uriToResolve.startsWith("https:")) { return false; } @@ -133,7 +94,7 @@ public class ResolverLocalFilesystem extends ResourceResolverSpi { private static URI getNewURI(String uri, String baseURI) throws URISyntaxException { URI newUri = null; - if (baseURI == null || "".equals(baseURI)) { + if (baseURI == null || baseURI.length() == 0) { newUri = new URI(uri); } else { newUri = new URI(baseURI).resolve(uri); diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java index bb279ecc728817bf6587f942f7029f6960965f71..7655866ad7402618fc11013c570fb79a3707e392 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java @@ -239,9 +239,6 @@ public abstract class ApacheCanonicalizer extends TransformService { try { in = apacheTransform.performTransform(in, os, secVal); - if (!in.isNodeSet() && !in.isElement()) { - return null; - } if (in.isOctetStream()) { return new ApacheOctetStreamData(in); } else { diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java index 0b63c5eba1615eaafde0fdf1a6ef79ac9703517a..d278808ea0572832352e188b6cf1417fc0c9583f 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java @@ -447,7 +447,7 @@ public final class DOMReference extends DOMStructure } Data data = dereferencedData; XMLSignatureInput xi = null; - try (OutputStream os = new UnsyncBufferedOutputStream(dos)) { + try (OutputStream os = new UnsyncBufferedOutputStream(dos)) { //NOPMD for (int i = 0, size = transforms.size(); i < size; i++) { DOMTransform transform = (DOMTransform)transforms.get(i); if (i < size - 1) { diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java index a18b76e81f65af2134d1c31a40f756062ab99add..fd6a89229c49dddea5d40c1aa013aa7e47a4d1b2 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java @@ -116,7 +116,7 @@ public class DOMTransform extends DOMStructure implements Transform { Document ownerDoc = DOMUtils.getOwnerDocument(parent); Element transformElem = null; - if (parent.getLocalName().equals("Transforms")) { + if ("Transforms".equals(parent.getLocalName())) { transformElem = DOMUtils.createElement(ownerDoc, "Transform", XMLSignature.XMLNS, dsPrefix); diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java index 6b728e236cb91ed12d3e3f14ace09d2b2973bc3e..e72642bbff35570d09bb229e60e75dd86e20a886 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. */ package org.jcp.xml.dsig.internal.dom; @@ -101,7 +101,9 @@ public final class DOMURIDereferencer implements URIDereferencer { if (id.startsWith("xpointer(id(")) { int i1 = id.indexOf('\''); int i2 = id.indexOf('\'', i1+1); - id = id.substring(i1+1, i2); + if (i1 >= 0 && i2 >= 0) { + id = id.substring(i1 + 1, i2); + } } // check if element is registered by Id @@ -138,7 +140,7 @@ public final class DOMURIDereferencer implements URIDereferencer { } try { - ResourceResolverContext resContext = new ResourceResolverContext(uriAttr, baseURI, false); + ResourceResolverContext resContext = new ResourceResolverContext(uriAttr, baseURI, secVal); XMLSignatureInput in = ResourceResolver.resolve(resContext); if (in.isOctetStream()) { return new ApacheOctetStreamData(in); diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java index f32cf39fd6212cdcb869339b409b955c6af2ad3a..fffca6b38f5262286d7aaedab42c26be1fe7c32a 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java @@ -43,14 +43,13 @@ import java.util.Set; */ public final class Policy { - // all restrictions are initialized to be unconstrained - private static Set disallowedAlgs = new HashSet<>(); - private static int maxTrans = Integer.MAX_VALUE; - private static int maxRefs = Integer.MAX_VALUE; - private static Set disallowedRefUriSchemes = new HashSet<>(); - private static Map minKeyMap = new HashMap<>(); - private static boolean noDuplicateIds = false; - private static boolean noRMLoops = false; + private static Set disallowedAlgs; + private static int maxTrans; + private static int maxRefs; + private static Set disallowedRefUriSchemes; + private static Map minKeyMap; + private static boolean noDuplicateIds; + private static boolean noRMLoops; static { try { @@ -64,6 +63,16 @@ public final class Policy { private Policy() {} private static void initialize() { + // First initialized to be unconstrained and then parse the + // security property "jdk.xml.dsig.secureValidationPolicy" + disallowedAlgs = new HashSet<>(); + maxTrans = Integer.MAX_VALUE; + maxRefs = Integer.MAX_VALUE; + disallowedRefUriSchemes = new HashSet<>(); + minKeyMap = new HashMap<>(); + noDuplicateIds = false; + noRMLoops = false; + @SuppressWarnings("removal") String prop = AccessController.doPrivileged((PrivilegedAction) () -> diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java index 0edb5dd5aff7019b895101a1c889723561a3f058..bcf28d0afe209c934be92db1093b963c227bdb8c 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. */ package org.jcp.xml.dsig.internal.dom; @@ -94,7 +94,9 @@ public final class Utils { if (id.startsWith("xpointer(id(")) { int i1 = id.indexOf('\''); int i2 = id.indexOf('\'', i1+1); - id = id.substring(i1+1, i2); + if (i1 >= 0 && i2 >= 0) { + id = id.substring(i1 + 1, i2); + } } return id; } @@ -114,7 +116,7 @@ public final class Utils { } private static boolean getBoolean(XMLCryptoContext xc, String name) { - Boolean value = (Boolean)xc.getProperty(name); + Boolean value = (Boolean) xc.getProperty(name); return value != null && value; } } diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java index f26b6d9940b0e45b898d96ea9c2abbaf69797e4a..65bb25f058ff261393bbf191432ec610a482aeca 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java @@ -134,7 +134,7 @@ public final class XMLDSigRI extends Provider { @SuppressWarnings("removal") public XMLDSigRI() { // This is the JDK XMLDSig provider, synced from - // Apache Santuario XML Security for Java, version 2.2.1 + // Apache Santuario XML Security for Java, version 2.3.0 super("XMLDSig", VER, INFO); final Provider p = this; diff --git a/src/java.xml.crypto/share/legal/santuario.md b/src/java.xml.crypto/share/legal/santuario.md index eba3a79e3e9f909de31670820917548d691e9f57..fa87128126d19e089465db75c016bbde4e236e22 100644 --- a/src/java.xml.crypto/share/legal/santuario.md +++ b/src/java.xml.crypto/share/legal/santuario.md @@ -1,4 +1,4 @@ -## Apache Santuario v2.2.1 +## Apache Santuario v2.3.0 ### Apache Santuario Notice
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
      index bc7194411f0899ead04824c72fd06f0340d16b30..39084c87f0b90ff2debbdda5c50a98f5f4f88ef2 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
      @@ -39,7 +39,7 @@ import jdk.xml.internal.SecuritySupport;
       
       /**
        * @author Morten Jorgensen
      - * @LastModified: May 2021
      + * @LastModified: Sept 2021
        */
       public final class LoadDocument {
       
      @@ -190,6 +190,9 @@ public final class LoadDocument {
               if (cache != null) {
                   newdom = cache.retrieveDocument(base, originalUri, translet);
                   if (newdom == null) {
      +                if (translet.getAccessError() != null) {
      +                    throw new Exception(translet.getAccessError());
      +                }
                       final Exception e = new FileNotFoundException(originalUri);
                       throw new TransletException(e);
                   }
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
      index 58b8f433e8ea4f2dd49ae1798224c61d57eb2639..1612fd6192383e965a6fc983096a9196d5833dc2 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
      @@ -54,7 +54,7 @@ import org.w3c.dom.Document;
        * @author Morten Jorgensen
        * @author G. Todd Miller
        * @author John Howard, JohnH@schemasoft.com
      - * @LastModified: May 2021
      + * @LastModified: Sept 2021
        */
       public abstract class AbstractTranslet implements Translet {
       
      @@ -116,6 +116,9 @@ public abstract class AbstractTranslet implements Translet {
            */
           private String _accessExternalStylesheet = JdkConstants.EXTERNAL_ACCESS_DEFAULT;
       
      +    // The error message when access to exteranl resources is rejected
      +    private String _accessErr = null;
      +
           /************************************************************************
            * Debugging
            ************************************************************************/
      @@ -786,6 +789,20 @@ public abstract class AbstractTranslet implements Translet {
               _accessExternalStylesheet = protocols;
           }
       
      +    /**
      +     * Returns the access error.
      +     */
      +    public String getAccessError() {
      +        return _accessErr;
      +    }
      +
      +    /**
      +     * Sets the access error.
      +     */
      +    public void setAccessError(String accessErr) {
      +        this._accessErr = accessErr;
      +    }
      +
           /************************************************************************
            * DOMImplementation caching for basis library
            ************************************************************************/
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
      index 9e266eec28f7a9e97bd2ccf20a31ffb11ed45421..b58eabc54d5adec75ee1d69b22e8c91bd7919d8a 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
      @@ -101,7 +101,7 @@ import org.xml.sax.ext.LexicalHandler;
        * @author Morten Jorgensen
        * @author G. Todd Miller
        * @author Santiago Pericas-Geertsen
      - * @LastModified: June 2021
      + * @LastModified: Sept 2021
        */
       public final class TransformerImpl extends Transformer
           implements DOMCache
      @@ -1351,8 +1351,33 @@ public final class TransformerImpl extends Transformer
                   }
       
                   if (resolvedSource == null)  {
      -                StreamSource streamSource = new StreamSource(
      -                     SystemIDResolver.getAbsoluteURI(href, baseURI));
      +                /**
      +                 * Uses the translet to carry over error msg.
      +                 * Performs the access check without any interface changes
      +                 * (e.g. Translet and DOMCache).
      +                 */
      +                @SuppressWarnings("unchecked") //AbstractTranslet is the sole impl.
      +                AbstractTranslet t = (AbstractTranslet)translet;
      +                String systemId = SystemIDResolver.getAbsoluteURI(href, baseURI);
      +                String errMsg = null;
      +                try {
      +                    String accessError = SecuritySupport.checkAccess(systemId,
      +                            t.getAllowedProtocols(),
      +                            JdkConstants.ACCESS_EXTERNAL_ALL);
      +                    if (accessError != null) {
      +                        ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
      +                                SecuritySupport.sanitizePath(href), accessError);
      +                        errMsg = msg.toString();
      +                    }
      +                } catch (IOException ioe) {
      +                    errMsg = ioe.getMessage();
      +                }
      +                if (errMsg != null) {
      +                    t.setAccessError(errMsg);
      +                    return null;
      +                }
      +
      +                StreamSource streamSource = new StreamSource(systemId);
                       return getDOM(streamSource) ;
                   }
       
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java
      index 1ec084e93a6a01d0423f873e6e17e3cb0ebf2e76..67f6478f1354f7d59f3cccc71c64183a2ec3dbb2 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
        */
       /*
        * Licensed to the Apache Software Foundation (ASF) under one or more
      @@ -54,7 +54,7 @@ import com.sun.org.apache.xerces.internal.xni.XNIException;
        * @author Andy Clark, IBM
        * @author Arnaud  Le Hors, IBM
        * @author Eric Ye, IBM
      - *
      + * @LastModified: Aug 2021
        */
       public class XML11DocumentScannerImpl
           extends XMLDocumentScannerImpl {
      @@ -278,16 +278,6 @@ public class XML11DocumentScannerImpl
                                                  + fStringBuffer.toString() + "\"");
                           }
                       }
      -                // note that none of these characters should ever get through
      -                // XML11EntityScanner.  Not sure why
      -                // this check was originally necessary.  - NG
      -                else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
      -                    fEntityScanner.scanChar(null);
      -                    fStringBuffer.append(' ');
      -                    if (entityDepth == fEntityDepth) {
      -                        fStringBuffer2.append('\n');
      -                    }
      -                }
                       else if (c != -1 && XMLChar.isHighSurrogate(c)) {
                           fStringBuffer3.clear();
                           if (scanSurrogates(fStringBuffer3)) {
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
      index 4be8d68e15331f5fe3932a9c972bab3de623e558..332aeb542060794d20f985fa6e64c06ec4d0b130 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
      @@ -21,6 +21,7 @@
       
       package com.sun.org.apache.xerces.internal.impl;
       
      +import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_1;
       import com.sun.org.apache.xerces.internal.impl.XMLScanner.NameType;
       import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
       import com.sun.org.apache.xerces.internal.util.XML11Char;
      @@ -40,7 +41,7 @@ import java.io.IOException;
        * @author Michael Glavassevich, IBM
        * @author Neil Graham, IBM
        *
      - * @LastModified: Apr 2021
      + * @LastModified: Aug 2021
        */
       
       public class XML11EntityScanner
      @@ -116,7 +117,7 @@ public class XML11EntityScanner
                       load(1, false, false);
                       offset = 0;
                   }
      -            if (c == '\r' && external) {
      +            if (c == '\r' && external && fCurrentEntity.position < fCurrentEntity.count) {
                       int cc = fCurrentEntity.ch[fCurrentEntity.position++];
                       if (cc != '\n' && cc != 0x85) {
                           fCurrentEntity.position--;
      @@ -761,71 +762,12 @@ public class XML11EntityScanner
               }
       
               // normalize newlines
      -        int offset = fCurrentEntity.position;
      -        int c = fCurrentEntity.ch[offset];
      -        int newlines = 0;
      -        boolean counted = false;
      -        boolean external = fCurrentEntity.isExternal();
      -        if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
      -            do {
      -                c = fCurrentEntity.ch[fCurrentEntity.position++];
      -                if ((c == '\r' ) && external) {
      -                    newlines++;
      -                    fCurrentEntity.lineNumber++;
      -                    fCurrentEntity.columnNumber = 1;
      -                    if (fCurrentEntity.position == fCurrentEntity.count) {
      -                        checkEntityLimit(null, fCurrentEntity, offset, newlines);
      -                        offset = 0;
      -                        fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
      -                        fCurrentEntity.position = newlines;
      -                        fCurrentEntity.startPosition = newlines;
      -                        if (load(newlines, false, true)) {
      -                            counted = true;
      -                            break;
      -                        }
      -                    }
      -                    int cc = fCurrentEntity.ch[fCurrentEntity.position];
      -                    if (cc == '\n' || cc == 0x85) {
      -                        fCurrentEntity.position++;
      -                        offset++;
      -                    }
      -                    /*** NEWLINE NORMALIZATION ***/
      -                    else {
      -                        newlines++;
      -                    }
      -                }
      -                else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
      -                    newlines++;
      -                    fCurrentEntity.lineNumber++;
      -                    fCurrentEntity.columnNumber = 1;
      -                    if (fCurrentEntity.position == fCurrentEntity.count) {
      -                        checkEntityLimit(null, fCurrentEntity, offset, newlines);
      -                        offset = 0;
      -                        fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
      -                        fCurrentEntity.position = newlines;
      -                        fCurrentEntity.startPosition = newlines;
      -                        if (load(newlines, false, true)) {
      -                            counted = true;
      -                            break;
      -                        }
      -                    }
      -                }
      -                else {
      -                    fCurrentEntity.position--;
      -                    break;
      -                }
      -            } while (fCurrentEntity.position < fCurrentEntity.count - 1);
      -            for (int i = offset; i < fCurrentEntity.position; i++) {
      -                fCurrentEntity.ch[i] = '\n';
      -            }
      -            int length = fCurrentEntity.position - offset;
      -            if (fCurrentEntity.position == fCurrentEntity.count - 1) {
      -                checkEntityLimit(null, fCurrentEntity, offset, length);
      -                content.setValues(fCurrentEntity.ch, offset, length);
      -                return -1;
      -            }
      +        if (normalizeNewlines(XML_VERSION_1_1, content, false, false, null)) {
      +            return -1;
               }
       
      +        int c;
      +        boolean external = fCurrentEntity.isExternal();
               // inner loop, scanning for content
               if (external) {
                   while (fCurrentEntity.position < fCurrentEntity.count) {
      @@ -913,65 +855,12 @@ public class XML11EntityScanner
               }
       
               // normalize newlines
      -        int offset = fCurrentEntity.position;
      -        int c = fCurrentEntity.ch[offset];
      -        int newlines = 0;
      -        boolean external = fCurrentEntity.isExternal();
      -        if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
      -            do {
      -                c = fCurrentEntity.ch[fCurrentEntity.position++];
      -                if ((c == '\r' ) && external) {
      -                    newlines++;
      -                    fCurrentEntity.lineNumber++;
      -                    fCurrentEntity.columnNumber = 1;
      -                    if (fCurrentEntity.position == fCurrentEntity.count) {
      -                        offset = 0;
      -                        fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
      -                        fCurrentEntity.position = newlines;
      -                        fCurrentEntity.startPosition = newlines;
      -                        if (load(newlines, false, true)) {
      -                            break;
      -                        }
      -                    }
      -                    int cc = fCurrentEntity.ch[fCurrentEntity.position];
      -                    if (cc == '\n' || cc == 0x85) {
      -                        fCurrentEntity.position++;
      -                        offset++;
      -                    }
      -                    /*** NEWLINE NORMALIZATION ***/
      -                    else {
      -                        newlines++;
      -                    }
      -                }
      -                else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
      -                    newlines++;
      -                    fCurrentEntity.lineNumber++;
      -                    fCurrentEntity.columnNumber = 1;
      -                    if (fCurrentEntity.position == fCurrentEntity.count) {
      -                        offset = 0;
      -                        fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
      -                        fCurrentEntity.position = newlines;
      -                        fCurrentEntity.startPosition = newlines;
      -                        if (load(newlines, false, true)) {
      -                            break;
      -                        }
      -                    }
      -                }
      -                else {
      -                    fCurrentEntity.position--;
      -                    break;
      -                }
      -            } while (fCurrentEntity.position < fCurrentEntity.count - 1);
      -            for (int i = offset; i < fCurrentEntity.position; i++) {
      -                fCurrentEntity.ch[i] = '\n';
      -            }
      -            int length = fCurrentEntity.position - offset;
      -            if (fCurrentEntity.position == fCurrentEntity.count - 1) {
      -                content.setValues(fCurrentEntity.ch, offset, length);
      -                return -1;
      -            }
      +        if (normalizeNewlines(XML_VERSION_1_1, content, false, true, null)) {
      +            return -1;
               }
       
      +        int c;
      +        boolean external = fCurrentEntity.isExternal();
               // scan literal value
               if (external) {
                   while (fCurrentEntity.position < fCurrentEntity.count) {
      @@ -1093,66 +982,11 @@ public class XML11EntityScanner
                   }
       
                   // normalize newlines
      -            int offset = fCurrentEntity.position;
      -            int c = fCurrentEntity.ch[offset];
      -            int newlines = 0;
      -            if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
      -                do {
      -                    c = fCurrentEntity.ch[fCurrentEntity.position++];
      -                    if ((c == '\r' ) && external) {
      -                        newlines++;
      -                        fCurrentEntity.lineNumber++;
      -                        fCurrentEntity.columnNumber = 1;
      -                        if (fCurrentEntity.position == fCurrentEntity.count) {
      -                            offset = 0;
      -                            fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
      -                            fCurrentEntity.position = newlines;
      -                            fCurrentEntity.startPosition = newlines;
      -                            if (load(newlines, false, true)) {
      -                                break;
      -                            }
      -                        }
      -                        int cc = fCurrentEntity.ch[fCurrentEntity.position];
      -                        if (cc == '\n' || cc == 0x85) {
      -                            fCurrentEntity.position++;
      -                            offset++;
      -                        }
      -                        /*** NEWLINE NORMALIZATION ***/
      -                        else {
      -                            newlines++;
      -                        }
      -                    }
      -                    else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
      -                        newlines++;
      -                        fCurrentEntity.lineNumber++;
      -                        fCurrentEntity.columnNumber = 1;
      -                        if (fCurrentEntity.position == fCurrentEntity.count) {
      -                            offset = 0;
      -                            fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
      -                            fCurrentEntity.position = newlines;
      -                            fCurrentEntity.startPosition = newlines;
      -                            fCurrentEntity.count = newlines;
      -                            if (load(newlines, false, true)) {
      -                                break;
      -                            }
      -                        }
      -                    }
      -                    else {
      -                        fCurrentEntity.position--;
      -                        break;
      -                    }
      -                } while (fCurrentEntity.position < fCurrentEntity.count - 1);
      -                for (int i = offset; i < fCurrentEntity.position; i++) {
      -                    fCurrentEntity.ch[i] = '\n';
      -                }
      -                int length = fCurrentEntity.position - offset;
      -                if (fCurrentEntity.position == fCurrentEntity.count - 1) {
      -                    checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
      -                    buffer.append(fCurrentEntity.ch, offset, length);
      -                    return true;
      -                }
      +            if (normalizeNewlines(XML_VERSION_1_1, buffer, true, false, NameType.COMMENT)) {
      +                return true;
                   }
       
      +            int c;
                   // iterate over buffer looking for delimiter
                   OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
                       c = fCurrentEntity.ch[fCurrentEntity.position++];
      @@ -1256,22 +1090,6 @@ public class XML11EntityScanner
                   checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
                   return true;
               }
      -        else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) {
      -            // handle newlines
      -            if (fCurrentEntity.position == fCurrentEntity.count) {
      -                invokeListeners(1);
      -                fCurrentEntity.ch[0] = (char)cc;
      -                load(1, false, false);
      -            }
      -            int ccc = fCurrentEntity.ch[++fCurrentEntity.position];
      -            if (ccc == '\n' || ccc == 0x85) {
      -                fCurrentEntity.position++;
      -            }
      -            fCurrentEntity.lineNumber++;
      -            fCurrentEntity.columnNumber = 1;
      -            checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
      -            return true;
      -        }
       
               // character was not skipped
               return false;
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
      index 7dbdf6075135d804bbac4e8fcc1eaefa7f4e7483..8a01f74e790325fadfb883b94a8ac36ac929dd0e 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
      @@ -91,7 +91,7 @@ import org.xml.sax.InputSource;
        * @author K.Venugopal SUN Microsystems
        * @author Neeraj Bajaj SUN Microsystems
        * @author Sunitha Reddy SUN Microsystems
      - * @LastModified: May 2021
      + * @LastModified: Aug 2021
        */
       public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
       
      @@ -1235,7 +1235,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
                   externalEntity = (Entity.ExternalEntity)entity;
                   extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
                   extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
      -            expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
      +            expandedSystemId = expandSystemId(extLitSysId, extBaseSysId, fStrictURI);
                   boolean unparsed = entity.isUnparsed();
                   boolean parameter = entityName.startsWith("%");
                   boolean general = !parameter;
      @@ -1312,15 +1312,13 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
                    */
                   xmlInputSource = staxInputSource.getXMLInputSource() ;
                   if (!fISCreatedByResolver) {
      -                //let the not-LoadExternalDTD or not-SupportDTD process to handle the situation
      -                if (fLoadExternalDTD) {
      -                    String accessError = SecuritySupport.checkAccess(expandedSystemId, fAccessExternalDTD, JdkConstants.ACCESS_EXTERNAL_ALL);
      -                    if (accessError != null) {
      -                        fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
      -                                "AccessExternalEntity",
      -                                new Object[] { SecuritySupport.sanitizePath(expandedSystemId), accessError },
      -                                XMLErrorReporter.SEVERITY_FATAL_ERROR);
      -                    }
      +                String accessError = SecuritySupport.checkAccess(expandedSystemId,
      +                        fAccessExternalDTD, JdkConstants.ACCESS_EXTERNAL_ALL);
      +                if (accessError != null) {
      +                    fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
      +                            "AccessExternalEntity",
      +                            new Object[] { SecuritySupport.sanitizePath(expandedSystemId), accessError },
      +                            XMLErrorReporter.SEVERITY_FATAL_ERROR);
                       }
                   }
               }
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
      index c48ed8f70be229e2f2e53d7207fdedf8a327a47f..33ffe9831b86ea016bbc973e0f778b0bd2ea1de5 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
      @@ -21,6 +21,8 @@
       
       package com.sun.org.apache.xerces.internal.impl;
       
      +import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_0;
      +import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_1;
       import com.sun.org.apache.xerces.internal.impl.XMLScanner.NameType;
       import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
       import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
      @@ -55,7 +57,7 @@ import java.util.Locale;
        * @author Arnaud  Le Hors, IBM
        * @author K.Venugopal Sun Microsystems
        *
      - * @LastModified: Apr 2021
      + * @LastModified: Sep 2021
        */
       public class XMLEntityScanner implements XMLLocator  {
       
      @@ -149,6 +151,15 @@ public class XMLEntityScanner implements XMLLocator  {
           // indicates that the operation is for detecting XML version
           boolean detectingVersion = false;
       
      +    // offset of the current cursor position
      +    int offset = 0;
      +
      +    // number of newlines in the current process
      +    int newlines = 0;
      +
      +    // indicating whether the content has been counted towards limit
      +    boolean counted = false;
      +
           //
           // Constructors
           //
      @@ -553,7 +564,7 @@ public class XMLEntityScanner implements XMLLocator  {
               }
       
               // scan character
      -        int offset = fCurrentEntity.position;
      +        offset = fCurrentEntity.position;
               int c = fCurrentEntity.ch[fCurrentEntity.position++];
               if (c == '\n' || (c == '\r' && isExternal)) {
                   fCurrentEntity.lineNumber++;
      @@ -561,10 +572,10 @@ public class XMLEntityScanner implements XMLLocator  {
                   if (fCurrentEntity.position == fCurrentEntity.count) {
                       invokeListeners(1);
                       fCurrentEntity.ch[0] = (char)c;
      -                load(1, false, false);
      +                load(1, true, false);
                       offset = 0;
                   }
      -            if (c == '\r' && isExternal) {
      +            if (c == '\r' && isExternal && fCurrentEntity.position < fCurrentEntity.count) {
                       if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') {
                           fCurrentEntity.position--;
                       }
      @@ -614,7 +625,7 @@ public class XMLEntityScanner implements XMLLocator  {
               }
       
               // scan nmtoken
      -        int offset = fCurrentEntity.position;
      +        offset = fCurrentEntity.position;
               boolean vc = false;
               char c;
               while (true){
      @@ -695,7 +706,7 @@ public class XMLEntityScanner implements XMLLocator  {
               }
       
               // scan name
      -        int offset = fCurrentEntity.position;
      +        offset = fCurrentEntity.position;
               int length;
               if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
                   if (++fCurrentEntity.position == fCurrentEntity.count) {
      @@ -788,7 +799,7 @@ public class XMLEntityScanner implements XMLLocator  {
               }
       
               // scan qualified name
      -        int offset = fCurrentEntity.position;
      +        offset = fCurrentEntity.position;
       
               //making a check if if the specified character is a valid name start character
               //as defined by production [5] in the XML 1.0 specification.
      @@ -1043,81 +1054,11 @@ public class XMLEntityScanner implements XMLLocator  {
               }
       
               // normalize newlines
      -        int offset = fCurrentEntity.position;
      -        int c = fCurrentEntity.ch[offset];
      -        int newlines = 0;
      -        boolean counted = false;
      -        if (c == '\n' || (c == '\r' && isExternal)) {
      -            if (DEBUG_BUFFER) {
      -                System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
      -                print();
      -                System.out.println();
      -            }
      -            do {
      -                c = fCurrentEntity.ch[fCurrentEntity.position++];
      -                if (c == '\r' && isExternal) {
      -                    newlines++;
      -                    fCurrentEntity.lineNumber++;
      -                    fCurrentEntity.columnNumber = 1;
      -                    if (fCurrentEntity.position == fCurrentEntity.count) {
      -                        checkEntityLimit(null, fCurrentEntity, offset, newlines);
      -                        offset = 0;
      -                        fCurrentEntity.position = newlines;
      -                        if (load(newlines, false, true)) {
      -                            counted = true;
      -                            break;
      -                        }
      -                    }
      -                    if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
      -                        fCurrentEntity.position++;
      -                        offset++;
      -                    }
      -                    /*** NEWLINE NORMALIZATION ***/
      -                    else {
      -                        newlines++;
      -                    }
      -                } else if (c == '\n') {
      -                    newlines++;
      -                    fCurrentEntity.lineNumber++;
      -                    fCurrentEntity.columnNumber = 1;
      -                    if (fCurrentEntity.position == fCurrentEntity.count) {
      -                        checkEntityLimit(null, fCurrentEntity, offset, newlines);
      -                        offset = 0;
      -                        fCurrentEntity.position = newlines;
      -                        if (load(newlines, false, true)) {
      -                            counted = true;
      -                            break;
      -                        }
      -                    }
      -                } else {
      -                    fCurrentEntity.position--;
      -                    break;
      -                }
      -            } while (fCurrentEntity.position < fCurrentEntity.count - 1);
      -            for (int i = offset; i < fCurrentEntity.position; i++) {
      -                fCurrentEntity.ch[i] = '\n';
      -            }
      -            int length = fCurrentEntity.position - offset;
      -            if (fCurrentEntity.position == fCurrentEntity.count - 1) {
      -                checkEntityLimit(null, fCurrentEntity, offset, length);
      -                //CHANGED: dont replace the value.. append to the buffer. This gives control to the callee
      -                //on buffering the data..
      -                content.setValues(fCurrentEntity.ch, offset, length);
      -                //content.append(fCurrentEntity.ch, offset, length);
      -                if (DEBUG_BUFFER) {
      -                    System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
      -                    print();
      -                    System.out.println();
      -                }
      -                return -1;
      -            }
      -            if (DEBUG_BUFFER) {
      -                System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
      -                print();
      -                System.out.println();
      -            }
      +        if (normalizeNewlines(XML_VERSION_1_0, content, false, false, null)) {
      +            return -1;
               }
       
      +        int c;
               while (fCurrentEntity.position < fCurrentEntity.count) {
                   c = fCurrentEntity.ch[fCurrentEntity.position++];
                   if (!XMLChar.isContent(c)) {
      @@ -1202,85 +1143,14 @@ public class XMLEntityScanner implements XMLLocator  {
               }
       
               // normalize newlines
      -        int offset = fCurrentEntity.position;
      -        int c = fCurrentEntity.ch[offset];
      -        int newlines = 0;
               if(whiteSpaceInfoNeeded)
                   whiteSpaceLen=0;
      -        if (c == '\n' || (c == '\r' && isExternal)) {
      -            if (DEBUG_BUFFER) {
      -                System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
      -                print();
      -                System.out.println();
      -            }
      -            do {
      -                c = fCurrentEntity.ch[fCurrentEntity.position++];
      -                if (c == '\r' && isExternal) {
      -                    newlines++;
      -                    fCurrentEntity.lineNumber++;
      -                    fCurrentEntity.columnNumber = 1;
      -                    if (fCurrentEntity.position == fCurrentEntity.count) {
      -                        offset = 0;
      -                        fCurrentEntity.position = newlines;
      -                        if (load(newlines, false, true)) {
      -                            break;
      -                        }
      -                    }
      -                    if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
      -                        fCurrentEntity.position++;
      -                        offset++;
      -                    }
      -                    /*** NEWLINE NORMALIZATION ***/
      -                    else {
      -                        newlines++;
      -                    }
      -                    /***/
      -                } else if (c == '\n') {
      -                    newlines++;
      -                    fCurrentEntity.lineNumber++;
      -                    fCurrentEntity.columnNumber = 1;
      -                    if (fCurrentEntity.position == fCurrentEntity.count) {
      -                        offset = 0;
      -                        fCurrentEntity.position = newlines;
      -                        if (load(newlines, false, true)) {
      -                            break;
      -                        }
      -                    }
      -                    /*** NEWLINE NORMALIZATION ***
      -                     * if (fCurrentEntity.ch[fCurrentEntity.position] == '\r'
      -                     * && external) {
      -                     * fCurrentEntity.position++;
      -                     * offset++;
      -                     * }
      -                     * /***/
      -                } else {
      -                    fCurrentEntity.position--;
      -                    break;
      -                }
      -            } while (fCurrentEntity.position < fCurrentEntity.count - 1);
      -            int i=0;
      -            for ( i = offset; i < fCurrentEntity.position; i++) {
      -                fCurrentEntity.ch[i] = '\n';
      -                storeWhiteSpace(i);
      -            }
       
      -            int length = fCurrentEntity.position - offset;
      -            if (fCurrentEntity.position == fCurrentEntity.count - 1) {
      -                content.setValues(fCurrentEntity.ch, offset, length);
      -                if (DEBUG_BUFFER) {
      -                    System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
      -                    print();
      -                    System.out.println();
      -                }
      -                return -1;
      -            }
      -            if (DEBUG_BUFFER) {
      -                System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
      -                print();
      -                System.out.println();
      -            }
      +        if (normalizeNewlines(XML_VERSION_1_0, content, false, true, null)) {
      +            return -1;
               }
       
      +        int c;
               // scan literal value
               for (; fCurrentEntity.position= whiteSpaceLookup.length) {
                   int [] tmp = new int[whiteSpaceLookup.length + 100];
                   System.arraycopy(whiteSpaceLookup, 0, tmp, 0, whiteSpaceLookup.length);
      @@ -1415,75 +1285,11 @@ public class XMLEntityScanner implements XMLLocator  {
                       return false;
                   }
       
      -            // normalize newlines
      -            int offset = fCurrentEntity.position;
      -            int c = fCurrentEntity.ch[offset];
      -            int newlines = 0;
      -            if (c == '\n' || (c == '\r' && isExternal)) {
      -                if (DEBUG_BUFFER) {
      -                    System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
      -                    print();
      -                    System.out.println();
      -                }
      -                do {
      -                    c = fCurrentEntity.ch[fCurrentEntity.position++];
      -                    if (c == '\r' && isExternal) {
      -                        newlines++;
      -                        fCurrentEntity.lineNumber++;
      -                        fCurrentEntity.columnNumber = 1;
      -                        if (fCurrentEntity.position == fCurrentEntity.count) {
      -                            offset = 0;
      -                            fCurrentEntity.position = newlines;
      -                            if (load(newlines, false, true)) {
      -                                break;
      -                            }
      -                        }
      -                        if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
      -                            fCurrentEntity.position++;
      -                            offset++;
      -                        }
      -                        /*** NEWLINE NORMALIZATION ***/
      -                        else {
      -                            newlines++;
      -                        }
      -                    } else if (c == '\n') {
      -                        newlines++;
      -                        fCurrentEntity.lineNumber++;
      -                        fCurrentEntity.columnNumber = 1;
      -                        if (fCurrentEntity.position == fCurrentEntity.count) {
      -                            offset = 0;
      -                            fCurrentEntity.position = newlines;
      -                            fCurrentEntity.count = newlines;
      -                            if (load(newlines, false, true)) {
      -                                break;
      -                            }
      -                        }
      -                    } else {
      -                        fCurrentEntity.position--;
      -                        break;
      -                    }
      -                } while (fCurrentEntity.position < fCurrentEntity.count - 1);
      -                for (int i = offset; i < fCurrentEntity.position; i++) {
      -                    fCurrentEntity.ch[i] = '\n';
      -                }
      -                int length = fCurrentEntity.position - offset;
      -                if (fCurrentEntity.position == fCurrentEntity.count - 1) {
      -                    checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
      -                    buffer.append(fCurrentEntity.ch, offset, length);
      -                    if (DEBUG_BUFFER) {
      -                        System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
      -                        print();
      -                        System.out.println();
      -                    }
      -                    return true;
      -                }
      -                if (DEBUG_BUFFER) {
      -                    System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
      -                    print();
      -                    System.out.println();
      -                }
      +            if (normalizeNewlines(XML_VERSION_1_0, buffer, true, false, NameType.COMMENT)) {
      +                return true;
                   }
       
      +            int c;
                   // iterate over buffer looking for delimiter
                   OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
                       c = fCurrentEntity.ch[fCurrentEntity.position++];
      @@ -1570,7 +1376,7 @@ public class XMLEntityScanner implements XMLLocator  {
               }
       
               // skip character
      -        int offset = fCurrentEntity.position;
      +        offset = fCurrentEntity.position;
               int cc = fCurrentEntity.ch[fCurrentEntity.position];
               if (cc == c) {
                   fCurrentEntity.position++;
      @@ -1587,26 +1393,6 @@ public class XMLEntityScanner implements XMLLocator  {
                   }
                   checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
                   return true;
      -        } else if (c == '\n' && cc == '\r' && isExternal) {
      -            // handle newlines
      -            if (fCurrentEntity.position == fCurrentEntity.count) {
      -                invokeListeners(1);
      -                fCurrentEntity.ch[0] = (char)cc;
      -                load(1, false, false);
      -            }
      -            fCurrentEntity.position++;
      -            if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
      -                fCurrentEntity.position++;
      -            }
      -            fCurrentEntity.lineNumber++;
      -            fCurrentEntity.columnNumber = 1;
      -            if (DEBUG_BUFFER) {
      -                System.out.print(")skipChar, '"+(char)c+"': ");
      -                print();
      -                System.out.println(" -> true");
      -            }
      -            checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
      -            return true;
               }
       
               // character was not skipped
      @@ -1659,7 +1445,7 @@ public class XMLEntityScanner implements XMLLocator  {
       
               // skip spaces
               int c = fCurrentEntity.ch[fCurrentEntity.position];
      -        int offset = fCurrentEntity.position - 1;
      +        offset = fCurrentEntity.position - 1;
               if (XMLChar.isSpace(c)) {
                   do {
                       boolean entityChanged = false;
      @@ -2332,5 +2118,86 @@ public class XMLEntityScanner implements XMLLocator  {
       
           } // skipDeclSpaces():boolean
       
      +    /**
      +     * Normalizes newlines. As specified in XML specification, this method
      +     * converts newlines, '\n', '\r' and '\r\n' to '\n' as 2.11 End-of-Line Handling.
      +     * Further, it may put them in a cache for later process as needed, for example
      +     * as specified in 3.3.3 Attribute-Value Normalization.
      +     *
      +     * @ImplNote this method does not limit to processing external parsed entities
      +     * as 2.11 required. It handles all cases where newlines need to be processed.
      +     *
      +     * @param buffer the current content buffer
      +     * @param append a flag indicating whether to append to the buffer
      +     * @param storeWS a flag indicating whether the whitespaces need to be stored
      +     * for later processing
      +     * @param nt the type of the entity
      +     * @return true if the cursor is at the end of the current entity, false otherwise.
      +     * @throws IOException
      +     */
      +    protected boolean normalizeNewlines(short version, XMLString buffer, boolean append,
      +            boolean storeWS, NameType nt)
      +            throws IOException {
      +        // normalize newlines
      +        offset = fCurrentEntity.position;
      +        int c = fCurrentEntity.ch[offset];
      +        newlines = 0;
      +        // how this information is used is determined by the caller of this method
      +        counted = false;
      +        if ((c == '\n' || c == '\r') ||
      +                (version == XML_VERSION_1_1 && (c == 0x85 || c == 0x2028) && isExternal)) {
      +            do {
      +                c = fCurrentEntity.ch[fCurrentEntity.position++];
      +                if ((c == '\n' || c == '\r') ||
      +                    (version == XML_VERSION_1_1 && (c == 0x85 || c == 0x2028))) {
      +                    newlines++;
      +                    fCurrentEntity.lineNumber++;
      +                    fCurrentEntity.columnNumber = 1;
      +                    if (fCurrentEntity.position == fCurrentEntity.count) {
      +                        checkEntityLimit(nt, fCurrentEntity, offset, newlines);
      +                        offset = 0;
      +                        fCurrentEntity.position = newlines;
      +                        if (load(newlines, false, true)) {
      +                            counted = true;
      +                            break;
      +                        }
      +                    }
      +                    if (c == '\r') {
      +                        int cc = fCurrentEntity.ch[fCurrentEntity.position];
      +                        if (cc == '\n' || (version == XML_VERSION_1_1 && cc == 0x85)) {
      +                            fCurrentEntity.position++;
      +                            offset++;
      +                        }
      +                        /*** NEWLINE NORMALIZATION ***/
      +                        else {
      +                            newlines++;
      +                        }
      +                    }
      +                } else {
      +                    fCurrentEntity.position--;
      +                    break;
      +                }
      +            } while (fCurrentEntity.position < fCurrentEntity.count - 1);
      +
      +            for (int i = offset; i < fCurrentEntity.position; i++) {
      +                fCurrentEntity.ch[i] = '\n';
      +                if (storeWS) {
      +                    storeWhiteSpace(i);
      +                }
      +            }
       
      +            int length = fCurrentEntity.position - offset;
      +            if (fCurrentEntity.position == fCurrentEntity.count - 1) {
      +                checkEntityLimit(nt, fCurrentEntity, offset, length);
      +                if (append) {
      +                    buffer.append(fCurrentEntity.ch, offset, length);
      +                } else {
      +                    buffer.setValues(fCurrentEntity.ch, offset, length);
      +                }
      +
      +                return true;
      +            }
      +        }
      +        return false;
      +    }
       } // class XMLEntityScanner
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java
      index 6a6362199c52ea826c2540db7580d0b568e9296b..2102b8558faddf8d1b1de705062332ddcaa17531 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
        */
       /*
        * Licensed to the Apache Software Foundation (ASF) under one or more
      @@ -67,7 +67,7 @@ import com.sun.xml.internal.stream.Entity;
        * @author Eric Ye, IBM
        * @author K.Venugopal SUN Microsystems
        * @author Sunitha Reddy, SUN Microsystems
      - * @LastModified: Feb 2020
      + * @LastModified: Aug 2021
        */
       public abstract class XMLScanner
               implements XMLComponent {
      @@ -956,12 +956,6 @@ public abstract class XMLScanner
                               System.out.println("** valueF: \""
                                       + stringBuffer.toString() + "\"");
                           }
      -                } else if (c == '\n' || c == '\r') {
      -                    fEntityScanner.scanChar(null);
      -                    stringBuffer.append(' ');
      -                    if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
      -                        fStringBuffer2.append('\n');
      -                    }
                       } else if (c != -1 && XMLChar.isHighSurrogate(c)) {
                           fStringBuffer3.clear();
                           if (scanSurrogates(fStringBuffer3)) {
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLStringBuffer.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLStringBuffer.java
      index 9e9157384239d9dfca1f2d995cf9e317942dcfa2..118aeb7ad967a520ea9721f607ff8c9a82fb75ec 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLStringBuffer.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLStringBuffer.java
      @@ -1,6 +1,5 @@
       /*
      - * reserved comment block
      - * DO NOT REMOVE OR ALTER!
      + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
        */
       /*
        * Licensed to the Apache Software Foundation (ASF) under one or more
      @@ -41,19 +40,11 @@ import com.sun.org.apache.xerces.internal.xni.XMLString;
        *
        * @author Andy Clark, IBM
        * @author Eric Ye, IBM
      - *
      + * @LastModified: Aug 2021
        */
       public class XMLStringBuffer
       extends XMLString {
       
      -    //
      -    // Constants
      -    //
      -
      -
      -    /** Default buffer size (32). */
      -    public static final int DEFAULT_SIZE = 32;
      -
           //
           // Data
           //
      @@ -112,79 +103,4 @@ extends XMLString {
               length = 0;
           }
       
      -    /**
      -     * append
      -     *
      -     * @param c
      -     */
      -    public void append(char c) {
      -        if(this.length + 1 > this.ch.length){
      -            int newLength = this.ch.length * 2 ;
      -            if(newLength < this.ch.length + DEFAULT_SIZE){
      -                newLength = this.ch.length + DEFAULT_SIZE;
      -            }
      -            char [] tmp = new char[newLength];
      -            System.arraycopy(this.ch, 0, tmp, 0, this.length);
      -            this.ch = tmp;
      -        }
      -        this.ch[this.length] = c ;
      -        this.length++;
      -    } // append(char)
      -
      -    /**
      -     * append
      -     *
      -     * @param s
      -     */
      -    public void append(String s) {
      -        int length = s.length();
      -        if (this.length + length > this.ch.length) {
      -            int newLength = this.ch.length * 2 ;
      -            if(newLength < this.ch.length + length + DEFAULT_SIZE){
      -                newLength = this.ch.length + length+ DEFAULT_SIZE;
      -            }
      -
      -            char[] newch = new char[newLength];
      -            System.arraycopy(this.ch, 0, newch, 0, this.length);
      -            this.ch = newch;
      -        }
      -        s.getChars(0, length, this.ch, this.length);
      -        this.length += length;
      -    } // append(String)
      -
      -    /**
      -     * append
      -     *
      -     * @param ch
      -     * @param offset
      -     * @param length
      -     */
      -    public void append(char[] ch, int offset, int length) {
      -        if (this.length + length > this.ch.length) {
      -            int newLength = this.ch.length * 2 ;
      -            if(newLength < this.ch.length + length + DEFAULT_SIZE){
      -                newLength = this.ch.length + length + DEFAULT_SIZE;
      -            }
      -            char[] newch = new char[newLength];
      -            System.arraycopy(this.ch, 0, newch, 0, this.length);
      -            this.ch = newch;
      -        }
      -        //making the code more robust as it would handle null or 0 length data,
      -        //add the data only when it contains some thing
      -        if(ch != null && length > 0){
      -            System.arraycopy(ch, offset, this.ch, this.length, length);
      -            this.length += length;
      -        }
      -    } // append(char[],int,int)
      -
      -    /**
      -     * append
      -     *
      -     * @param s
      -     */
      -    public void append(XMLString s) {
      -        append(s.ch, s.offset, s.length);
      -    } // append(XMLString)
      -
      -
       } // class XMLStringBuffer
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xni/XMLString.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xni/XMLString.java
      index f63e1d20aa680f17fc161f8b238a767cf872d698..9d26c252651a8a04c07c8502c19d4d3eaa6c35da 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xni/XMLString.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xni/XMLString.java
      @@ -1,6 +1,5 @@
       /*
      - * reserved comment block
      - * DO NOT REMOVE OR ALTER!
      + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
        */
       /*
        * Licensed to the Apache Software Foundation (ASF) under one or more
      @@ -42,9 +41,11 @@ package com.sun.org.apache.xerces.internal.xni;
        *
        * @author Eric Ye, IBM
        * @author Andy Clark, IBM
      - *
      + * @LastModified: Aug 2021
        */
       public class XMLString {
      +    /** Default buffer size (32). */
      +    public static final int DEFAULT_SIZE = 32;
       
           //
           // Data
      @@ -189,4 +190,78 @@ public class XMLString {
               return length > 0 ? new String(ch, offset, length) : "";
           } // toString():String
       
      +    /**
      +     * Appends a char to the buffer.
      +     *
      +     * @param c the char
      +     */
      +    public void append(char c) {
      +        if(this.length + 1 > this.ch.length){
      +            int newLength = this.ch.length * 2 ;
      +            if(newLength < this.ch.length + DEFAULT_SIZE){
      +                newLength = this.ch.length + DEFAULT_SIZE;
      +            }
      +            char [] tmp = new char[newLength];
      +            System.arraycopy(this.ch, 0, tmp, 0, this.length);
      +            this.ch = tmp;
      +        }
      +        this.ch[this.length] = c ;
      +        this.length++;
      +    } // append(char)
      +
      +    /**
      +     * Appends a string to the buffer.
      +     *
      +     * @param s the string
      +     */
      +    public void append(String s) {
      +        int length = s.length();
      +        if (this.length + length > this.ch.length) {
      +            int newLength = this.ch.length * 2 ;
      +            if(newLength < this.ch.length + length + DEFAULT_SIZE){
      +                newLength = this.ch.length + length+ DEFAULT_SIZE;
      +            }
      +
      +            char[] newch = new char[newLength];
      +            System.arraycopy(this.ch, 0, newch, 0, this.length);
      +            this.ch = newch;
      +        }
      +        s.getChars(0, length, this.ch, this.length);
      +        this.length += length;
      +    } // append(String)
      +
      +    /**
      +     * Appends a number of characters to the buffer.
      +     *
      +     * @param ch the char array
      +     * @param offset the offset
      +     * @param length the length
      +     */
      +    public void append(char[] ch, int offset, int length) {
      +        if (this.length + length > this.ch.length) {
      +            int newLength = this.ch.length * 2 ;
      +            if(newLength < this.ch.length + length + DEFAULT_SIZE){
      +                newLength = this.ch.length + length + DEFAULT_SIZE;
      +            }
      +            char[] newch = new char[newLength];
      +            System.arraycopy(this.ch, 0, newch, 0, this.length);
      +            this.ch = newch;
      +        }
      +        //making the code more robust as it would handle null or 0 length data,
      +        //add the data only when it contains some thing
      +        if(ch != null && length > 0){
      +            System.arraycopy(ch, offset, this.ch, this.length, length);
      +            this.length += length;
      +        }
      +    } // append(char[],int,int)
      +
      +    /**
      +     * Appends another buffer to this buffer
      +     *
      +     * @param s another buffer
      +     */
      +    public void append(XMLString s) {
      +        append(s.ch, s.offset, s.length);
      +    } // append(XMLString)
      +
       } // class XMLString
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java
      index f2c198c9f09572f331b780f2216473e3a59b6148..fa4e0c901260fc9e75e82c57b6cd6d94f442516c 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java
      @@ -1,6 +1,5 @@
       /*
      - * reserved comment block
      - * DO NOT REMOVE OR ALTER!
      + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
        */
       /*
        * Licensed to the Apache Software Foundation (ASF) under one or more
      @@ -42,6 +41,8 @@ import com.sun.org.apache.xml.internal.serializer.utils.URI.MalformedURIExceptio
        * used in com.sun.org.apache.xml.internal.serializer.
        *
        * @xsl.usage internal
      + *
      + * @LastModified: Jan 2022
        */
       public final class SystemIDResolver
       {
      @@ -282,7 +283,7 @@ public final class SystemIDResolver
         public static String getAbsoluteURI(String urlString, String base)
                 throws TransformerException
         {
      -    if (base == null)
      +    if (base == null || base.length() == 0)
             return getAbsoluteURI(urlString);
       
           String absoluteBase = getAbsoluteURI(base);
      diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java
      index de383ca3e9dabd79ea4666eccc1ca678f7399dda..caf2a4b1ba7b0a0a21e066ace451995503c69da4 100644
      --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java
      +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java
      @@ -1,6 +1,5 @@
       /*
      - * reserved comment block
      - * DO NOT REMOVE OR ALTER!
      + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
        */
       /*
        * Licensed to the Apache Software Foundation (ASF) under one or more
      @@ -35,6 +34,8 @@ import com.sun.org.apache.xml.internal.utils.URI.MalformedURIException;
        * fact that it's declared to throw TransformerException.  Please
        * see code comments for details on how resolution is performed.

      * @xsl.usage internal + * + * @LastModified: Sept 2021 */ public class SystemIDResolver { @@ -275,7 +276,7 @@ public class SystemIDResolver public static String getAbsoluteURI(String urlString, String base) throws TransformerException { - if (base == null) + if (base == null || base.length() == 0) return getAbsoluteURI(urlString); String absoluteBase = getAbsoluteURI(base); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java index bad9cf1a311e6ff0bfc5fd3d5fcc53209e65c431..819faa61b9ca0799ae623b5be87f6761fc053dc3 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java @@ -164,11 +164,8 @@ public class FuncSystemProperty extends FunctionOneArg try { // Use SecuritySupport class to provide privileged access to property file - InputStream is = SecuritySupport.getResourceAsStream(XSLT_PROPERTIES); - - // get a buffered version - try (BufferedInputStream bis = new BufferedInputStream(is)) { - target.load(bis); // and load up the property bag from this + try (InputStream is = SecuritySupport.getResourceAsStream(XSLT_PROPERTIES)) { + target.load(is); // and load up the property bag from this } } catch (Exception ex) diff --git a/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java b/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java index c2a230fe2853b4f556d3f29246a28d1b1dee3bec..a40b4c9142bd16c3e1ed07998b3751eb0ec1b75b 100644 --- a/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java +++ b/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,7 @@ import javax.xml.namespace.QName; * getProperty(), hasNext(), require(), close(), * getNamespaceURI(), isStartElement(), * isEndElement(), isCharacters(), isWhiteSpace(), - * getNamespaceContext(), getEventType(),getLocation(), + * getNamespaceContext(), getEventType(), getLocation(), * hasText(), hasName() * * diff --git a/src/java.xml/share/classes/org/xml/sax/ext/DeclHandler.java b/src/java.xml/share/classes/org/xml/sax/ext/DeclHandler.java index 7d5944656f2f5c46f6db9424891838737da42c39..f0ce5b63ae27be3825db3570f98b43ee919ffa81 100644 --- a/src/java.xml/share/classes/org/xml/sax/ext/DeclHandler.java +++ b/src/java.xml/share/classes/org/xml/sax/ext/DeclHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ public interface DeclHandler * string "ANY", or a parenthesised group, optionally followed * by an occurrence indicator. The model will be normalized so * that all parameter entities are fully resolved and all whitespace - * is removed,and will include the enclosing parentheses. Other + * is removed, and will include the enclosing parentheses. Other * normalization (such as removing redundant parentheses or * simplifying occurrence indicators) is at the discretion of the * parser.

      diff --git a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java index 853be1977546357ad702ceb5c8029fdb3e85d18f..e178e646d7d7088f57a47c23d7cf1aec28c325a0 100644 --- a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java +++ b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java @@ -27,6 +27,7 @@ package com.sun.java.accessibility.internal; import java.awt.*; import java.awt.event.*; +import java.awt.geom.AffineTransform; import java.util.*; import java.lang.*; import java.lang.reflect.*; @@ -478,6 +479,9 @@ public final class AccessBridge { if (parent == null) { return null; } + Point userSpaceXY = AccessibilityGraphicsEnvironment.toUserSpace(x, y); + x = userSpaceXY.x; + y = userSpaceXY.y; if (windowHandleToContextMap != null && windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) { // Path for applications that register their top-level @@ -1593,6 +1597,8 @@ public final class AccessBridge { if (p != null) { r.x = p.x; r.y = p.y; + + r = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(r); return r; } } catch (Exception e) { @@ -2257,6 +2263,7 @@ public final class AccessBridge { if (s != null && s.equals("\n")) { rect.width = 0; } + rect = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(rect); return rect; } } @@ -7338,4 +7345,182 @@ public final class AccessBridge { } } } + + /** + * A helper class to handle coordinate conversion between screen and user spaces. + * See {@link sun.java2d.SunGraphicsEnvironment} + */ + private static abstract class AccessibilityGraphicsEnvironment extends GraphicsEnvironment { + /** + * Returns the graphics configuration which bounds contain the given point in the user's space. + * + * See {@link sun.java2d.SunGraphicsEnvironment#getGraphicsConfigurationAtPoint(GraphicsConfiguration, double, double)} + * + * @param x the x coordinate of the given point in the user's space + * @param y the y coordinate of the given point in the user's space + * @return the graphics configuration + */ + public static GraphicsConfiguration getGraphicsConfigurationAtPoint(double x, double y) { + GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration(); + return getGraphicsConfigurationAtPoint(gc, x, y); + } + + /** + * Returns the graphics configuration which bounds contain the given point in the user's space. + * + * See {@link sun.java2d.SunGraphicsEnvironment#getGraphicsConfigurationAtPoint(GraphicsConfiguration, double, double)} + * + * @param current the default configuration which is checked in the first + * place + * @param x the x coordinate of the given point in the user's space + * @param y the y coordinate of the given point in the user's space + * @return the graphics configuration + */ + public static GraphicsConfiguration getGraphicsConfigurationAtPoint( + GraphicsConfiguration current, double x, double y) { + if (containsUserSpacePoint(current, x, y)) { + return current; + } + GraphicsEnvironment env = getLocalGraphicsEnvironment(); + for (GraphicsDevice device : env.getScreenDevices()) { + GraphicsConfiguration config = device.getDefaultConfiguration(); + if (containsUserSpacePoint(config, x, y)) { + return config; + } + } + return current; + } + + /** + * Returns the graphics configuration which bounds contain the given point in the device space. + * + * @param x the x coordinate of the given point in the device space + * @param y the y coordinate of the given point in the device space + * @return the graphics configuration + */ + public static GraphicsConfiguration getGraphicsConfigurationAtDevicePoint(double x, double y) { + GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration(); + return getGraphicsConfigurationAtDevicePoint(gc, x, y); + } + + /** + * Returns the graphics configuration which bounds contain the given point in the device space. + * + * @param current the default configuration which is checked in the first + * place + * @param x the x coordinate of the given point in the device space + * @param y the y coordinate of the given point in the device space + * @return the graphics configuration + */ + public static GraphicsConfiguration getGraphicsConfigurationAtDevicePoint( + GraphicsConfiguration current, double x, double y) { + if (containsDeviceSpacePoint(current, x, y)) { + return current; + } + GraphicsEnvironment env = getLocalGraphicsEnvironment(); + for (GraphicsDevice device : env.getScreenDevices()) { + GraphicsConfiguration config = device.getDefaultConfiguration(); + if (containsDeviceSpacePoint(config, x, y)) { + return config; + } + } + return current; + } + + private static boolean containsDeviceSpacePoint(GraphicsConfiguration config, double x, double y) { + Rectangle bounds = config.getBounds(); + bounds = toDeviceSpaceAbs(config, bounds.x, bounds.y, bounds.width, bounds.height); + return bounds.contains(x, y); + } + + private static boolean containsUserSpacePoint(GraphicsConfiguration config, double x, double y) { + Rectangle bounds = config.getBounds(); + return bounds.contains(x, y); + } + + /** + * Converts absolute coordinates from the device + * space to the user's space space using appropriate device transformation. + * + * @param x absolute x coordinate in the device's space + * @param y absolute y coordinate in the device's space + * @return the corresponding coordinates in user's space + */ + public static Point toUserSpace(int x, int y) { + GraphicsConfiguration gc = getGraphicsConfigurationAtDevicePoint(x, y); + return toUserSpace(gc, x, y); + } + + /** + * Converts absolute coordinates from the device + * space to the user's space using passed graphics configuration. + * + * @param gc the graphics configuration to be used for transformation + * @param x absolute x coordinate in the device's space + * @param y absolute y coordinate in the device's space + * @return the corresponding coordinates in user's space + */ + public static Point toUserSpace(GraphicsConfiguration gc, int x, int y) { + AffineTransform tx = gc.getDefaultTransform(); + Rectangle screen = gc.getBounds(); + int userX = screen.x + clipRound((x - screen.x) / tx.getScaleX()); + int userY = screen.y + clipRound((y - screen.y) / tx.getScaleY()); + return new Point(userX, userY); + } + + /** + * Converts the rectangle from the user's space to the device space using + * appropriate device transformation. + * + * See {@link sun.java2d.SunGraphicsEnvironment#toDeviceSpaceAbs(Rectangle)} + * + * @param rect the rectangle in the user's space + * @return the rectangle which uses device space (pixels) + */ + public static Rectangle toDeviceSpaceAbs(Rectangle rect) { + GraphicsConfiguration gc = getGraphicsConfigurationAtPoint(rect.x, rect.y); + return toDeviceSpaceAbs(gc, rect.x, rect.y, rect.width, rect.height); + } + + /** + * Converts absolute coordinates (x, y) and the size (w, h) from the user's + * space to the device space using passed graphics configuration. + * + * See {@link sun.java2d.SunGraphicsEnvironment#toDeviceSpaceAbs(GraphicsConfiguration, int, int, int, int)} + * + * @param gc the graphics configuration to be used for transformation + * @param x absolute coordinate in the user's space + * @param y absolute coordinate in the user's space + * @param w the width in the user's space + * @param h the height in the user's space + * @return the rectangle which uses device space (pixels) + */ + public static Rectangle toDeviceSpaceAbs(GraphicsConfiguration gc, + int x, int y, int w, int h) { + AffineTransform tx = gc.getDefaultTransform(); + Rectangle screen = gc.getBounds(); + return new Rectangle( + screen.x + clipRound((x - screen.x) * tx.getScaleX()), + screen.y + clipRound((y - screen.y) * tx.getScaleY()), + clipRound(w * tx.getScaleX()), + clipRound(h * tx.getScaleY()) + ); + } + + /** + * See {@link sun.java2d.pipe.Region#clipRound} + */ + private static int clipRound(final double coordinate) { + final double newv = coordinate - 0.5; + if (newv < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } + if (newv > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + return (int) Math.ceil(newv); + } + } } diff --git a/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c b/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c index a21ce9fa73b7327a00b04811127f525c79fe7337..f08a7c004b31420f0ea380462699570fee0ad162 100644 --- a/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c +++ b/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -399,6 +399,7 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue /* * Setup data to copy to target process */ + memset(&data, 0, sizeof(data)); data._GetModuleHandle = _GetModuleHandle; data._GetProcAddress = _GetProcAddress; diff --git a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java index b0375d200c3f88c00529698a1b8676aa869a2d95..4dea3d09bf46de415cb38df714c6d7714766f044 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java @@ -80,6 +80,8 @@ public interface DocTree { /** * Used for instances of {@link DocTypeTree} * representing an HTML DocType declaration. + * + * @since 10 */ DOC_TYPE, @@ -122,6 +124,8 @@ public interface DocTree { /** * Used for instances of {@link IndexTree} * representing an {@code @index} tag. + * + * @since 9 */ INDEX("index"), @@ -158,6 +162,8 @@ public interface DocTree { /** * Used for instances of {@link ProvidesTree} * representing an {@code @provides} tag. + * + * @since 9 */ PROVIDES("provides"), @@ -207,6 +213,8 @@ public interface DocTree { /** * Used for instances of {@link SnippetTree} * representing an {@code @snippet} tag. + * + * @since 18 */ SNIPPET("snippet"), @@ -219,12 +227,16 @@ public interface DocTree { /** * Used for instances of {@link SystemPropertyTree} * representing an {@code @systemProperty} tag. + * + * @since 12 */ SYSTEM_PROPERTY("systemProperty"), /** * Used for instances of {@link SummaryTree} * representing an {@code @summary} tag. + * + * @since 10 */ SUMMARY("summary"), @@ -255,6 +267,8 @@ public interface DocTree { /** * Used for instances of {@link UsesTree} * representing an {@code @uses} tag. + * + * @since 9 */ USES("uses"), diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java b/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java index a1344aff555f7606866ed65e5573a0a878842007..5a9aee518a1475bbc11ec7aa82f6492de5805080 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java @@ -87,6 +87,11 @@ public abstract class DocTrees extends Trees { /** * Returns the doc comment tree, if any, for the Tree node identified by a given TreePath. * Returns {@code null} if no doc comment was found. + * + * @implNote The default implementation of this method returns the same + * {@code DocCommentTree} instance for repeated invocations + * with the same argument. + * * @param path the path for the tree node * @return the doc comment tree */ @@ -95,6 +100,11 @@ public abstract class DocTrees extends Trees { /** * Returns the doc comment tree of the given element. * Returns {@code null} if no doc comment was found. + * + * @implNote The default implementation of this method returns the same + * {@code DocCommentTree} instance for repeated invocations + * with the same argument. + * * @param e an element whose documentation is required * @return the doc comment tree * @@ -109,6 +119,9 @@ public abstract class DocTrees extends Trees { * Returns {@code null} if no doc comment was found. * Future releases may support additional file types. * + * @implNote The default implementation of this method returns a + * new {@code DocCommentTree} instance for each invocation. + * * @param fileObject the content container * @return the doc comment tree * @since 9 @@ -123,6 +136,9 @@ public abstract class DocTrees extends Trees { * Returns {@code null} if no doc comment was found. * Future releases may support additional file types. * + * @implNote The default implementation of this method returns a + * new {@code DocCommentTree} instance for each invocation. + * * @param e an element whose path is used as a reference * @param relativePath the relative path from the Element * @return the doc comment tree diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java index 3b189799368b7cae9ef29d20b63d54b1a1a69013..5fac3447139a4c1f57806472f6e2fed47daf0a97 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -507,10 +507,16 @@ public class JavacTrees extends DocTrees { } ClassSymbol sym = (ClassSymbol) types.skipTypeVars(tsym.type, false).tsym; - Symbol msym = (memberName == sym.name) - ? findConstructor(sym, paramTypes) - : findMethod(sym, memberName, paramTypes); + ? findConstructor(sym, paramTypes, true) + : findMethod(sym, memberName, paramTypes, true); + + if (msym == null) { + msym = (memberName == sym.name) + ? findConstructor(sym, paramTypes, false) + : findMethod(sym, memberName, paramTypes, false); + } + if (paramTypes != null) { // explicit (possibly empty) arg list given, so cannot be a field return msym; @@ -608,10 +614,10 @@ public class JavacTrees extends DocTrees { return null; } - MethodSymbol findConstructor(ClassSymbol tsym, List paramTypes) { + MethodSymbol findConstructor(ClassSymbol tsym, List paramTypes, boolean strict) { for (Symbol sym : tsym.members().getSymbolsByName(names.init)) { if (sym.kind == MTH) { - if (hasParameterTypes((MethodSymbol) sym, paramTypes)) { + if (hasParameterTypes((MethodSymbol) sym, paramTypes, strict)) { return (MethodSymbol) sym; } } @@ -619,12 +625,13 @@ public class JavacTrees extends DocTrees { return null; } - private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List paramTypes) { - return searchMethod(tsym, methodName, paramTypes, new HashSet<>()); + private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List paramTypes, boolean strict) { + return searchMethod(tsym, methodName, paramTypes, strict, new HashSet<>()); } private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName, - List paramTypes, Set searched) { + List paramTypes, boolean strict, + Set searched) { //### Note that this search is not necessarily what the compiler would do! // do not match constructors @@ -662,7 +669,7 @@ public class JavacTrees extends DocTrees { for (Symbol sym : tsym.members().getSymbolsByName(methodName)) { if (sym != null && sym.kind == MTH) { - if (hasParameterTypes((MethodSymbol) sym, paramTypes)) { + if (hasParameterTypes((MethodSymbol) sym, paramTypes, strict)) { return (MethodSymbol) sym; } } @@ -675,7 +682,7 @@ public class JavacTrees extends DocTrees { // search superclass Type superclass = tsym.getSuperclass(); if (superclass.tsym != null) { - MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, searched); + MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, strict, searched); if (msym != null) { return msym; } @@ -686,7 +693,7 @@ public class JavacTrees extends DocTrees { for (List l = intfs; l.nonEmpty(); l = l.tail) { Type intf = l.head; if (intf.isErroneous()) continue; - MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, searched); + MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, strict, searched); if (msym != null) { return msym; } @@ -695,7 +702,7 @@ public class JavacTrees extends DocTrees { // search enclosing class ClassSymbol encl = tsym.owner.enclClass(); if (encl != null) { - MethodSymbol msym = searchMethod(encl, methodName, paramTypes, searched); + MethodSymbol msym = searchMethod(encl, methodName, paramTypes, strict, searched); if (msym != null) { return msym; } @@ -704,7 +711,7 @@ public class JavacTrees extends DocTrees { return null; } - private boolean hasParameterTypes(MethodSymbol method, List paramTypes) { + private boolean hasParameterTypes(MethodSymbol method, List paramTypes, boolean strict) { if (paramTypes == null) return true; @@ -712,7 +719,7 @@ public class JavacTrees extends DocTrees { return false; List methodParamTypes = method.asType().getParameterTypes(); - if (!Type.isErroneous(paramTypes) && types.isSubtypes(paramTypes, methodParamTypes)) { + if (!strict && !Type.isErroneous(paramTypes) && types.isSubtypes(paramTypes, methodParamTypes)) { return true; } @@ -980,7 +987,7 @@ public class JavacTrees extends DocTrees { } }.scan(env.enclClass); //revert changes done by the visitor: - toClear.stream().forEach(c -> { + toClear.forEach(c -> { chk.clearLocalClassNameIndexes(c); chk.removeCompiled(c); }); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java index fa67ff3a7cabe09943766f250dfcbf73f5c6efaf..ab7582e7cedf34c878906a295b93fe8bcaea9535 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -292,10 +292,16 @@ public class ClassFinder { ClassSymbol c = (ClassSymbol) sym; dependencies.push(c, CompletionCause.CLASS_READER); annotate.blockAnnotations(); - c.members_field = new Scope.ErrorScope(c); // make sure it's always defined + Scope.ErrorScope members = new Scope.ErrorScope(c); + c.members_field = members; // make sure it's always defined completeOwners(c.owner); completeEnclosing(c); - fillIn(c); + //if an enclosing class is completed from the source, + //this class might have been completed already as well, + //avoid attempts to re-complete it: + if (c.members_field == members) { + fillIn(c); + } } finally { annotate.unblockAnnotationsNoFlush(); dependencies.pop(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java index 617d891fb7ce496e264ece81e5c36c835796e664..a6dddba278c468cc634df5970cb441dbba5b7d20 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java @@ -117,7 +117,12 @@ public enum Source { /** * 18, tbd */ - JDK18("18"); + JDK18("18"), + + /** + * 19, tbd + */ + JDK19("19"); private static final Context.Key sourceKey = new Context.Key<>(); @@ -169,6 +174,7 @@ public enum Source { public Target requiredTarget() { return switch(this) { + case JDK19 -> Target.JDK1_19; case JDK18 -> Target.JDK1_18; case JDK17 -> Target.JDK1_17; case JDK16 -> Target.JDK1_16; @@ -313,6 +319,7 @@ public enum Source { case JDK16 -> RELEASE_16; case JDK17 -> RELEASE_17; case JDK18 -> RELEASE_18; + case JDK19 -> RELEASE_19; default -> null; }; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java index a078fb6e22cd4287538e8632176dcd4d175adade..558d2b3107c0d99bcd82ffb3f159ab8574bf4e28 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -667,7 +667,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem * It is assumed that both symbols have the same name. The static * modifier is ignored for this test. * - * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 + * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4 */ public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { return false; @@ -2060,7 +2060,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem * origin) don't get rejected as summarily and are put to test against the * suitable criteria. * - * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 + * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4 */ public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { return overrides(_other, origin, types, checkResult, true); @@ -2077,7 +2077,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem * It is assumed that both symbols have the same name. The static * modifier is ignored for this test. * - * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 + * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4 */ public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult, boolean requireConcreteIfInherited) { @@ -2115,7 +2115,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem } private boolean isOverridableIn(TypeSymbol origin) { - // JLS 8.4.6.1 + // JLS 8.4.8.1 switch ((int)(flags_field & Flags.AccessFlags)) { case Flags.PRIVATE: return false; @@ -2278,6 +2278,11 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem this.staticArgs = staticArgs; } + @Override + public Name name() { + return name; + } + @Override public boolean isDynamic() { return true; @@ -2316,6 +2321,11 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem this.staticArgs = staticArgs; } + @Override + public Name name() { + return name; + } + @Override public boolean isDynamic() { return true; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 0343f826eac014f7ea7850dbccf031e61a1695f1..ae80d86625e9bb636af3670df034b105a719213c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -56,18 +56,27 @@ import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.TreeInfo; +import com.sun.tools.javac.tree.JCTree.JCAnnotatedType; +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCLambda; +import com.sun.tools.javac.tree.JCTree.JCMemberReference; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.JCNewArray; import com.sun.tools.javac.tree.JCTree.JCNewClass; import com.sun.tools.javac.tree.JCTree.JCTypeApply; +import com.sun.tools.javac.tree.JCTree.JCTypeIntersection; +import com.sun.tools.javac.tree.JCTree.JCTypeParameter; +import com.sun.tools.javac.tree.JCTree.JCTypeUnion; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.JCTree.Tag; +import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; -import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; @@ -1132,7 +1141,7 @@ public class TypeAnnotations { } scan(tree.defs); if (tree.sym.isRecord()) { - tree.sym.getRecordComponents().stream().forEach(rc -> scan(rc.accessorMeth)); + tree.sym.getRecordComponents().forEach(rc -> scan(rc.accessorMeth)); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java index fe0f14323051728c98c386b6ba25e24c6099d0c6..99d0cae240eeccaff1c8f531532602b795818e0d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,7 +143,7 @@ public class ArgumentAttr extends JCTree.Visitor { /** * Checks a type in the speculative tree against a given result; the type can be either a plain - * type or an argument type,in which case a more complex check is required. + * type or an argument type, in which case a more complex check is required. */ Type checkSpeculative(JCTree expr, ResultInfo resultInfo) { return checkSpeculative(expr, expr.type, resultInfo); @@ -151,7 +151,7 @@ public class ArgumentAttr extends JCTree.Visitor { /** * Checks a type in the speculative tree against a given result; the type can be either a plain - * type or an argument type,in which case a more complex check is required. + * type or an argument type, in which case a more complex check is required. */ Type checkSpeculative(DiagnosticPosition pos, Type t, ResultInfo resultInfo) { if (t.hasTag(DEFERRED)) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 7bd813cddb73abb43d14c71051acfdaca111cb56..b7fd5a76c09e58373ba1f4227d18586f940b4ce0 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,9 +50,11 @@ import com.sun.tools.javac.comp.Check.CheckContext; import com.sun.tools.javac.comp.DeferredAttr.AttrMode; import com.sun.tools.javac.comp.MatchBindingsComputer.MatchBindings; import com.sun.tools.javac.jvm.*; + import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond; import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg; import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArgs; + import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.resources.CompilerProperties.Warnings; @@ -2909,11 +2911,18 @@ public class Attr extends JCTree.Visitor { // ... // } InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); + Type enclType = clazztype.getEnclosingType(); + if (enclType != null && + enclType.hasTag(CLASS) && + !chk.checkDenotable((ClassType)enclType)) { + log.error(tree.encl, Errors.EnclosingClassTypeNonDenotable(enclType)); + } final boolean isDiamond = TreeInfo.isDiamond(tree); if (isDiamond && ((tree.constructorType != null && inferenceContext.free(tree.constructorType)) || (tree.clazz.type != null && inferenceContext.free(tree.clazz.type)))) { final ResultInfo resultInfoForClassDefinition = this.resultInfo; + Env dupLocalEnv = localEnv.dup(localEnv.tree, localEnv.info.dup(localEnv.info.scope.dupUnshared())); inferenceContext.addFreeTypeListener(List.of(tree.constructorType, tree.clazz.type), instantiatedContext -> { tree.constructorType = instantiatedContext.asInstType(tree.constructorType); @@ -2922,7 +2931,7 @@ public class Attr extends JCTree.Visitor { try { this.resultInfo = resultInfoForClassDefinition; visitAnonymousClassDefinition(tree, clazz, clazz.type, cdef, - localEnv, argtypes, typeargtypes, pkind); + dupLocalEnv, argtypes, typeargtypes, pkind); } finally { this.resultInfo = prevResult; } @@ -5461,7 +5470,7 @@ public class Attr extends JCTree.Visitor { } else { // Check that all extended classes and interfaces // are compatible (i.e. no two define methods with same arguments - // yet different return types). (JLS 8.4.6.3) + // yet different return types). (JLS 8.4.8.3) chk.checkCompatibleSupertypes(tree.pos(), c.type); if (allowDefaultMethods) { chk.checkDefaultMethodClashes(tree.pos(), c.type); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java index dc9684827fd7d3d4886405bbe7b0802503440af3..f95be28973f3661576c988c03557abe4bcac63a7 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java @@ -193,7 +193,7 @@ public class AttrRecover { attr.new ResultInfo(todo.resultInfo.pkind, todo.resultInfo.pt.getReturnType(), todo.resultInfo.checkContext, todo.resultInfo.checkMode), todo.env, args, pats, todo.resultInfo.pt.getTypeArguments()); - rollback.stream().forEach(Runnable::run); + rollback.forEach(Runnable::run); } else { owntype = basicMethodInvocationRecovery(todo.tree, todo.site, todo.errSym, todo.env, todo.resultInfo); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index 55f71a2b8716ffb17879d96d4d11080d6eb78631..96d91f22c21daa7d636cd67fa636c0bcd7981838 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1790,7 +1790,7 @@ public class Check { return; } - // Error if static method overrides instance method (JLS 8.4.6.2). + // Error if static method overrides instance method (JLS 8.4.8.2). if ((m.flags() & STATIC) != 0 && (other.flags() & STATIC) == 0) { log.error(TreeInfo.diagnosticPositionFor(m, tree), @@ -1800,7 +1800,7 @@ public class Check { } // Error if instance method overrides static or final - // method (JLS 8.4.6.1). + // method (JLS 8.4.8.1). if ((other.flags() & FINAL) != 0 || (m.flags() & STATIC) == 0 && (other.flags() & STATIC) != 0) { @@ -1816,7 +1816,7 @@ public class Check { return; } - // Error if overriding method has weaker access (JLS 8.4.6.3). + // Error if overriding method has weaker access (JLS 8.4.8.3). if (protection(m.flags()) > protection(other.flags())) { log.error(TreeInfo.diagnosticPositionFor(m, tree), (other.flags() & AccessFlags) == 0 ? diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index eaff2f1106d8b1181904282ae0ee3244d15ba6a8..1346d141bb76740e6d3b0be4712b061cfedf9ce5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -207,7 +207,6 @@ public class Flow { private final JCDiagnostic.Factory diags; private Env attrEnv; private Lint lint; - private final DeferredCompletionFailureHandler dcfh; private final boolean allowEffectivelyFinalInInnerClasses; public static Flow instance(Context context) { @@ -332,7 +331,6 @@ public class Flow { lint = Lint.instance(context); rs = Resolve.instance(context); diags = JCDiagnostic.Factory.instance(context); - dcfh = DeferredCompletionFailureHandler.instance(context); Source source = Source.instance(context); allowEffectivelyFinalInInnerClasses = Feature.EFFECTIVELY_FINAL_IN_INNER_CLASSES.allowedInSource(source); } @@ -693,7 +691,7 @@ public class Flow { } if (!tree.hasTotalPattern && exhaustiveSwitch && !TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases) && - (constants == null || !isExhaustive(tree.selector.type, constants))) { + (constants == null || !isExhaustive(tree.selector.pos(), tree.selector.type, constants))) { log.error(tree, Errors.NotExhaustiveStatement); } if (!tree.hasTotalPattern) { @@ -728,7 +726,7 @@ public class Flow { } } if (!tree.hasTotalPattern && !TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases) && - !isExhaustive(tree.selector.type, constants)) { + !isExhaustive(tree.selector.pos(), tree.selector.type, constants)) { log.error(tree, Errors.NotExhaustive); } alive = prevAlive; @@ -751,7 +749,7 @@ public class Flow { } } - private void transitiveCovers(Type seltype, Set covered) { + private void transitiveCovers(DiagnosticPosition pos, Type seltype, Set covered) { List todo = List.from(covered); while (todo.nonEmpty()) { Symbol sym = todo.head; @@ -773,7 +771,7 @@ public class Flow { case TYP -> { for (Type sup : types.directSupertypes(sym.type)) { if (sup.tsym.kind == TYP) { - if (isTransitivelyCovered(seltype, sup.tsym, covered) && + if (isTransitivelyCovered(pos, seltype, sup.tsym, covered) && covered.add(sup.tsym)) { todo = todo.prepend(sup.tsym); } @@ -784,9 +782,8 @@ public class Flow { } } - private boolean isTransitivelyCovered(Type seltype, Symbol sealed, Set covered) { - DeferredCompletionFailureHandler.Handler prevHandler = - dcfh.setHandler(dcfh.speculativeCodeHandler); + private boolean isTransitivelyCovered(DiagnosticPosition pos, Type seltype, + Symbol sealed, Set covered) { try { if (covered.stream().anyMatch(c -> sealed.isSubClass(c, types))) return true; @@ -796,30 +793,30 @@ public class Flow { .filter(s -> { return types.isCastable(seltype, s.type/*, types.noWarnings*/); }) - .allMatch(s -> isTransitivelyCovered(seltype, s, covered)); + .allMatch(s -> isTransitivelyCovered(pos, seltype, s, covered)); } return false; } catch (CompletionFailure cf) { - //safe to ignore, the symbol will be un-completed when the speculative handler is removed. - return false; - } finally { - dcfh.setHandler(prevHandler); + chk.completionError(pos, cf); + return true; } } - private boolean isExhaustive(Type seltype, Set covered) { - transitiveCovers(seltype, covered); + private boolean isExhaustive(DiagnosticPosition pos, Type seltype, Set covered) { + transitiveCovers(pos, seltype, covered); return switch (seltype.getTag()) { case CLASS -> { if (seltype.isCompound()) { if (seltype.isIntersection()) { - yield ((Type.IntersectionClassType) seltype).getComponents().stream().anyMatch(t -> isExhaustive(t, covered)); + yield ((Type.IntersectionClassType) seltype).getComponents() + .stream() + .anyMatch(t -> isExhaustive(pos, t, covered)); } yield false; } yield covered.contains(seltype.tsym); } - case TYPEVAR -> isExhaustive(((TypeVar) seltype).getUpperBound(), covered); + case TYPEVAR -> isExhaustive(pos, ((TypeVar) seltype).getUpperBound(), covered); default -> false; }; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java index 94d95069c03060d10294e1b827ce1b0dc222a418..d88b36abcdbf1f559ca7c65396a97fd0e5d65294 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java @@ -28,7 +28,6 @@ package com.sun.tools.javac.comp; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; @@ -393,7 +392,7 @@ public class InferenceContext { Map> minMap = new LinkedHashMap<>(); void scan(List roots) { - roots.stream().forEach(this::visit); + roots.forEach(this::visit); } @Override diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index 55f79c5bc1c5679fec6d59c5b822f15c22290b15..0638da66a8969191b572a18375af6bee01790718 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -165,9 +165,14 @@ public class LambdaToMethod extends TreeTranslator { dumpLambdaToMethodStats = options.isSet("debug.dumpLambdaToMethodStats"); attr = Attr.instance(context); forceSerializable = options.isSet("forceSerializable"); - debugLinesOrVars = options.isSet(Option.G) - || options.isSet(Option.G_CUSTOM, "lines") - || options.isSet(Option.G_CUSTOM, "vars"); + boolean lineDebugInfo = + options.isUnset(Option.G_CUSTOM) || + options.isSet(Option.G_CUSTOM, "lines"); + boolean varDebugInfo = + options.isUnset(Option.G_CUSTOM) + ? options.isSet(Option.G) + : options.isSet(Option.G_CUSTOM, "vars"); + debugLinesOrVars = lineDebugInfo || varDebugInfo; verboseDeduplication = options.isSet("debug.dumpLambdaToMethodDeduplication"); deduplicateLambdas = options.getBoolean("deduplicateLambdas", true); nestmateLambdas = Target.instance(context).runtimeUseNestAccess(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index 1ba0ace43b4099f79b81288ad49e333789e7526a..7c912dcc877cd1f069c625d4211046bcef00748b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -1301,7 +1301,7 @@ public class Resolve { @Override void skip(JCTree tree) { - result &= false; + result = false; } @Override @@ -1313,9 +1313,9 @@ public class Resolve { @Override public void visitReference(JCMemberReference tree) { if (sRet.hasTag(VOID)) { - result &= true; + // do nothing } else if (tRet.hasTag(VOID)) { - result &= false; + result = false; } else if (tRet.isPrimitive() != sRet.isPrimitive()) { boolean retValIsPrimitive = tree.refPolyKind == PolyKind.STANDALONE && @@ -1335,9 +1335,9 @@ public class Resolve { @Override public void visitLambda(JCLambda tree) { if (sRet.hasTag(VOID)) { - result &= true; + // do nothing } else if (tRet.hasTag(VOID)) { - result &= false; + result = false; } else { List lambdaResults = lambdaResults(tree); if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) { @@ -2942,9 +2942,6 @@ public class Resolve { sym.kind != WRONG_MTHS) { sym = super.access(env, pos, location, sym); } else { - final JCDiagnostic details = sym.kind == WRONG_MTH ? - ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd : - null; sym = new DiamondError(sym, currentResolutionContext); sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); env.info.pendingResolutionPhase = currentResolutionContext.step; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java index 56fdc73e02e6da351dc1019a00b2f4c2cce06328..48a575658b3a0ca8fa497b0ee7154446f42ef6c1 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java @@ -665,11 +665,14 @@ public class TransPatterns extends TreeTranslator { @Override public void visitClassDef(JCClassDecl tree) { ClassSymbol prevCurrentClass = currentClass; + MethodSymbol prevMethodSym = currentMethodSym; try { currentClass = tree.sym; + currentMethodSym = null; super.visitClassDef(tree); } finally { currentClass = prevCurrentClass; + currentMethodSym = prevMethodSym; } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java index b94c52cc6d610b76bf39a87a19defbaa3645f9ef..c5df4f9ff3c0c95ae3d4d4ccc29c650e0f1d9152 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java @@ -109,7 +109,6 @@ public class TypeEnter implements Completer { private final Annotate annotate; private final TypeAnnotations typeAnnotations; private final Types types; - private final JCDiagnostic.Factory diags; private final DeferredLintHandler deferredLintHandler; private final Lint lint; private final TypeEnvs typeEnvs; @@ -137,7 +136,6 @@ public class TypeEnter implements Completer { annotate = Annotate.instance(context); typeAnnotations = TypeAnnotations.instance(context); types = Types.instance(context); - diags = JCDiagnostic.Factory.instance(context); deferredLintHandler = DeferredLintHandler.instance(context); lint = Lint.instance(context); typeEnvs = TypeEnvs.instance(context); @@ -356,8 +354,10 @@ public class TypeEnter implements Completer { // Import-on-demand java.lang. PackageSymbol javaLang = syms.enterPackage(syms.java_base, names.java_lang); - if (javaLang.members().isEmpty() && !javaLang.exists()) - throw new FatalError(diags.fragment(Fragments.FatalErrNoJavaLang)); + if (javaLang.members().isEmpty() && !javaLang.exists()) { + log.error(Errors.NoJavaLang); + throw new Abort(); + } importAll(make.at(tree.pos()).Import(make.QualIdent(javaLang), false), javaLang, env); JCModuleDecl decl = tree.getModuleDecl(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java index 5831f3c22bd2a52a7458402f421d9961ed5fdcb9..adc4f813c602f1188df4e9da66fc7516daab829a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java @@ -178,13 +178,6 @@ public abstract class PathFileObject implements JavaFileObject { return toBinaryName(root.relativize(path)); } - @Override @DefinedBy(Api.COMPILER) - public URI toUri() { - // Work around bug JDK-8134451: - // path.toUri() returns double-encoded URIs, that cannot be opened by URLConnection - return createJarUri(userJarPath, path.toString()); - } - @Override public String toString() { return "JarFileObject[" + userJarPath + ":" + path + "]"; @@ -197,17 +190,6 @@ public abstract class PathFileObject implements JavaFileObject { userJarPath ); } - - private static URI createJarUri(Path jarFile, String entryName) { - URI jarURI = jarFile.toUri().normalize(); - String separator = entryName.startsWith("/") ? "!" : "!/"; - try { - // The jar URI convention appears to be not to re-encode the jarURI - return new URI("jar:" + jarURI + separator + entryName); - } catch (URISyntaxException e) { - throw new CannotCreateUriError(jarURI + separator + entryName, e); - } - } } /** diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java index c9077db01fc694628302f8a288a44441163ee62f..9499827c3206c030a8429fb4357c402f9effbe21 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java @@ -119,7 +119,8 @@ public class ClassFile { V59(59, 0), // JDK 15 V60(60, 0), // JDK 16 V61(61, 0), // JDK 17 - V62(62, 0); // JDK 18 + V62(62, 0), // JDK 18 + V63(63, 0); // JDK 19 Version(int major, int minor) { this.major = major; this.minor = minor; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java index 170cac2a111c89532f31bb83d53b1e1e1ec1b91d..c15287ad45e0e5e86ce3f317a516d16073452edf 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -669,7 +669,7 @@ public class Items { } else { switch (targetcode) { case INTcode: - if (Code.truncate(typecode) == INTcode) + if (Code.truncate(typecode) == INTcode && typecode != CHARcode) return this; else return new ImmediateItem( diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java index 77fbec7a569f8e6f6acece414f4c959b311ae9c4..2077efc188826cfeb0b201e610be1046cd1dbe84 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java @@ -134,6 +134,11 @@ public interface PoolConstant { */ PoolConstant dynamicType(); + /** + * The dynamic constant's name. + */ + Name name(); + /** * The dynamic constant's static argument list. */ @@ -150,7 +155,7 @@ public interface PoolConstant { @Override default Object poolKey(Types types) { - return new Pair<>(bsmKey(types), dynamicType().poolKey(types)); + return new PoolKey(name(), bsmKey(types), dynamicType().poolKey(types)); } /** @@ -192,6 +197,8 @@ public interface PoolConstant { && Objects.equals(staticArgKeys, key.staticArgKeys); } } + + record PoolKey(Name name, BsmKey bsmKey, Object dynamicType) {} } /** diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/StringConcat.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/StringConcat.java index 0dddb3e5868e4f776a9b17e165c3ba5483476420..edb41fc2faf53a6de59af2675322f3cce6c3acc0 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/StringConcat.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/StringConcat.java @@ -142,25 +142,6 @@ public abstract class StringConcat { return res.append(tree); } - /** - * If the type is not accessible from current context, try to figure out the - * sharpest accessible supertype. - * - * @param originalType type to sharpen - * @return sharped type - */ - Type sharpestAccessible(Type originalType) { - if (originalType.hasTag(ARRAY)) { - return types.makeArrayType(sharpestAccessible(types.elemtype(originalType))); - } - - Type type = originalType; - while (!rs.isAccessible(gen.getAttrEnv(), type.asElement())) { - type = types.supertype(type); - } - return type; - } - /** * "Legacy" bytecode flavor: emit the StringBuilder.append chains for string * concatenation. @@ -305,6 +286,14 @@ public abstract class StringConcat { return splits.toList(); } + + /** + * Returns true if the argument should be converted to a string eagerly, to preserve + * possible side-effects. + */ + protected boolean shouldConvertToStringEagerly(Type argType) { + return !types.unboxedTypeOrType(argType).isPrimitive() && argType.tsym != syms.stringType.tsym; + } } /** @@ -333,14 +322,18 @@ public abstract class StringConcat { for (JCTree arg : t) { Object constVal = arg.type.constValue(); if ("".equals(constVal)) continue; - if (arg.type == syms.botType) { - dynamicArgs.add(types.boxedClass(syms.voidType).type); - } else { - dynamicArgs.add(sharpestAccessible(arg.type)); + Type argType = arg.type; + if (argType == syms.botType) { + argType = types.boxedClass(syms.voidType).type; } if (!first || generateFirstArg) { gen.genExpr(arg, arg.type).load(); } + if (shouldConvertToStringEagerly(argType)) { + gen.callMethod(pos, syms.stringType, names.valueOf, List.of(syms.objectType), true); + argType = syms.stringType; + } + dynamicArgs.add(argType); first = false; } doCall(type, pos, dynamicArgs.toList()); @@ -439,10 +432,15 @@ public abstract class StringConcat { } else { // Ordinary arguments come through the dynamic arguments. recipe.append(TAG_ARG); - dynamicArgs.add(sharpestAccessible(arg.type)); + Type argType = arg.type; if (!first || generateFirstArg) { gen.genExpr(arg, arg.type).load(); } + if (shouldConvertToStringEagerly(argType)) { + gen.callMethod(pos, syms.stringType, names.valueOf, List.of(syms.objectType), true); + argType = syms.stringType; + } + dynamicArgs.add(argType); first = false; } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java index fba0c2584c9abeb0cf158a37aaf1ad78867ee7c7..49a2135b9950733e8f18333847341787002db6ea 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java @@ -88,7 +88,10 @@ public enum Target { JDK1_17("17", 61, 0), /** JDK 18. */ - JDK1_18("18", 62, 0); + JDK1_18("18", 62, 0), + + /** JDK 19. */ + JDK1_19("19", 63, 0); private static final Context.Key targetKey = new Context.Key<>(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java index a1ae6c543a946ea8d376fa01cb88c228bc3222f9..ed909c8b80f72cc68bf59cc5432203e00ad3310b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -757,6 +757,12 @@ public class JavacElements implements Elements { */ private Pair getTreeAndTopLevel(Element e) { Symbol sym = cast(Symbol.class, e); + if (sym.kind == PCK) { + TypeSymbol pkgInfo = ((PackageSymbol) sym).package_info; + if (pkgInfo != null) { + pkgInfo.complete(); + } + } Env enterEnv = getEnterEnv(sym); if (enterEnv == null) return null; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index 4b508c4bdf093dab35f0c38e866bf9f76b0569c3..b14673532bf142918b63fa4a628be46719918cbf 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -2035,7 +2035,7 @@ public class JavacParser implements Parser { args.append(parseExpression()); } } - accept(RPAREN); + accept(RPAREN, tk -> Errors.Expected2(RPAREN, COMMA)); } else { syntaxError(token.pos, Errors.Expected(LPAREN)); } @@ -2123,7 +2123,7 @@ public class JavacParser implements Parser { nextToken(); break; default: - args.append(syntaxError(token.pos, Errors.Expected(GT))); + args.append(syntaxError(token.pos, Errors.Expected2(GT, COMMA))); break; } return args.toList(); @@ -3379,7 +3379,7 @@ public class JavacParser implements Parser { buf.append(annotationValue()); } } - accept(RBRACE); + accept(RBRACE, tk -> Errors.AnnotationMissingElementValue); return toP(F.at(pos).NewArray(null, List.nil(), buf.toList())); default: selectExprMode(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 15329912c29df67af5449a3aead197d07c75f36b..594bb4e95b4f7f4768a92f6517032328310fc07a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -37,7 +37,6 @@ import java.util.*; import java.util.Map.Entry; import java.util.function.Predicate; import java.util.regex.*; -import java.util.stream.Collectors; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; @@ -46,7 +45,6 @@ import javax.lang.model.util.*; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; -import javax.tools.StandardJavaFileManager; import static javax.tools.StandardLocation.*; @@ -1642,7 +1640,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea List recordComponents = node.sym.getRecordComponents(); for (RecordComponent rc : recordComponents) { List originalAnnos = rc.getOriginalAnnos(); - originalAnnos.stream().forEach(a -> visitAnnotation(a)); + originalAnnos.forEach(a -> visitAnnotation(a)); } // we should empty the list of permitted subclasses for next round node.sym.permitted = List.nil(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java index 5ea75340db284bfd9cc5a55547bc4fb20a319528..9838057f6a46e6e3eb98e2d26b3830835bab3243 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java @@ -55,7 +55,7 @@ import com.sun.tools.javac.util.StringUtils; * deletion without notice. */ @SupportedAnnotationTypes("*") -@SupportedSourceVersion(SourceVersion.RELEASE_18) +@SupportedSourceVersion(SourceVersion.RELEASE_19) public class PrintingProcessor extends AbstractProcessor { PrintWriter writer; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 65ba0e6aed79b3203b590c714a6fdd77cf44bbe9..fddd3e935e1d24ca0fe321be4827dc47eb1040cd 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -118,6 +118,9 @@ compiler.err.already.defined.static.single.import=\ compiler.err.already.defined.this.unit=\ {0} is already defined in this compilation unit +compiler.err.annotation.missing.element.value=\ + annotation is missing element value + # 0: type, 1: list of name compiler.err.annotation.missing.default.value=\ annotation @{0} is missing a default value for the element ''{1}'' @@ -1528,13 +1531,13 @@ compiler.err.locn.invalid.arg.for.xpatch=\ compiler.err.file.sb.on.source.or.patch.path.for.module=\ file should be on source path, or on patch path for module +compiler.err.no.java.lang=\ + Unable to find package java.lang in platform classes + ##### # Fatal Errors -compiler.misc.fatal.err.no.java.lang=\ - Fatal Error: Unable to find package java.lang in classpath or bootclasspath - # 0: name compiler.misc.fatal.err.cant.locate.meth=\ Fatal Error: Unable to find method {0} @@ -3912,3 +3915,8 @@ compiler.warn.declared.using.preview=\ compiler.warn.attempt.to.synchronize.on.instance.of.value.based.class=\ attempt to synchronize on an instance of a value-based class + +# 0: type +compiler.err.enclosing.class.type.non.denotable=\ + enclosing class type: {0}\n\ + is non-denotable, try casting to a denotable type diff --git a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java index 8a9f1cbb30163406df360d2436edc1f322f78b05..f10d1b4fa69b05ee5d18a2f207ee2da972e650ba 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ import com.sun.tools.sjavac.pubapi.PubApi; /** * The Package class maintains meta information about a package. - * For example its sources, dependents,its pubapi and its artifacts. + * For example its sources, dependents, its pubapi and its artifacts. * * It might look odd that we track dependents/pubapi/artifacts on * a package level, but it makes sense since recompiling a full package diff --git a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java index c9e2c62865cbb6e8711b2aee7488f88767e7a8d3..4f2ea5d0c7ea9fe983274cbe8cf3cb000b671869 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ import com.sun.tools.sjavac.pubapi.PubApi; * The transform interface is used to transform content inside a package, from one form to another. * Usually the output form is an unpredictable number of output files. (eg class files) * but can also be an unpredictable number of generated source files (eg idl2java) - * or a single predictable output file (eg when copying,cleaning or compiling a properties file). + * or a single predictable output file (eg when copying, cleaning or compiling a properties file). * *

      This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. diff --git a/src/jdk.compiler/share/classes/module-info.java b/src/jdk.compiler/share/classes/module-info.java index 88066d3c36358fb8b5e3050a0b0b1d10a58ccceb..a417a2998dc63b393219009094f611cd1e857e0a 100644 --- a/src/jdk.compiler/share/classes/module-info.java +++ b/src/jdk.compiler/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,10 @@ * {@linkplain javax.tools.ToolProvider#getSystemJavaCompiler system Java compiler} * and its command line equivalent, {@index javac javac tool}. * + *

      The {@code com.sun.source.*} packages provide the {@index "Compiler Tree API"}: + * an API for accessing the abstract trees (ASTs) representing Java source code + * and documentation comments, used by javac, javadoc and related tools. + * *

      javac

      * *

      diff --git a/src/jdk.compiler/share/man/javac.1 b/src/jdk.compiler/share/man/javac.1 index c2a3190193c1473dd21333f4944f8e6963179c2d..7cc5714aa6ec5818f2972f98075d5e57b310898a 100644 --- a/src/jdk.compiler/share/man/javac.1 +++ b/src/jdk.compiler/share/man/javac.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVAC" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JAVAC" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP @@ -681,43 +681,28 @@ Selects a diagnostic mode. .RE .TP .B \f[CB]\-Xdoclint\f[R] -Enables recommended checks for problems in \f[CB]javadoc\f[R] comments +Enables recommended checks for problems in documentation comments. .RS .RE .TP .B \f[CB]\-Xdoclint:\f[R](\f[CB]all\f[R]|\f[CB]none\f[R]|[\f[CB]\-\f[R]]\f[I]group\f[R])[\f[CB]/\f[R]\f[I]access\f[R]] -Enables or disables specific groups of checks, +Enables or disables specific groups of checks in documentation comments. .RS .PP \f[I]group\f[R] can have one of the following values: -.IP \[bu] 2 -\f[CB]accessibility\f[R] -.IP \[bu] 2 -\f[CB]html\f[R] -.IP \[bu] 2 -\f[CB]missing\f[R] -.IP \[bu] 2 -\f[CB]reference\f[R] -.IP \[bu] 2 -\f[CB]syntax\f[R] +\f[CB]accessibility\f[R], \f[CB]html\f[R], \f[CB]missing\f[R], +\f[CB]reference\f[R], \f[CB]syntax\f[R] .PP The variable \f[I]access\f[R] specifies the minimum visibility level of classes and members that the \f[CB]\-Xdoclint\f[R] option checks. It can have one of the following values (in order of most to least -visible): -.IP \[bu] 2 -\f[CB]public\f[R] -.IP \[bu] 2 -\f[CB]protected\f[R] -.IP \[bu] 2 -\f[CB]package\f[R] -.IP \[bu] 2 -\f[CB]private\f[R] +visible): \f[CB]public\f[R], \f[CB]protected\f[R], \f[CB]package\f[R], +\f[CB]private\f[R]. .PP The default \f[I]access\f[R] level is \f[CB]private\f[R]. .PP For more information about these groups of checks, see the -\f[CB]\-Xdoclint\f[R] option of the \f[CB]javadoc\f[R] command. +\f[B]DocLint\f[R] section of the \f[CB]javadoc\f[R] command documentation. The \f[CB]\-Xdoclint\f[R] option is disabled by default in the \f[CB]javac\f[R] command. .PP @@ -747,6 +732,9 @@ sub\-packages of the given package. Each \f[I]package\f[R] can be prefixed with a hyphen (\f[CB]\-\f[R]) to disable checks for a specified package or packages. .RS +.PP +For more information, see the \f[B]DocLint\f[R] section of the +\f[CB]javadoc\f[R] command documentation. .RE .TP .B \f[CB]\-Xlint\f[R] @@ -1047,7 +1035,7 @@ Create a file named \f[CB]options\f[R] that contains the following: \f[R] .fi .PP -Create a file named \f[CB]classes\f[R] that contains the following: +Create a file named \f[CB]sources\f[R] that contains the following: .IP .nf \f[CB] @@ -1060,7 +1048,7 @@ MyClass3.java Then, run the \f[CB]javac\f[R] command as follows: .RS .PP -\f[CB]javac\ \@options\ \@classes\f[R] +\f[CB]javac\ \@options\ \@sources\f[R] .RE .RE .TP @@ -1071,7 +1059,7 @@ are relative to the current working directory (not \f[CB]path1\f[R] or .RS .RS .PP -\f[CB]javac\ \@path1/options\ \@path2/classes\f[R] +\f[CB]javac\ \@path1/options\ \@path2/sources\f[R] .RE .RE .SH ARRANGEMENT OF SOURCE CODE diff --git a/src/jdk.compiler/share/man/serialver.1 b/src/jdk.compiler/share/man/serialver.1 index 7781a3cbb355b0735833771dd578243034bdacd0..844e4fbca76147f1ba917ea7298c7411fcc02706 100644 --- a/src/jdk.compiler/share/man/serialver.1 +++ b/src/jdk.compiler/share/man/serialver.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "SERIALVER" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "SERIALVER" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java index 6939c7be6f81f3c409ff8714aa9a41c9556a7d0a..676c1fe50e3c7aad21bf8d0c0c41584f8444ed60 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java @@ -165,7 +165,7 @@ final class Config { // name of the C function that returns the PKCS#11 functionlist // This option primarily exists for the deprecated // Secmod.Module.getProvider() method. - private String functionList = "C_GetFunctionList"; + private String functionList = null; // whether to use NSS secmod mode. Implicitly set if nssLibraryDirectory, // nssSecmodDirectory, or nssModule is specified. @@ -311,6 +311,12 @@ final class Config { } String getFunctionList() { + if (functionList == null) { + // defaults to "C_GetFunctionList" for NSS secmod + if (nssUseSecmod || nssUseSecmodTrust) { + return "C_GetFunctionList"; + } + } return functionList; } @@ -408,67 +414,73 @@ final class Config { if (token != TT_WORD) { throw excToken("Unexpected token:"); } - String word = st.sval; - if (word.equals("name")) { - name = parseStringEntry(word); - } else if (word.equals("library")) { - library = parseLibrary(word); - } else if (word.equals("description")) { - parseDescription(word); - } else if (word.equals("slot")) { - parseSlotID(word); - } else if (word.equals("slotListIndex")) { - parseSlotListIndex(word); - } else if (word.equals("enabledMechanisms")) { - parseEnabledMechanisms(word); - } else if (word.equals("disabledMechanisms")) { - parseDisabledMechanisms(word); - } else if (word.equals("attributes")) { - parseAttributes(word); - } else if (word.equals("handleStartupErrors")) { - parseHandleStartupErrors(word); - } else if (word.endsWith("insertionCheckInterval")) { - insertionCheckInterval = parseIntegerEntry(word); + switch (st.sval) { + case "name"-> + name = parseStringEntry(st.sval); + case "library"-> + library = parseLibrary(st.sval); + case "description"-> + parseDescription(st.sval); + case "slot"-> + parseSlotID(st.sval); + case "slotListIndex"-> + parseSlotListIndex(st.sval); + case "enabledMechanisms"-> + parseEnabledMechanisms(st.sval); + case "disabledMechanisms"-> + parseDisabledMechanisms(st.sval); + case "attributes"-> + parseAttributes(st.sval); + case "handleStartupErrors"-> + parseHandleStartupErrors(st.sval); + case "insertionCheckInterval"-> { + insertionCheckInterval = parseIntegerEntry(st.sval); if (insertionCheckInterval < 100) { - throw excLine(word + " must be at least 100 ms"); + throw excLine(st.sval + " must be at least 100 ms"); } - } else if (word.equals("cleaner.shortInterval")) { - resourceCleanerShortInterval = parseIntegerEntry(word); + } + case "cleaner.shortInterval"-> { + resourceCleanerShortInterval = parseIntegerEntry(st.sval); if (resourceCleanerShortInterval < 1_000) { - throw excLine(word + " must be at least 1000 ms"); + throw excLine(st.sval + " must be at least 1000 ms"); } - } else if (word.equals("cleaner.longInterval")) { - resourceCleanerLongInterval = parseIntegerEntry(word); + } + case "cleaner.longInterval"-> { + resourceCleanerLongInterval = parseIntegerEntry(st.sval); if (resourceCleanerLongInterval < 1_000) { - throw excLine(word + " must be at least 1000 ms"); + throw excLine(st.sval + " must be at least 1000 ms"); } - } else if (word.equals("destroyTokenAfterLogout")) { - destroyTokenAfterLogout = parseBooleanEntry(word); - } else if (word.equals("showInfo")) { - showInfo = parseBooleanEntry(word); - } else if (word.equals("keyStoreCompatibilityMode")) { - keyStoreCompatibilityMode = parseBooleanEntry(word); - } else if (word.equals("explicitCancel")) { - explicitCancel = parseBooleanEntry(word); - } else if (word.equals("omitInitialize")) { - omitInitialize = parseBooleanEntry(word); - } else if (word.equals("allowSingleThreadedModules")) { - allowSingleThreadedModules = parseBooleanEntry(word); - } else if (word.equals("functionList")) { - functionList = parseStringEntry(word); - } else if (word.equals("nssUseSecmod")) { - nssUseSecmod = parseBooleanEntry(word); - } else if (word.equals("nssLibraryDirectory")) { - nssLibraryDirectory = parseLibrary(word); + } + case "destroyTokenAfterLogout"-> + destroyTokenAfterLogout = parseBooleanEntry(st.sval); + case "showInfo"-> + showInfo = parseBooleanEntry(st.sval); + case "keyStoreCompatibilityMode"-> + keyStoreCompatibilityMode = parseBooleanEntry(st.sval); + case "explicitCancel"-> + explicitCancel = parseBooleanEntry(st.sval); + case "omitInitialize"-> + omitInitialize = parseBooleanEntry(st.sval); + case "allowSingleThreadedModules"-> + allowSingleThreadedModules = parseBooleanEntry(st.sval); + case "functionList"-> + functionList = parseStringEntry(st.sval); + case "nssUseSecmod"-> + nssUseSecmod = parseBooleanEntry(st.sval); + case "nssLibraryDirectory"-> { + nssLibraryDirectory = parseLibrary(st.sval); nssUseSecmod = true; - } else if (word.equals("nssSecmodDirectory")) { - nssSecmodDirectory = expand(parseStringEntry(word)); + } + case "nssSecmodDirectory"-> { + nssSecmodDirectory = expand(parseStringEntry(st.sval)); nssUseSecmod = true; - } else if (word.equals("nssModule")) { - nssModule = parseStringEntry(word); + } + case "nssModule"-> { + nssModule = parseStringEntry(st.sval); nssUseSecmod = true; - } else if (word.equals("nssDbMode")) { - String mode = parseStringEntry(word); + } + case "nssDbMode"-> { + String mode = parseStringEntry(st.sval); if (mode.equals("readWrite")) { nssDbMode = Secmod.DbMode.READ_WRITE; } else if (mode.equals("readOnly")) { @@ -479,22 +491,25 @@ final class Config { throw excToken("nssDbMode must be one of readWrite, readOnly, and noDb:"); } nssUseSecmod = true; - } else if (word.equals("nssNetscapeDbWorkaround")) { - nssNetscapeDbWorkaround = parseBooleanEntry(word); + } + case "nssNetscapeDbWorkaround"-> { + nssNetscapeDbWorkaround = parseBooleanEntry(st.sval); nssUseSecmod = true; - } else if (word.equals("nssArgs")) { - parseNSSArgs(word); - } else if (word.equals("nssUseSecmodTrust")) { - nssUseSecmodTrust = parseBooleanEntry(word); - } else if (word.equals("useEcX963Encoding")) { - useEcX963Encoding = parseBooleanEntry(word); - } else if (word.equals("nssOptimizeSpace")) { - nssOptimizeSpace = parseBooleanEntry(word); - } else { + } + case "nssArgs"-> + parseNSSArgs(st.sval); + case "nssUseSecmodTrust"-> + nssUseSecmodTrust = parseBooleanEntry(st.sval); + case "useEcX963Encoding"-> + useEcX963Encoding = parseBooleanEntry(st.sval); + case "nssOptimizeSpace"-> + nssOptimizeSpace = parseBooleanEntry(st.sval); + default-> throw new ConfigurationException - ("Unknown keyword '" + word + "', line " + st.lineno()); + ("Unknown keyword '" + st.sval + "', line " + + st.lineno()); } - parsedKeywords.add(word); + parsedKeywords.add(st.sval); } reader.close(); reader = null; diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java index 8a01705b76ff0a562563852406b62d78ed42acb3..fbabbf2a36c1e83a4f07294268d45f01191e2b47 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java @@ -401,7 +401,13 @@ final class P11AEADCipher extends CipherSpi { } private void cancelOperation() { - // cancel operation by finishing it; avoid killSession as some + token.ensureValid(); + if (P11Util.trySessionCancel(token, session, + (encrypt ? CKF_ENCRYPT : CKF_DECRYPT))) { + return; + } + + // cancel by finishing operations; avoid killSession as some // hardware vendors may require re-login int bufLen = doFinalLength(0); byte[] buffer = new byte[bufLen]; @@ -453,7 +459,7 @@ final class P11AEADCipher extends CipherSpi { token.ensureValid(); - byte[] aad = (aadBuffer.size() > 0? aadBuffer.toByteArray() : null); + byte[] aad = (aadBuffer.size() > 0 ? aadBuffer.toByteArray() : null); long p11KeyID = p11Key.getKeyID(); try { @@ -507,7 +513,7 @@ final class P11AEADCipher extends CipherSpi { result -= tagLen; } } - return (result > 0? result : 0); + return (result > 0 ? result : 0); } // reset the states to the pre-initialized values diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java index 5934299e10c7bc73f6b10e49f42d34aa0a05fd21..367c9b84832f5b1aeef229a63d73d9741dbc1402 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java @@ -445,8 +445,14 @@ final class P11Cipher extends CipherSpi { private void cancelOperation() { token.ensureValid(); - // cancel operation by finishing it; avoid killSession as some - // hardware vendors may require re-login + + if (P11Util.trySessionCancel(token, session, + (encrypt ? CKF_ENCRYPT : CKF_DECRYPT))) { + return; + } + + // cancel by finishing operations; avoid killSession as + // some hardware vendors may require re-login try { int bufLen = doFinalLength(0); byte[] buffer = new byte[bufLen]; @@ -458,7 +464,7 @@ final class P11Cipher extends CipherSpi { } catch (PKCS11Exception e) { if (e.match(CKR_OPERATION_NOT_INITIALIZED)) { // Cancel Operation may be invoked after an error on a PKCS#11 - // call. If the operation inside the token was already cancelled, + // call. If the operation inside the token is already cancelled, // do not fail here. This is part of a defensive mechanism for // PKCS#11 libraries that do not strictly follow the standard. return; @@ -488,7 +494,7 @@ final class P11Cipher extends CipherSpi { if (session == null) { session = token.getOpSession(); } - CK_MECHANISM mechParams = (blockMode == MODE_CTR? + CK_MECHANISM mechParams = (blockMode == MODE_CTR ? new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) : new CK_MECHANISM(mechanism, iv)); if (encrypt) { diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java index 638bd208aa6132d65a9890f42d26b48d2bee2342..cae28a06d7be7e0cd7ea094c0afe6cb156ad03ae 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java @@ -90,6 +90,9 @@ abstract class P11Key implements Key, Length { // flags indicating whether the key is a token object, sensitive, extractable final boolean tokenObject, sensitive, extractable; + // flag indicating whether the current token is NSS + final transient boolean isNSS; + @SuppressWarnings("serial") // Type of field is not Serializable private final NativeKeyHolder keyIDHolder; @@ -115,7 +118,7 @@ abstract class P11Key implements Key, Length { } P11Key(String type, Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { + int keyLength, CK_ATTRIBUTE[] attrs) { this.type = type; this.token = session.token; this.algorithm = algorithm; @@ -123,22 +126,22 @@ abstract class P11Key implements Key, Length { boolean tokenObject = false; boolean sensitive = false; boolean extractable = true; - int n = (attributes == null) ? 0 : attributes.length; - for (int i = 0; i < n; i++) { - CK_ATTRIBUTE attr = attributes[i]; - if (attr.type == CKA_TOKEN) { - tokenObject = attr.getBoolean(); - } else if (attr.type == CKA_SENSITIVE) { - sensitive = attr.getBoolean(); - } else if (attr.type == CKA_EXTRACTABLE) { - extractable = attr.getBoolean(); + if (attrs != null) { + for (CK_ATTRIBUTE attr : attrs) { + if (attr.type == CKA_TOKEN) { + tokenObject = attr.getBoolean(); + } else if (attr.type == CKA_SENSITIVE) { + sensitive = attr.getBoolean(); + } else if (attr.type == CKA_EXTRACTABLE) { + extractable = attr.getBoolean(); + } } } this.tokenObject = tokenObject; this.sensitive = sensitive; this.extractable = extractable; char[] tokenLabel = this.token.tokenInfo.label; - boolean isNSS = (tokenLabel[0] == 'N' && tokenLabel[1] == 'S' + isNSS = (tokenLabel[0] == 'N' && tokenLabel[1] == 'S' && tokenLabel[2] == 'S'); boolean extractKeyInfo = (!DISABLE_NATIVE_KEYS_EXTRACTION && isNSS && extractable && !tokenObject); @@ -239,7 +242,8 @@ abstract class P11Key implements Key, Length { } else { // XXX short term serialization for unextractable keys throw new NotSerializableException - ("Cannot serialize sensitive and unextractable keys"); + ("Cannot serialize sensitive, unextractable " + (isNSS ? + ", and NSS token keys" : "keys")); } return new KeyRep(type, getAlgorithm(), format, getEncodedInternal()); } @@ -247,7 +251,7 @@ abstract class P11Key implements Key, Length { public String toString() { token.ensureValid(); String s1 = token.provider.getName() + " " + algorithm + " " + type - + " key, " + keyLength + " bits"; + + " key, " + keyLength + " bits "; s1 += (tokenObject ? "token" : "session") + " object"; if (isPublic()) { s1 += ")"; @@ -278,19 +282,31 @@ abstract class P11Key implements Key, Length { return type == SECRET; } - void fetchAttributes(CK_ATTRIBUTE[] attributes) { + CK_ATTRIBUTE[] fetchAttributes(CK_ATTRIBUTE[] attrs) { + Objects.requireNonNull(attrs, "attrs must be non-null"); Session tempSession = null; long keyID = this.getKeyID(); try { tempSession = token.getOpSession(); token.p11.C_GetAttributeValue(tempSession.id(), keyID, - attributes); + attrs); } catch (PKCS11Exception e) { throw new ProviderException(e); } finally { this.releaseKeyID(); token.releaseSession(tempSession); } + return attrs; + } + + // convenience method which returns the attribute values as BigInteger[] + BigInteger[] fetchAttributesAsInts(CK_ATTRIBUTE[] attrs) { + attrs = fetchAttributes(attrs); + BigInteger[] res = new BigInteger[attrs.length]; + for (int i = 0; i < attrs.length; i++) { + res[i] = attrs[i].getBigInteger(); + } + return res; } private static final CK_ATTRIBUTE[] A0 = new CK_ATTRIBUTE[0]; @@ -329,44 +345,43 @@ abstract class P11Key implements Key, Length { } static SecretKey secretKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_TOKEN), - new CK_ATTRIBUTE(CKA_SENSITIVE), - new CK_ATTRIBUTE(CKA_EXTRACTABLE), + int keyLength, CK_ATTRIBUTE[] attrs) { + attrs = getAttributes(session, keyID, attrs, new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_TOKEN), + new CK_ATTRIBUTE(CKA_SENSITIVE), + new CK_ATTRIBUTE(CKA_EXTRACTABLE), }); - return new P11SecretKey(session, keyID, algorithm, keyLength, - attributes); + return new P11SecretKey(session, keyID, algorithm, keyLength, attrs); } - static SecretKey masterSecretKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes, int major, int minor) { - attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_TOKEN), - new CK_ATTRIBUTE(CKA_SENSITIVE), - new CK_ATTRIBUTE(CKA_EXTRACTABLE), + static SecretKey masterSecretKey(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs, + int major, int minor) { + attrs = getAttributes(session, keyID, attrs, new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_TOKEN), + new CK_ATTRIBUTE(CKA_SENSITIVE), + new CK_ATTRIBUTE(CKA_EXTRACTABLE), }); - return new P11TlsMasterSecretKey( - session, keyID, algorithm, keyLength, attributes, major, - minor); + return new P11TlsMasterSecretKey(session, keyID, algorithm, keyLength, + attrs, major, minor); } // we assume that all components of public keys are always accessible static PublicKey publicKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { + int keyLength, CK_ATTRIBUTE[] attrs) { switch (algorithm) { case "RSA": return new P11RSAPublicKey(session, keyID, algorithm, - keyLength, attributes); + keyLength, attrs); case "DSA": return new P11DSAPublicKey(session, keyID, algorithm, - keyLength, attributes); + keyLength, attrs); case "DH": return new P11DHPublicKey(session, keyID, algorithm, - keyLength, attributes); + keyLength, attrs); case "EC": return new P11ECPublicKey(session, keyID, algorithm, - keyLength, attributes); + keyLength, attrs); default: throw new ProviderException ("Unknown public key algorithm " + algorithm); @@ -374,73 +389,45 @@ abstract class P11Key implements Key, Length { } static PrivateKey privateKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_TOKEN), - new CK_ATTRIBUTE(CKA_SENSITIVE), - new CK_ATTRIBUTE(CKA_EXTRACTABLE), + int keyLength, CK_ATTRIBUTE[] attrs) { + attrs = getAttributes(session, keyID, attrs, new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_TOKEN), + new CK_ATTRIBUTE(CKA_SENSITIVE), + new CK_ATTRIBUTE(CKA_EXTRACTABLE), }); - if (attributes[1].getBoolean() || (attributes[2].getBoolean() == false)) { - return new P11PrivateKey - (session, keyID, algorithm, keyLength, attributes); - } else { - switch (algorithm) { - case "RSA": - // In order to decide if this is RSA CRT key, we first query - // and see if all extra CRT attributes are available. - CK_ATTRIBUTE[] attrs2 = new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), - new CK_ATTRIBUTE(CKA_PRIME_1), - new CK_ATTRIBUTE(CKA_PRIME_2), - new CK_ATTRIBUTE(CKA_EXPONENT_1), - new CK_ATTRIBUTE(CKA_EXPONENT_2), - new CK_ATTRIBUTE(CKA_COEFFICIENT), - }; - boolean crtKey; - try { - session.token.p11.C_GetAttributeValue - (session.id(), keyID, attrs2); - crtKey = ((attrs2[0].pValue instanceof byte[]) && - (attrs2[1].pValue instanceof byte[]) && - (attrs2[2].pValue instanceof byte[]) && - (attrs2[3].pValue instanceof byte[]) && - (attrs2[4].pValue instanceof byte[]) && - (attrs2[5].pValue instanceof byte[])) ; - } catch (PKCS11Exception e) { - // ignore, assume not available - crtKey = false; - } - if (crtKey) { - return new P11RSAPrivateKey(session, keyID, algorithm, - keyLength, attributes, attrs2); - } else { - return new P11RSAPrivateNonCRTKey(session, keyID, - algorithm, keyLength, attributes); - } - case "DSA": - return new P11DSAPrivateKey(session, keyID, algorithm, - keyLength, attributes); - case "DH": - return new P11DHPrivateKey(session, keyID, algorithm, - keyLength, attributes); - case "EC": - return new P11ECPrivateKey(session, keyID, algorithm, - keyLength, attributes); - default: - throw new ProviderException - ("Unknown private key algorithm " + algorithm); - } + + boolean keySensitive = (attrs[0].getBoolean() || + attrs[1].getBoolean() || !attrs[2].getBoolean()); + + switch (algorithm) { + case "RSA": + return P11RSAPrivateKeyInternal.of(session, keyID, algorithm, + keyLength, attrs, keySensitive); + case "DSA": + return P11DSAPrivateKeyInternal.of(session, keyID, algorithm, + keyLength, attrs, keySensitive); + case "DH": + return P11DHPrivateKeyInternal.of(session, keyID, algorithm, + keyLength, attrs, keySensitive); + case "EC": + return P11ECPrivateKeyInternal.of(session, keyID, algorithm, + keyLength, attrs, keySensitive); + default: + throw new ProviderException + ("Unknown private key algorithm " + algorithm); } } - // class for sensitive and unextractable private keys - private static final class P11PrivateKey extends P11Key - implements PrivateKey { + // base class for all PKCS11 private keys + private static abstract class P11PrivateKey extends P11Key implements + PrivateKey { private static final long serialVersionUID = -2138581185214187615L; + protected byte[] encoded; // guard by synchronized + P11PrivateKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PRIVATE, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(PRIVATE, session, keyID, algorithm, keyLength, attrs); } // XXX temporary encoding for serialization purposes public String getFormat() { @@ -455,45 +442,37 @@ abstract class P11Key implements Key, Length { private static class P11SecretKey extends P11Key implements SecretKey { private static final long serialVersionUID = -7828241727014329084L; - private volatile byte[] encoded; + + private volatile byte[] encoded; // guard by double-checked locking + P11SecretKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(SECRET, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(SECRET, session, keyID, algorithm, keyLength, attrs); } + public String getFormat() { token.ensureValid(); - if (sensitive || (extractable == false)) { + if (sensitive || !extractable || (isNSS && tokenObject)) { return null; } else { return "RAW"; } } + byte[] getEncodedInternal() { token.ensureValid(); if (getFormat() == null) { return null; } + byte[] b = encoded; if (b == null) { synchronized (this) { b = encoded; if (b == null) { - Session tempSession = null; - long keyID = this.getKeyID(); - try { - tempSession = token.getOpSession(); - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { + b = fetchAttributes(new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_VALUE), - }; - token.p11.C_GetAttributeValue - (tempSession.id(), keyID, attributes); - b = attributes[0].getByteArray(); - } catch (PKCS11Exception e) { - throw new ProviderException(e); - } finally { - this.releaseKeyID(); - token.releaseSession(tempSession); - } + })[0].getByteArray(); encoded = b; } } @@ -502,6 +481,19 @@ abstract class P11Key implements Key, Length { } } + // base class for all PKCS11 public keys + private static abstract class P11PublicKey extends P11Key implements + PublicKey { + private static final long serialVersionUID = 1L; + + protected byte[] encoded; // guard by synchronized + + P11PublicKey(Session session, long keyID, String algorithm, + int keyLength, CK_ATTRIBUTE[] attrs) { + super(PUBLIC, session, keyID, algorithm, keyLength, attrs); + } + } + @SuppressWarnings("deprecation") private static class P11TlsMasterSecretKey extends P11SecretKey implements TlsMasterSecret { @@ -509,8 +501,8 @@ abstract class P11Key implements Key, Length { private final int majorVersion, minorVersion; P11TlsMasterSecretKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes, int major, int minor) { - super(session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs, int major, int minor) { + super(session, keyID, algorithm, keyLength, attrs); this.majorVersion = major; this.minorVersion = minor; } @@ -523,17 +515,92 @@ abstract class P11Key implements Key, Length { } } + // impl class for sensitive/unextractable RSA private keys + static class P11RSAPrivateKeyInternal extends P11PrivateKey { + private static final long serialVersionUID = -2138581185214187615L; + + static P11RSAPrivateKeyInternal of(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs, + boolean keySensitive) { + if (keySensitive) { + return new P11RSAPrivateKeyInternal(session, keyID, algorithm, + keyLength, attrs); + } else { + CK_ATTRIBUTE[] rsaAttrs = new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_MODULUS), + new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), + new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), + new CK_ATTRIBUTE(CKA_PRIME_1), + new CK_ATTRIBUTE(CKA_PRIME_2), + new CK_ATTRIBUTE(CKA_EXPONENT_1), + new CK_ATTRIBUTE(CKA_EXPONENT_2), + new CK_ATTRIBUTE(CKA_COEFFICIENT), + }; + boolean isCRT = true; + Session tempSession = null; + try { + tempSession = session.token.getOpSession(); + session.token.p11.C_GetAttributeValue(tempSession.id(), + keyID, rsaAttrs); + for (CK_ATTRIBUTE attr : rsaAttrs) { + isCRT &= (attr.pValue instanceof byte[]); + if (!isCRT) break; + } + } catch (PKCS11Exception e) { + // ignore, assume not available + isCRT = false; + } finally { + session.token.releaseSession(tempSession); + } + BigInteger n = rsaAttrs[0].getBigInteger(); + BigInteger d = rsaAttrs[1].getBigInteger(); + if (isCRT) { + return new P11RSAPrivateKey(session, keyID, algorithm, + keyLength, attrs, n, d, + Arrays.copyOfRange(rsaAttrs, 2, rsaAttrs.length)); + } else { + return new P11RSAPrivateNonCRTKey(session, keyID, + algorithm, keyLength, attrs, n, d); + } + } + } + + protected transient BigInteger n; + + private P11RSAPrivateKeyInternal(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); + } + + private synchronized void fetchValues() { + token.ensureValid(); + if (n != null) return; + + n = fetchAttributesAsInts(new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_MODULUS) + })[0]; + } + + public BigInteger getModulus() { + fetchValues(); + return n; + } + } + // RSA CRT private key - private static final class P11RSAPrivateKey extends P11Key - implements RSAPrivateCrtKey { + private static final class P11RSAPrivateKey extends P11RSAPrivateKeyInternal + implements RSAPrivateCrtKey { private static final long serialVersionUID = 9215872438913515220L; - private BigInteger n, e, d, p, q, pe, qe, coeff; - private byte[] encoded; - P11RSAPrivateKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE[] crtAttrs) { - super(PRIVATE, session, keyID, algorithm, keyLength, attrs); + private transient BigInteger e, d, p, q, pe, qe, coeff; + private P11RSAPrivateKey(Session session, long keyID, String algorithm, + int keyLength, CK_ATTRIBUTE[] attrs, BigInteger n, BigInteger d, + CK_ATTRIBUTE[] crtAttrs) { + super(session, keyID, algorithm, keyLength, attrs); + + this.n = n; + this.d = d; for (CK_ATTRIBUTE a : crtAttrs) { if (a.type == CKA_PUBLIC_EXPONENT) { e = a.getBigInteger(); @@ -550,28 +617,15 @@ abstract class P11Key implements Key, Length { } } } - private synchronized void fetchValues() { - token.ensureValid(); - if (n != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_MODULUS), - new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), - }; - fetchAttributes(attributes); - n = attributes[0].getBigInteger(); - d = attributes[1].getBigInteger(); - } public String getFormat() { token.ensureValid(); return "PKCS#8"; } + synchronized byte[] getEncodedInternal() { token.ensureValid(); if (encoded == null) { - fetchValues(); try { Key newKey = RSAPrivateCrtKeyImpl.newKey (KeyType.RSA, null, n, e, d, p, q, pe, qe, coeff); @@ -582,15 +636,15 @@ abstract class P11Key implements Key, Length { } return encoded; } + + @Override public BigInteger getModulus() { - fetchValues(); return n; } public BigInteger getPublicExponent() { return e; } public BigInteger getPrivateExponent() { - fetchValues(); return d; } public BigInteger getPrimeP() { @@ -611,37 +665,28 @@ abstract class P11Key implements Key, Length { } // RSA non-CRT private key - private static final class P11RSAPrivateNonCRTKey extends P11Key - implements RSAPrivateKey { + private static final class P11RSAPrivateNonCRTKey extends + P11RSAPrivateKeyInternal implements RSAPrivateKey { private static final long serialVersionUID = 1137764983777411481L; - private BigInteger n, d; - private byte[] encoded; + private transient BigInteger d; + P11RSAPrivateNonCRTKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PRIVATE, session, keyID, algorithm, keyLength, attributes); - } - private synchronized void fetchValues() { - token.ensureValid(); - if (n != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_MODULUS), - new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), - }; - fetchAttributes(attributes); - n = attributes[0].getBigInteger(); - d = attributes[1].getBigInteger(); + int keyLength, CK_ATTRIBUTE[] attrs, BigInteger n, + BigInteger d) { + super(session, keyID, algorithm, keyLength, attrs); + this.n = n; + this.d = d; } + public String getFormat() { token.ensureValid(); return "PKCS#8"; } + synchronized byte[] getEncodedInternal() { token.ensureValid(); if (encoded == null) { - fetchValues(); try { // XXX make constructor in SunRsaSign provider public // and call it directly @@ -655,42 +700,43 @@ abstract class P11Key implements Key, Length { } return encoded; } + + @Override public BigInteger getModulus() { - fetchValues(); return n; } public BigInteger getPrivateExponent() { - fetchValues(); return d; } } - private static final class P11RSAPublicKey extends P11Key + private static final class P11RSAPublicKey extends P11PublicKey implements RSAPublicKey { private static final long serialVersionUID = -826726289023854455L; - private BigInteger n, e; - private byte[] encoded; + private transient BigInteger n, e; + P11RSAPublicKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PUBLIC, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); } + private synchronized void fetchValues() { token.ensureValid(); - if (n != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { + if (n != null) return; + + BigInteger[] res = fetchAttributesAsInts(new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_MODULUS), - new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), - }; - fetchAttributes(attributes); - n = attributes[0].getBigInteger(); - e = attributes[1].getBigInteger(); + new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT) + }); + n = res[0]; + e = res[1]; } + public String getFormat() { token.ensureValid(); return "X.509"; } + synchronized byte[] getEncodedInternal() { token.ensureValid(); if (encoded == null) { @@ -704,6 +750,7 @@ abstract class P11Key implements Key, Length { } return encoded; } + public BigInteger getModulus() { fetchValues(); return n; @@ -719,41 +766,37 @@ abstract class P11Key implements Key, Length { } } - private static final class P11DSAPublicKey extends P11Key + private static final class P11DSAPublicKey extends P11PublicKey implements DSAPublicKey { private static final long serialVersionUID = 5989753793316396637L; - private BigInteger y; - @SuppressWarnings("serial") // Type of field is not Serializable - private DSAParams params; - private byte[] encoded; + private transient BigInteger y; + private transient DSAParams params; + P11DSAPublicKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PUBLIC, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); } + private synchronized void fetchValues() { token.ensureValid(); - if (y != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { + if (y != null) return; + + BigInteger[] res = fetchAttributesAsInts(new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_VALUE), new CK_ATTRIBUTE(CKA_PRIME), new CK_ATTRIBUTE(CKA_SUBPRIME), - new CK_ATTRIBUTE(CKA_BASE), - }; - fetchAttributes(attributes); - y = attributes[0].getBigInteger(); - params = new DSAParameterSpec( - attributes[1].getBigInteger(), - attributes[2].getBigInteger(), - attributes[3].getBigInteger() - ); + new CK_ATTRIBUTE(CKA_BASE) + }); + y = res[0]; + params = new DSAParameterSpec(res[1], res[2], res[3]); } + public String getFormat() { token.ensureValid(); return "X.509"; } + synchronized byte[] getEncodedInternal() { token.ensureValid(); if (encoded == null) { @@ -783,41 +826,76 @@ abstract class P11Key implements Key, Length { } } - private static final class P11DSAPrivateKey extends P11Key - implements DSAPrivateKey { + static class P11DSAPrivateKeyInternal extends P11PrivateKey { + private static final long serialVersionUID = 3119629997181999389L; + + protected transient DSAParams params; + + static P11DSAPrivateKeyInternal of(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs, + boolean keySensitive) { + if (keySensitive) { + return new P11DSAPrivateKeyInternal(session, keyID, algorithm, + keyLength, attrs); + } else { + return new P11DSAPrivateKey(session, keyID, algorithm, + keyLength, attrs); + } + } + + private P11DSAPrivateKeyInternal(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); + } + + private synchronized void fetchValues() { + token.ensureValid(); + if (params != null) return; + + BigInteger[] res = fetchAttributesAsInts(new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_PRIME), + new CK_ATTRIBUTE(CKA_SUBPRIME), + new CK_ATTRIBUTE(CKA_BASE), + }); + params = new DSAParameterSpec(res[0], res[1], res[2]); + } + + protected DSAParams getParams() { + fetchValues(); + return params; + } + } + + private static final class P11DSAPrivateKey extends P11DSAPrivateKeyInternal + implements DSAPrivateKey { private static final long serialVersionUID = 3119629997181999389L; - private BigInteger x; - @SuppressWarnings("serial") // Type of field is not Serializable - private DSAParams params; - private byte[] encoded; + private transient BigInteger x; // params inside P11DSAPrivateKeyInternal + P11DSAPrivateKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PRIVATE, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); } + private synchronized void fetchValues() { token.ensureValid(); - if (x != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_VALUE), - new CK_ATTRIBUTE(CKA_PRIME), - new CK_ATTRIBUTE(CKA_SUBPRIME), - new CK_ATTRIBUTE(CKA_BASE), - }; - fetchAttributes(attributes); - x = attributes[0].getBigInteger(); - params = new DSAParameterSpec( - attributes[1].getBigInteger(), - attributes[2].getBigInteger(), - attributes[3].getBigInteger() - ); + if (x != null) return; + + BigInteger[] res = fetchAttributesAsInts(new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_VALUE), + new CK_ATTRIBUTE(CKA_PRIME), + new CK_ATTRIBUTE(CKA_SUBPRIME), + new CK_ATTRIBUTE(CKA_BASE), + }); + x = res[0]; + params = new DSAParameterSpec(res[1], res[2], res[3]); } + public String getFormat() { token.ensureValid(); return "PKCS#8"; } + synchronized byte[] getEncodedInternal() { token.ensureValid(); if (encoded == null) { @@ -828,49 +906,87 @@ abstract class P11Key implements Key, Length { } return encoded; } + public BigInteger getX() { fetchValues(); return x; } + + @Override public DSAParams getParams() { fetchValues(); return params; } } - private static final class P11DHPrivateKey extends P11Key + static class P11DHPrivateKeyInternal extends P11PrivateKey { + private static final long serialVersionUID = 1L; + + protected transient DHParameterSpec params; + + static P11DHPrivateKeyInternal of(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs, + boolean keySensitive) { + if (keySensitive) { + return new P11DHPrivateKeyInternal(session, keyID, algorithm, + keyLength, attrs); + } else { + return new P11DHPrivateKey(session, keyID, algorithm, + keyLength, attrs); + } + } + + private P11DHPrivateKeyInternal(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); + } + + private synchronized void fetchValues() { + token.ensureValid(); + if (params != null) return; + + BigInteger[] res = fetchAttributesAsInts(new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_PRIME), + new CK_ATTRIBUTE(CKA_BASE), + }); + params = new DHParameterSpec(res[0], res[1]); + } + + public DHParameterSpec getParams() { + fetchValues(); + return params; + } + } + + private static final class P11DHPrivateKey extends P11DHPrivateKeyInternal implements DHPrivateKey { private static final long serialVersionUID = -1698576167364928838L; - private BigInteger x; - @SuppressWarnings("serial") // Type of field is not Serializable - private DHParameterSpec params; - private byte[] encoded; + private transient BigInteger x; // params in P11DHPrivateKeyInternal + P11DHPrivateKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PRIVATE, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); } + private synchronized void fetchValues() { token.ensureValid(); - if (x != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_VALUE), - new CK_ATTRIBUTE(CKA_PRIME), - new CK_ATTRIBUTE(CKA_BASE), - }; - fetchAttributes(attributes); - x = attributes[0].getBigInteger(); - params = new DHParameterSpec( - attributes[1].getBigInteger(), - attributes[2].getBigInteger() - ); + if (x != null) return; + + BigInteger[] res = fetchAttributesAsInts(new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_VALUE), + new CK_ATTRIBUTE(CKA_PRIME), + new CK_ATTRIBUTE(CKA_BASE), + }); + x = res[0]; + params = new DHParameterSpec(res[1], res[2]); } + public String getFormat() { token.ensureValid(); return "PKCS#8"; } + synchronized byte[] getEncodedInternal() { token.ensureValid(); if (encoded == null) { @@ -897,10 +1013,10 @@ abstract class P11Key implements Key, Length { return params; } public int hashCode() { + fetchValues(); if (!token.isValid()) { return 0; } - fetchValues(); return Objects.hash(x, params.getP(), params.getG()); } public boolean equals(Object obj) { @@ -921,39 +1037,36 @@ abstract class P11Key implements Key, Length { } } - private static final class P11DHPublicKey extends P11Key + private static final class P11DHPublicKey extends P11PublicKey implements DHPublicKey { static final long serialVersionUID = -598383872153843657L; - private BigInteger y; - @SuppressWarnings("serial") // Type of field is not Serializable - private DHParameterSpec params; - private byte[] encoded; + private transient BigInteger y; + private transient DHParameterSpec params; + P11DHPublicKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PUBLIC, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); } + private synchronized void fetchValues() { token.ensureValid(); - if (y != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { - new CK_ATTRIBUTE(CKA_VALUE), - new CK_ATTRIBUTE(CKA_PRIME), - new CK_ATTRIBUTE(CKA_BASE), - }; - fetchAttributes(attributes); - y = attributes[0].getBigInteger(); - params = new DHParameterSpec( - attributes[1].getBigInteger(), - attributes[2].getBigInteger() - ); + if (y != null) return; + + BigInteger[] res = fetchAttributesAsInts(new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_VALUE), + new CK_ATTRIBUTE(CKA_PRIME), + new CK_ATTRIBUTE(CKA_BASE), + }); + y = res[0]; + params = new DHParameterSpec(res[1], res[2]); } + public String getFormat() { token.ensureValid(); return "X.509"; } + synchronized byte[] getEncodedInternal() { token.ensureValid(); if (encoded == null) { @@ -1009,45 +1122,88 @@ abstract class P11Key implements Key, Length { } } - private static final class P11ECPrivateKey extends P11Key + static class P11ECPrivateKeyInternal extends P11PrivateKey { + + private static final long serialVersionUID = 1L; + + protected transient ECParameterSpec params; + + static P11ECPrivateKeyInternal of(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs, + boolean keySensitive) { + if (keySensitive) { + return new P11ECPrivateKeyInternal(session, keyID, algorithm, + keyLength, attrs); + } else { + return new P11ECPrivateKey(session, keyID, algorithm, + keyLength, attrs); + } + } + + private P11ECPrivateKeyInternal(Session session, long keyID, + String algorithm, int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); + } + + private synchronized void fetchValues() { + token.ensureValid(); + if (params != null) return; + + try { + byte[] paramBytes = fetchAttributes(new CK_ATTRIBUTE[] { + new CK_ATTRIBUTE(CKA_EC_PARAMS) + })[0].getByteArray(); + + params = P11ECKeyFactory.decodeParameters(paramBytes); + } catch (Exception e) { + throw new RuntimeException("Could not parse key values", e); + } + } + + protected ECParameterSpec getParams() { + fetchValues(); + return params; + } + } + + private static final class P11ECPrivateKey extends P11ECPrivateKeyInternal implements ECPrivateKey { private static final long serialVersionUID = -7786054399510515515L; - private BigInteger s; - @SuppressWarnings("serial") // Type of field is not Serializable - private ECParameterSpec params; - private byte[] encoded; + private transient BigInteger s; // params in P11ECPrivateKeyInternal + P11ECPrivateKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PRIVATE, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); } + private synchronized void fetchValues() { token.ensureValid(); - if (s != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { + if (s != null) return; + + CK_ATTRIBUTE[] attrs = fetchAttributes(new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_VALUE), - new CK_ATTRIBUTE(CKA_EC_PARAMS, params), - }; - fetchAttributes(attributes); - s = attributes[0].getBigInteger(); + new CK_ATTRIBUTE(CKA_EC_PARAMS), + }); + + s = attrs[0].getBigInteger(); try { params = P11ECKeyFactory.decodeParameters - (attributes[1].getByteArray()); + (attrs[1].getByteArray()); } catch (Exception e) { throw new RuntimeException("Could not parse key values", e); } } + public String getFormat() { token.ensureValid(); return "PKCS#8"; } + synchronized byte[] getEncodedInternal() { - token.ensureValid(); if (encoded == null) { - fetchValues(); try { + fetchValues(); Key key = ECUtil.generateECPrivateKey(s, params); encoded = key.getEncoded(); } catch (InvalidKeySpecException e) { @@ -1056,44 +1212,43 @@ abstract class P11Key implements Key, Length { } return encoded; } + public BigInteger getS() { fetchValues(); return s; } + public ECParameterSpec getParams() { fetchValues(); return params; } } - private static final class P11ECPublicKey extends P11Key + private static final class P11ECPublicKey extends P11PublicKey implements ECPublicKey { private static final long serialVersionUID = -6371481375154806089L; - @SuppressWarnings("serial") // Type of field is not Serializable - private ECPoint w; - @SuppressWarnings("serial") // Type of field is not Serializable - private ECParameterSpec params; - private byte[] encoded; + private transient ECPoint w; + private transient ECParameterSpec params; + P11ECPublicKey(Session session, long keyID, String algorithm, - int keyLength, CK_ATTRIBUTE[] attributes) { - super(PUBLIC, session, keyID, algorithm, keyLength, attributes); + int keyLength, CK_ATTRIBUTE[] attrs) { + super(session, keyID, algorithm, keyLength, attrs); } + private synchronized void fetchValues() { token.ensureValid(); - if (w != null) { - return; - } - CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { + if (w != null) return; + + CK_ATTRIBUTE[] attrs = fetchAttributes(new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_EC_POINT), new CK_ATTRIBUTE(CKA_EC_PARAMS), - }; - fetchAttributes(attributes); + }); try { params = P11ECKeyFactory.decodeParameters - (attributes[1].getByteArray()); - byte[] ecKey = attributes[0].getByteArray(); + (attrs[1].getByteArray()); + byte[] ecKey = attrs[0].getByteArray(); // Check whether the X9.63 encoding of an EC point is wrapped // in an ASN.1 OCTET STRING @@ -1115,10 +1270,12 @@ abstract class P11Key implements Key, Length { throw new RuntimeException("Could not parse key values", e); } } + public String getFormat() { token.ensureValid(); return "X.509"; } + synchronized byte[] getEncodedInternal() { token.ensureValid(); if (encoded == null) { @@ -1417,3 +1574,4 @@ final class SessionKeyRef extends PhantomReference { this.clear(); } } + diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java index 0f7b97ebc87903556afb7c00462f75b241bef10d..585fb47ec5461492aa2fc7fdceb8ea538af6e5f2 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java @@ -243,7 +243,7 @@ final class P11KeyStore extends KeyStoreSpi { pc.setPassword(password); // this clones the password if not null } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { if (password != null) { Arrays.fill(password, ' '); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyWrapCipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyWrapCipher.java index 2385040d75c900ddbefbf8e8200a51c861c6c824..caf0bd298fe15611a99710ee3c47fe44968fbce7 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyWrapCipher.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyWrapCipher.java @@ -126,7 +126,7 @@ final class P11KeyWrapCipher extends CipherSpi { String[] algoParts = algorithm.split("/"); if (algoParts[0].startsWith("AES")) { int index = algoParts[0].indexOf('_'); - fixedKeySize = (index == -1? -1 : + fixedKeySize = (index == -1 ? -1 : // should be well-formed since we specify what we support Integer.parseInt(algoParts[0].substring(index+1)) >> 3); try { @@ -180,7 +180,7 @@ final class P11KeyWrapCipher extends CipherSpi { protected AlgorithmParameters engineGetParameters() { // KW and KWP uses but not require parameters, return the default // IV when no IV is supplied by caller - byte[] iv = (this.iv == null? type.defIv : this.iv); + byte[] iv = (this.iv == null ? type.defIv : this.iv); AlgorithmParameterSpec spec = new IvParameterSpec(iv); try { @@ -213,7 +213,7 @@ final class P11KeyWrapCipher extends CipherSpi { ("Only IvParameterSpec is supported"); } - byte[] ivValue = (params == null? null : + byte[] ivValue = (params == null ? null : ((IvParameterSpec)params).getIV()); implInit(opmode, key, ivValue, sr); @@ -285,7 +285,14 @@ final class P11KeyWrapCipher extends CipherSpi { } private void cancelOperation() { - // cancel operation by finishing it; avoid killSession as some + token.ensureValid(); + + if (P11Util.trySessionCancel(token, session, + (opmode == Cipher.ENCRYPT_MODE ? CKF_ENCRYPT : CKF_DECRYPT))) { + return; + } + + // cancel by finishing operations; avoid killSession as some // hardware vendors may require re-login byte[] in = dataBuffer.toByteArray(); int inLen = in.length; @@ -379,7 +386,7 @@ final class P11KeyWrapCipher extends CipherSpi { } else { result -= BLK_SIZE; // minus the leading block including the ICV } - return (result > 0? result : 0); + return (result > 0 ? result : 0); } // reset the states to the pre-initialized values @@ -654,7 +661,7 @@ final class P11KeyWrapCipher extends CipherSpi { P11Key tbwP11Key = null; if (!(tbwKey instanceof P11Key)) { try { - tbwP11Key = (tbwKey instanceof SecretKey? + tbwP11Key = (tbwKey instanceof SecretKey ? P11SecretKeyFactory.convertKey(token, tbwKey, tbwKey.getAlgorithm()) : P11KeyFactory.convertKey(token, tbwKey, diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java index 0e86528bb5708ae4e1a6ebe355a9fc702ac824a3..97082eae850f61b76fc9166eabeb3ecb308ded5f 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java @@ -147,7 +147,12 @@ final class P11Mac extends MacSpi { private void cancelOperation() { token.ensureValid(); - // cancel operation by finishing it; avoid killSession as some + + if (P11Util.trySessionCancel(token, session, CKF_SIGN)) { + return; + } + + // cancel by finishing operations; avoid killSession as some // hardware vendors may require re-login try { token.p11.C_SignFinal(session.id(), 0); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java index 88b7b9cd5e87eac329e562bbfae1d38408d49825..512bf521be79172b20aabaf17f04118cd436f1ac 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java @@ -170,7 +170,7 @@ final class P11PSSSignature extends SignatureSpi { this.mechanism = new CK_MECHANISM(mechId); int idx = algorithm.indexOf("with"); // convert to stdName - this.mdAlg = (idx == -1? + this.mdAlg = (idx == -1 ? null : toStdName(algorithm.substring(0, idx))); switch ((int)mechId) { @@ -193,7 +193,7 @@ final class P11PSSSignature extends SignatureSpi { throw new NoSuchAlgorithmException("Unsupported algorithm: " + algorithm); } - this.md = (this.mdAlg == null? null : + this.md = (this.mdAlg == null ? null : MessageDigest.getInstance(this.mdAlg)); type = T_DIGEST; break; @@ -269,9 +269,16 @@ final class P11PSSSignature extends SignatureSpi { private void cancelOperation() { token.ensureValid(); + if (DEBUG) System.out.print("Cancelling operation"); - // cancel operation by finishing it; avoid killSession as some + if (P11Util.trySessionCancel(token, session, + (mode == M_SIGN ? CKF_SIGN : CKF_VERIFY))) { + if (DEBUG) System.out.println(" by C_SessionCancel"); + return; + } + + // cancel by finishing operations; avoid killSession call as some // hardware vendors may require re-login try { if (mode == M_SIGN) { @@ -280,7 +287,7 @@ final class P11PSSSignature extends SignatureSpi { token.p11.C_SignFinal(session.id(), 0); } else { byte[] digest = - (md == null? new byte[0] : md.digest()); + (md == null ? new byte[0] : md.digest()); if (DEBUG) System.out.println(" by C_Sign"); token.p11.C_Sign(session.id(), digest); } @@ -292,7 +299,7 @@ final class P11PSSSignature extends SignatureSpi { token.p11.C_VerifyFinal(session.id(), signature); } else { byte[] digest = - (md == null? new byte[0] : md.digest()); + (md == null ? new byte[0] : md.digest()); if (DEBUG) System.out.println(" by C_Verify"); token.p11.C_Verify(session.id(), digest, signature); } diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSACipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSACipher.java index 869b77d4a638238965d873c851f991d980fe2495..1506918da962033128cdc98136dadefce6062352 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSACipher.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSACipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ import javax.crypto.spec.*; import static sun.security.pkcs11.TemplateManager.*; import sun.security.pkcs11.wrapper.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; +import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*; import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; import sun.security.util.KeyUtil; @@ -266,7 +267,21 @@ final class P11RSACipher extends CipherSpi { // state variables such as "initialized" private void cancelOperation() { token.ensureValid(); - // cancel operation by finishing it; avoid killSession as some + + long flags = switch(mode) { + case MODE_ENCRYPT -> CKF_ENCRYPT; + case MODE_DECRYPT -> CKF_DECRYPT; + case MODE_SIGN -> CKF_SIGN; + case MODE_VERIFY -> CKF_VERIFY; + default -> { + throw new AssertionError("Unexpected value: " + mode); + } + }; + if (P11Util.trySessionCancel(token, session, flags)) { + return; + } + + // cancel by finishing operations; avoid killSession as some // hardware vendors may require re-login try { PKCS11 p11 = token.p11; diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java index 7c1714356407e4b0162c4e3530ce1ffabd16a7cf..c27a3f4f02e77d5877a709176f546c9620308209 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java @@ -119,6 +119,9 @@ final class P11Signature extends SignatureSpi { // key instance used, if init*() was called private P11Key p11Key; + // signature length expected or 0 for unknown + private int sigLen; + // message digest, if we do the digesting ourselves private final MessageDigest md; @@ -280,12 +283,18 @@ final class P11Signature extends SignatureSpi { private void cancelOperation() { token.ensureValid(); - // cancel operation by finishing it; avoid killSession as some + + if (P11Util.trySessionCancel(token, session, + (mode == M_SIGN ? CKF_SIGN : CKF_VERIFY))) { + return; + } + + // cancel by finishing operations; avoid killSession call as some // hardware vendors may require re-login try { if (mode == M_SIGN) { if (type == T_UPDATE) { - token.p11.C_SignFinal(session.id(), 0); + token.p11.C_SignFinal(session.id(), sigLen); } else { byte[] digest; if (type == T_DIGEST) { @@ -296,12 +305,7 @@ final class P11Signature extends SignatureSpi { token.p11.C_Sign(session.id(), digest); } } else { // M_VERIFY - byte[] signature; - if (mechanism == CKM_DSA) { - signature = new byte[64]; // assume N = 256 - } else { - signature = new byte[(p11Key.length() + 7) >> 3]; - } + byte[] signature = new byte[sigLen]; if (type == T_UPDATE) { token.p11.C_VerifyFinal(session.id(), signature); } else { @@ -317,9 +321,9 @@ final class P11Signature extends SignatureSpi { } catch (PKCS11Exception e) { if (e.match(CKR_OPERATION_NOT_INITIALIZED)) { // Cancel Operation may be invoked after an error on a PKCS#11 - // call. If the operation inside the token was already cancelled, - // do not fail here. This is part of a defensive mechanism for - // PKCS#11 libraries that do not strictly follow the standard. + // call. If the operation was already cancelled, do not fail + // here. This is part of a defensive mechanism for PKCS#11 + // libraries that do not strictly follow the standard. return; } if (mode == M_VERIFY) { @@ -372,6 +376,15 @@ final class P11Signature extends SignatureSpi { md.reset(); } } + sigLen = 0; + if ("DSA".equals(p11Key.getAlgorithm())) { + if (p11Key instanceof P11Key.P11DSAPrivateKeyInternal) { + sigLen = ((P11Key.P11DSAPrivateKeyInternal)p11Key).getParams() + .getQ().bitLength() >> 2; + } else if (p11Key instanceof DSAKey) { + sigLen = ((DSAKey)p11Key).getParams().getQ().bitLength() >> 2; + } + } initialized = true; } @@ -617,7 +630,7 @@ final class P11Signature extends SignatureSpi { try { byte[] signature; if (type == T_UPDATE) { - signature = token.p11.C_SignFinal(session.id(), 0); + signature = token.p11.C_SignFinal(session.id(), sigLen); } else { byte[] digest; if (type == T_DIGEST) { @@ -684,7 +697,7 @@ final class P11Signature extends SignatureSpi { try { if (!p1363Format) { if (keyAlgorithm.equals("DSA")) { - signature = asn1ToDSA(signature); + signature = asn1ToDSA(signature, sigLen); } else if (keyAlgorithm.equals("EC")) { signature = asn1ToECDSA(signature); } @@ -801,7 +814,8 @@ final class P11Signature extends SignatureSpi { } } - private static byte[] asn1ToDSA(byte[] sig) throws SignatureException { + private static byte[] asn1ToDSA(byte[] sig, int sigLen) + throws SignatureException { try { // Enforce strict DER checking for signatures DerInputStream in = new DerInputStream(sig, 0, sig.length, false); @@ -816,8 +830,8 @@ final class P11Signature extends SignatureSpi { BigInteger r = values[0].getPositiveBigInteger(); BigInteger s = values[1].getPositiveBigInteger(); - byte[] br = toByteArray(r, 20); - byte[] bs = toByteArray(s, 20); + byte[] br = toByteArray(r, sigLen/2); + byte[] bs = toByteArray(s, sigLen/2); if ((br == null) || (bs == null)) { throw new SignatureException("Out of range value for R or S"); } @@ -829,7 +843,7 @@ final class P11Signature extends SignatureSpi { } } - private byte[] asn1ToECDSA(byte[] sig) throws SignatureException { + private static byte[] asn1ToECDSA(byte[] sig) throws SignatureException { try { // Enforce strict DER checking for signatures DerInputStream in = new DerInputStream(sig, 0, sig.length, false); @@ -909,3 +923,4 @@ final class P11Signature extends SignatureSpi { return null; } } + diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java index 262cfc062adae7b687e86ae3e2d9a58e95823798..256c2f965689809d20cc9ee34d34c71760502249 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java @@ -28,6 +28,9 @@ package sun.security.pkcs11; import java.math.BigInteger; import java.security.*; +import sun.security.pkcs11.wrapper.PKCS11Exception; +import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*; + /** * Collection of static utility methods. * @@ -187,4 +190,22 @@ public final class P11Util { return sb.toString(); } + // returns true if successfully cancelled + static boolean trySessionCancel(Token token, Session session, long flags) + throws ProviderException { + if (token.p11.getVersion().major == 3) { + try { + token.p11.C_SessionCancel(session.id(), flags); + return true; + } catch (PKCS11Exception e) { + // return false for CKR_OPERATION_CANCEL_FAILED, so callers + // can cancel in the pre v3.0 way, i.e. by finishing off the + // current operation + if (!e.match(CKR_OPERATION_CANCEL_FAILED)) { + throw new ProviderException("cancel failed", e); + } + } + } + return false; + } } diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java index e86d54963d36c0a23c3f7a511bf24651a79cfadd..9cdbdfa9d6b920949e5a3b50367d9c5072293c8c 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -150,7 +150,7 @@ public final class SunPKCS11 extends AuthProvider { this.config = c; if (debug != null) { - System.out.println("SunPKCS11 loading " + config.getFileName()); + debug.println("SunPKCS11 loading " + config.getFileName()); } String library = config.getLibrary(); @@ -176,7 +176,6 @@ public final class SunPKCS11 extends AuthProvider { // switch to using the NSS trust attributes for trusted certs // (KeyStore). // - if (useSecmod) { // note: Config ensures library/slot/slotListIndex not specified // in secmod mode. @@ -328,8 +327,7 @@ public final class SunPKCS11 extends AuthProvider { initArgs.flags = CKF_OS_LOCKING_OK; PKCS11 tmpPKCS11; try { - tmpPKCS11 = PKCS11.getInstance( - library, functionList, initArgs, + tmpPKCS11 = PKCS11.getInstance(library, functionList, initArgs, config.getOmitInitialize()); } catch (PKCS11Exception e) { if (debug != null) { @@ -345,18 +343,18 @@ public final class SunPKCS11 extends AuthProvider { } else { initArgs.flags = 0; } - tmpPKCS11 = PKCS11.getInstance(library, - functionList, initArgs, config.getOmitInitialize()); + tmpPKCS11 = PKCS11.getInstance(library, functionList, initArgs, + config.getOmitInitialize()); } p11 = tmpPKCS11; - CK_INFO p11Info = p11.C_GetInfo(); - if (p11Info.cryptokiVersion.major < 2) { + if (p11.getVersion().major < 2) { throw new ProviderException("Only PKCS#11 v2.0 and later " - + "supported, library version is v" + p11Info.cryptokiVersion); + + "supported, library version is v" + p11.getVersion()); } boolean showInfo = config.getShowInfo(); if (showInfo) { + CK_INFO p11Info = p11.C_GetInfo(); System.out.println("Information for provider " + getName()); System.out.println("Library info:"); System.out.println(p11Info); @@ -1482,12 +1480,10 @@ public final class SunPKCS11 extends AuthProvider { } // get the pin if necessary - char[] pin = null; if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) { // get password - CallbackHandler myHandler = getCallbackHandler(handler); if (myHandler == null) { throw new LoginException @@ -1503,6 +1499,7 @@ public final class SunPKCS11 extends AuthProvider { PasswordCallback pcall = new PasswordCallback(form.format(source), false); Callback[] callbacks = { pcall }; + try { myHandler.handle(callbacks); } catch (Exception e) { @@ -1522,13 +1519,12 @@ public final class SunPKCS11 extends AuthProvider { } // perform token login - Session session = null; try { session = token.getOpSession(); - // pin is NULL if using CKF_PROTECTED_AUTHENTICATION_PATH p11.C_Login(session.id(), CKU_USER, pin); + if (debug != null) { debug.println("login succeeded"); } diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java index 2b2f3d0ebd41d1163ae81f6018823db08a32b27c..f87690bc24f96de870115022f843eee0cd74b35c 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java @@ -110,7 +110,7 @@ public class PKCS11 { * e.g. pk2priv.dll. */ private final String pkcs11ModulePath; - + private final CK_VERSION version; private long pNativeData; /** @@ -141,13 +141,30 @@ public class PKCS11 { * path, if the driver is not in the system's search path. * * @param pkcs11ModulePath the PKCS#11 library path + * @param functionList the method name for retrieving the PKCS#11 + * function list; may be null if not set in config file * @preconditions (pkcs11ModulePath <> null) * @postconditions */ - PKCS11(String pkcs11ModulePath, String functionListName) + PKCS11(String pkcs11ModulePath, String functionList) throws IOException { - connect(pkcs11ModulePath, functionListName); + this.version = connect(pkcs11ModulePath, functionList); this.pkcs11ModulePath = pkcs11ModulePath; + // bug in native PKCS#11 lib; workaround it by calling C_GetInfo() + // and get cryptoki version from there + if (this.version.major != 2 && this.version.major != 3) { + try { + CK_INFO p11Info = C_GetInfo(); + this.version.major = p11Info.cryptokiVersion.major; + this.version.minor = p11Info.cryptokiVersion.minor; + } catch (PKCS11Exception e) { + // give up; just use what is returned by connect() + } + } + } + + public CK_VERSION getVersion() { + return version; } public static synchronized PKCS11 getInstance(String pkcs11ModulePath, @@ -186,11 +203,14 @@ public class PKCS11 { * native part. * * @param pkcs11ModulePath The PKCS#11 library path. + * @param functionList the method name for retrieving the PKCS#11 + * function list; may be null if not set in config file + * @return the actual PKCS11 interface version * @preconditions (pkcs11ModulePath <> null) * @postconditions */ - private native void connect(String pkcs11ModulePath, String functionListName) - throws IOException; + private native CK_VERSION connect(String pkcs11ModulePath, + String functionList) throws IOException; /** * Disconnects the PKCS#11 library from this object. After calling this @@ -463,6 +483,20 @@ public class PKCS11 { public native CK_SESSION_INFO C_GetSessionInfo(long hSession) throws PKCS11Exception; + /** + * C_SessionCancel terminates active session based operations. + * (Session management) (New in PKCS#11 v3.0) + * + * @param hSession the session's handle + * (PKCS#11 param: CK_SESSION_HANDLE hSession) + * @param flags indicates the operations to cancel. + * (PKCS#11 param: CK_FLAGS flags) + * @exception PKCS11Exception If function returns other value than CKR_OK. + * @preconditions + * @postconditions + */ + public native void C_SessionCancel(long hSession, long flags) + throws PKCS11Exception; /** * C_GetOperationState obtains the state of the cryptographic operation @@ -521,6 +555,24 @@ public class PKCS11 { public native void C_Login(long hSession, long userType, char[] pPin) throws PKCS11Exception; + ///** + // * C_LoginUser logs a user into a token. (New in PKCS#11 v3.0) + // * (Session management) + // * + // * @param hSession the session's handle + // * (PKCS#11 param: CK_SESSION_HANDLE hSession) + // * @param userType the user type + // * (PKCS#11 param: CK_USER_TYPE userType) + // * @param pPin the user's PIN and the length of the PIN + // * (PKCS#11 param: CK_CHAR_PTR pPin, CK_ULONG ulPinLen) + // * @param pUsername the user name and the length of the user name + // * (PKCS#11 param: CK_CHAR_PTR pUsername, CK_ULONG ulUsernameLen) + // * @exception PKCS11Exception If function returns other value than CKR_OK. + // * @preconditions + // * @postconditions + // */ + //public native void C_LoginUser(long hSession, long userType, char[] pPin, + // String pUsername) throws PKCS11Exception; /** * C_Logout logs a user out from a token. @@ -807,7 +859,6 @@ public class PKCS11 { public native int C_EncryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception; - /** * C_DecryptInit initializes a decryption operation. * (Encryption and decryption) @@ -902,8 +953,6 @@ public class PKCS11 { public native int C_DecryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception; - - /* ***************************************************************************** * Message digesting ******************************************************************************/ @@ -1615,7 +1664,7 @@ public class PKCS11 { * * @exception Throwable If finalization fails. */ - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { disconnect(); } @@ -1624,9 +1673,9 @@ public class PKCS11 { // parent. Used for tokens that only support single threaded access static class SynchronizedPKCS11 extends PKCS11 { - SynchronizedPKCS11(String pkcs11ModulePath, String functionListName) + SynchronizedPKCS11(String pkcs11ModulePath, String functionList) throws IOException { - super(pkcs11ModulePath, functionListName); + super(pkcs11ModulePath, functionList); } synchronized void C_Initialize(Object pInitArgs) throws PKCS11Exception { @@ -1682,11 +1731,22 @@ static class SynchronizedPKCS11 extends PKCS11 { return super.C_GetSessionInfo(hSession); } - public synchronized void C_Login(long hSession, long userType, char[] pPin) + public synchronized void C_SessionCancel(long hSession, long flags) throws PKCS11Exception { + super.C_SessionCancel(hSession, flags); + } + + public synchronized void C_Login(long hSession, long userType, + char[] pPin) throws PKCS11Exception { super.C_Login(hSession, userType, pPin); } + //public synchronized void C_LoginUser(long hSession, long userType, + // char[] pPin, String pUsername) + // throws PKCS11Exception { + // super.C_LoginUser(hSession, userType, pPin, pUsername); + //} + public synchronized void C_Logout(long hSession) throws PKCS11Exception { super.C_Logout(hSession); } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c index b06d397b09e1b8c89e6f43e0f5b1e58f91b78487..5209c5bbf78bc3e966be36f367bbf97fd4d11471 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -272,6 +272,33 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionI } #endif +#ifdef P11_ENABLE_C_SESSIONCANCEL +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_SessionCancel + * Signature: (JJ)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jlong jFlags CK_FLAGS flags + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SessionCancel + (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jFlags) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_RV rv; + + CK_FUNCTION_LIST_3_0_PTR ckpFunctions30 = getFunctionList30(env, obj); + if (ckpFunctions30 == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + + rv = (*ckpFunctions30->C_SessionCancel)(ckSessionHandle, + jLongToCKULong(jFlags)); + + ckAssertReturnValueOK(env, rv); +} +#endif + #ifdef P11_ENABLE_C_GETOPERATIONSTATE /* * Class: sun_security_pkcs11_wrapper_PKCS11 @@ -351,7 +378,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationSt free(ckpState); - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } + ckAssertReturnValueOK(env, rv); } #endif @@ -367,28 +394,83 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationSt * CK_ULONG ulPinLen */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login - (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, jcharArray jPin) + (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, + jcharArray jPin) { CK_SESSION_HANDLE ckSessionHandle; CK_USER_TYPE ckUserType; CK_CHAR_PTR ckpPinArray = NULL_PTR; CK_ULONG ckPinLength; CK_RV rv; + CK_FUNCTION_LIST_PTR ckpFunctions; - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return; } + ckpFunctions = getFunctionList(env, obj); + + if (ckpFunctions == NULL) { + return; + } ckSessionHandle = jLongToCKULong(jSessionHandle); ckUserType = jLongToCKULong(jUserType); jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength); if ((*env)->ExceptionCheck(env)) { return; } - rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray, ckPinLength); + rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray, + ckPinLength); + free(ckpPinArray); + + ckAssertReturnValueOK(env, rv); +} +#endif + +#ifdef P11_ENABLE_C_LOGINUSER +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_LoginUser + * Signature: (JJ[C;Ljava/lang/String;)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jlong jUserType CK_USER_TYPE userType + * @param jcharArray jPin CK_CHAR_PTR pPin + * CK_ULONG ulPinLen + * @param jstring jUsername CK_CHAR_PTR pUsername + * CK_ULONG ulUsernameLen + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1LoginUser + (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, + jcharArray jPin, jstring jUsername) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_USER_TYPE ckUserType; + CK_CHAR_PTR ckpPinArray = NULL_PTR; + CK_ULONG ckPinLength; + CK_CHAR_PTR ckpUsername = NULL_PTR; + CK_ULONG ckUsernameLength; + CK_RV rv; + CK_FUNCTION_LIST_3_0_PTR ckpFunctions30; + + ckpFunctions30 = getFunctionList30(env, obj); + + ckSessionHandle = jLongToCKULong(jSessionHandle); + ckUserType = jLongToCKULong(jUserType); + jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength); + if ((*env)->ExceptionCheck(env)) { return; } + jStringToCKUTF8CharArray(env, jUsername, &ckpUsername, + &ckUsernameLength); + if ((*env)->ExceptionCheck(env)) { return; } + + if (ckpFunctions30 == NULL) { + return; + } + rv = (*ckpFunctions30->C_LoginUser)(ckSessionHandle, ckUserType, + ckpPinArray, ckPinLength, ckpUsername, ckUsernameLength); free(ckpPinArray); + free(ckpUsername); - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } + ckAssertReturnValueOK(env, rv); } + #endif #ifdef P11_ENABLE_C_LOGOUT @@ -411,7 +493,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout ckSessionHandle = jLongToCKULong(jSessionHandle); rv = (*ckpFunctions->C_Logout)(ckSessionHandle); - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } + ckAssertReturnValueOK(env, rv); } #endif diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c index 520bd52a2cd6c1fda7290073b00b21f1810074a6..2920707a2542d710e4ee384714f31a9b2c5a59bb 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c @@ -136,6 +136,20 @@ CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation) return ckpFunctions; } +CK_FUNCTION_LIST_3_0_PTR getFunctionList30(JNIEnv *env, jobject + pkcs11Implementation) { + ModuleData *moduleData; + CK_FUNCTION_LIST_3_0_PTR ckpFunctions30; + + moduleData = getModuleEntry(env, pkcs11Implementation); + if (moduleData == NULL) { + throwDisconnectedRuntimeException(env); + return NULL; + } + ckpFunctions30 = moduleData->ckFunctionList30Ptr; + return ckpFunctions30; +} + /* * Returns 1, if the given pkcs11Implementation is in the list. diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h index eb6d01b9e47c8a6bc265722c858833684eb54b9f..c2b6f3d94b5076b9e699802988e6a684c6d99e15 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h @@ -100,9 +100,11 @@ #define P11_ENABLE_C_CLOSESESSION #undef P11_ENABLE_C_CLOSEALLSESSIONS #define P11_ENABLE_C_GETSESSIONINFO +#define P11_ENABLE_C_SESSIONCANCEL #define P11_ENABLE_C_GETOPERATIONSTATE #define P11_ENABLE_C_SETOPERATIONSTATE #define P11_ENABLE_C_LOGIN +//#define P11_ENABLE_C_LOGINUSER #define P11_ENABLE_C_LOGOUT #define P11_ENABLE_C_CREATEOBJECT #define P11_ENABLE_C_COPYOBJECT @@ -209,17 +211,21 @@ //#define TRACE0d(s) { printf(s); fflush(stdout); } //#define TRACE1d(s, p1) { printf(s, p1); fflush(stdout); } //#define TRACE2d(s, p1, p2) { printf(s, p1, p2); fflush(stdout); } +//#define TRACE3d(s, p1, p2, p3) { printf(s, p1, p2, p3); fflush(stdout); } +//#define TRACE4d(s, p1, p2, p3, p4) { printf(s, p1, p2, p3, p4); fflush(stdout); } #ifdef P11_DEBUG #define TRACE0(s) { printf(s); fflush(stdout); } #define TRACE1(s, p1) { printf(s, p1); fflush(stdout); } #define TRACE2(s, p1, p2) { printf(s, p1, p2); fflush(stdout); } #define TRACE3(s, p1, p2, p3) { printf(s, p1, p2, p3); fflush(stdout); } +#define TRACE4(s, p1, p2, p3, p4) { printf(s, p1, p2, p3, p4); fflush(stdout); } #else #define TRACE0(s) #define TRACE1(s, p1) #define TRACE2(s, p1, p2) #define TRACE3(s, p1, p2, p3) +#define TRACE4(s, p1, p2, p3, p4) #define TRACE_INTEND #define TRACE_UNINTEND #endif @@ -412,6 +418,8 @@ CK_RV callJUnlockMutex(CK_VOID_PTR pMutex); void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData); ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation); CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation); +CK_FUNCTION_LIST_3_0_PTR getFunctionList30(JNIEnv *env, jobject + pkcs11Implementation); /* A structure to encapsulate the required data for a Notify callback */ struct NotifyEncapsulation { diff --git a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c index 0105a9873b56f25259c288ed5902b91e5be00500..6cae296e8d4dbd330a7ccec7b5270a69b8ae0e3b 100644 --- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c +++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -72,26 +72,34 @@ /* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: connect - * Signature: (Ljava/lang/String;)V + * Signature: (Ljava/lang/String;)Lsun/security/pkcs11/wrapper/CK_VERSION; */ -JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect - (JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList) -{ +JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect + (JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, + jstring jGetFunctionList) { + void *hModule; char *error; - CK_C_GetFunctionList C_GetFunctionList=NULL; + int i; + CK_ULONG ulCount = 0; + CK_C_GetInterfaceList C_GetInterfaceList = NULL; + CK_INTERFACE_PTR iList = NULL; + CK_C_GetInterface C_GetInterface = NULL; + CK_INTERFACE_PTR interface = NULL; + CK_C_GetFunctionList C_GetFunctionList = NULL; CK_RV rv; - ModuleData *moduleData; + ModuleData *moduleData = NULL; jobject globalPKCS11ImplementationReference; char *systemErrorMessage; char *exceptionMessage; - const char *getFunctionListStr; + const char *getFunctionListStr = NULL; - const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0); + const char *libraryNameStr = (*env)->GetStringUTFChars(env, + jPkcs11ModulePath, 0); if (libraryNameStr == NULL) { - return; + return NULL; } - TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr); + TRACE1("Connect: connect to PKCS#11 module: %s ... ", libraryNameStr); /* * Load the PKCS #11 DLL @@ -108,39 +116,92 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect exceptionMessage = (char *) malloc(sizeof(char) * (strlen(systemErrorMessage) + strlen(libraryNameStr) + 1)); if (exceptionMessage == NULL) { throwOutOfMemoryError(env, 0); - (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr); - return; + goto cleanup; } strcpy(exceptionMessage, systemErrorMessage); strcat(exceptionMessage, libraryNameStr); throwIOException(env, exceptionMessage); - (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr); free(exceptionMessage); - return; + goto cleanup; } - (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr); - /* - * Get function pointer to C_GetFunctionList - */ - dlerror(); /* clear any old error message not fetched */ - // with the old JAR file jGetFunctionList is null, temporarily check for that + // clear any old error message not fetched + dlerror(); + +#ifdef DEBUG + C_GetInterfaceList = (CK_C_GetInterfaceList) dlsym(hModule, + "C_GetInterfaceList"); + if (C_GetInterfaceList != NULL) { + TRACE0("Connect: Found C_GetInterfaceList func\n"); + rv = (C_GetInterfaceList)(NULL, &ulCount); + if (rv == CKR_OK) { + TRACE1("Connect: interface list size %ld \n", ulCount); + // retrieve available interfaces and report their info + iList = (CK_INTERFACE_PTR) + malloc(ulCount*sizeof(CK_INTERFACE)); + rv = C_GetInterfaceList(iList, &ulCount); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { + TRACE0("Connect: error polling interface list\n"); + goto cleanup; + } + for (i=0; i < (int)ulCount; i++) { + TRACE4("Connect: name %s, version %d.%d, flags 0x%lX\n", + iList[i].pInterfaceName, + ((CK_VERSION *)iList[i].pFunctionList)->major, + ((CK_VERSION *)iList[i].pFunctionList)->minor, + iList[i].flags); + } + } else { + TRACE0("Connect: error polling interface list size\n"); + } + } else { + TRACE0("Connect: No C_GetInterfaceList func\n"); + } +#endif + if (jGetFunctionList != NULL) { - getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0); + getFunctionListStr = (*env)->GetStringUTFChars(env, + jGetFunctionList, 0); if (getFunctionListStr == NULL) { - return; + goto cleanup; } - C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr); - (*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr); - } - if (C_GetFunctionList == NULL) { - throwIOException(env, "ERROR: C_GetFunctionList == NULL"); - return; - } else if ( (systemErrorMessage = dlerror()) != NULL ){ - throwIOException(env, systemErrorMessage); - return; + C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, + getFunctionListStr); + if ((systemErrorMessage = dlerror()) != NULL){ + throwIOException(env, systemErrorMessage); + goto cleanup; + } + if (C_GetFunctionList == NULL) { + TRACE1("Connect: No %s func\n", getFunctionListStr); + throwIOException(env, "ERROR: C_GetFunctionList == NULL"); + goto cleanup; + } + TRACE1("Connect: Found %s func\n", getFunctionListStr); + } else { + // if none specified, then we try 3.0 API first before trying 2.40 + C_GetInterface = (CK_C_GetInterface) dlsym(hModule, "C_GetInterface"); + if ((C_GetInterface != NULL) && (dlerror() == NULL)) { + TRACE0("Connect: Found C_GetInterface func\n"); + rv = (C_GetInterface)(NULL, NULL, &interface, 0L); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + goto setModuleData; + } + } + C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, + "C_GetFunctionList"); + if ((systemErrorMessage = dlerror()) != NULL){ + throwIOException(env, systemErrorMessage); + goto cleanup; + } + if (C_GetFunctionList == NULL) { + TRACE0("Connect: No C_GetFunctionList func\n"); + throwIOException(env, "ERROR: C_GetFunctionList == NULL"); + goto cleanup; + } + TRACE0("Connect: Found C_GetFunctionList func\n"); } +setModuleData: /* * Get function pointers to all PKCS #11 functions */ @@ -148,19 +209,56 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect if (moduleData == NULL) { dlclose(hModule); throwOutOfMemoryError(env, 0); - return; + goto cleanup; } moduleData->hModule = hModule; moduleData->applicationMutexHandler = NULL; - rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr)); + if (C_GetFunctionList != NULL) { + rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr)); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { + goto cleanup; + } + } else if (interface != NULL) { + moduleData->ckFunctionListPtr = interface->pFunctionList; + if (((CK_VERSION *)moduleData->ckFunctionListPtr)->major == 3) { + moduleData->ckFunctionList30Ptr = interface->pFunctionList; + } + } else { + // should never happen + throwIOException(env, "ERROR: No function list ptr found"); + goto cleanup; + } + if (((CK_VERSION *)moduleData->ckFunctionListPtr)->major == 3) { + moduleData->ckFunctionList30Ptr = interface->pFunctionList; + } else { + moduleData->ckFunctionList30Ptr = NULL; + } + + TRACE2("Connect: FunctionListPtr version = %d.%d\n", + ((CK_VERSION *)moduleData->ckFunctionListPtr)->major, + ((CK_VERSION *)moduleData->ckFunctionListPtr)->minor); + globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj); putModuleEntry(env, globalPKCS11ImplementationReference, moduleData); - TRACE0("FINISHED\n"); - - if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +cleanup: + if (jPkcs11ModulePath != NULL && libraryNameStr != NULL) { + (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr); + } + if (jGetFunctionList != NULL && getFunctionListStr != NULL) { + (*env)->ReleaseStringUTFChars(env, jGetFunctionList, + getFunctionListStr); + } + TRACE0("Connect: FINISHED\n"); + if (moduleData != NULL) { + return ckVersionPtrToJVersion(env, + (CK_VERSION *)moduleData->ckFunctionListPtr); + } else { + return NULL; + } } + /* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: disconnect diff --git a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h index 0d8cb36337495b634a8825cc1ed9300c1eb30a74..676e3ab5d4c6d4614a26ae44240b0ac28a9de5cc 100644 --- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h +++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. */ /* @@ -83,8 +83,9 @@ struct ModuleData { /* the module (DLL or shared library) handle */ void *hModule; - /* The pointer to the PKCS#11 functions of this module. */ + /* The pointers to the PKCS#11 functions of this module. */ CK_FUNCTION_LIST_PTR ckFunctionListPtr; + CK_FUNCTION_LIST_3_0_PTR ckFunctionList30Ptr; /* Reference to the object to use for mutex handling. NULL, if not used. */ jobject applicationMutexHandler; diff --git a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c index 145ad7f5693127fede0c576c7f03b58f7492b322..ea005664dff91ef61c4ab32a6977de1a06312cc4 100644 --- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c +++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -72,16 +72,22 @@ /* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: connect - * Signature: (Ljava/lang/String;)V + * Signature: (Ljava/lang/String;)Lsun/security/pkcs11/wrapper/CK_VERSION; */ -JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect +JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect (JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, - jstring jGetFunctionList) + jstring jGetFunctionList) { HINSTANCE hModule; - CK_C_GetFunctionList C_GetFunctionList; + int i = 0; + CK_ULONG ulCount = 0; + CK_C_GetInterfaceList C_GetInterfaceList = NULL; + CK_INTERFACE_PTR iList = NULL; + CK_C_GetInterface C_GetInterface = NULL; + CK_INTERFACE_PTR interface = NULL; + CK_C_GetFunctionList C_GetFunctionList = NULL; CK_RV rv = CK_ASSERT_OK; - ModuleData *moduleData; + ModuleData *moduleData = NULL; jobject globalPKCS11ImplementationReference; LPVOID lpMsgBuf = NULL; char *exceptionMessage = NULL; @@ -91,10 +97,9 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect jPkcs11ModulePath, 0); TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr); - - /* - * Load the PKCS #11 DLL - */ + /* + * Load the PKCS #11 DLL + */ hModule = LoadLibrary(libraryNameStr); if (hModule == NULL) { FormatMessage( @@ -120,29 +125,93 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect goto cleanup; } +#ifdef DEBUG /* - * Get function pointer to C_GetFunctionList + * Get function pointer to C_GetInterfaceList */ - getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0); - C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule, - getFunctionListStr); - (*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr); - if (C_GetFunctionList == NULL) { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - 0, /* Default language */ - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - throwIOException(env, (LPTSTR) lpMsgBuf); - goto cleanup; + C_GetInterfaceList = (CK_C_GetInterfaceList) GetProcAddress(hModule, + "C_GetInterfaceList"); + if (C_GetInterfaceList != NULL) { + TRACE0("Found C_GetInterfaceList func\n"); + rv = (C_GetInterfaceList)(NULL, &ulCount); + if (rv == CKR_OK) { + /* get copy of interfaces */ + iList = (CK_INTERFACE_PTR) + malloc(ulCount*sizeof(CK_INTERFACE)); + rv = C_GetInterfaceList(iList, &ulCount); + for (i=0; i < (int)ulCount; i++) { + printf("interface %s version %d.%d funcs %p flags 0x%lu\n", + iList[i].pInterfaceName, + ((CK_VERSION *)iList[i].pFunctionList)->major, + ((CK_VERSION *)iList[i].pFunctionList)->minor, + iList[i].pFunctionList, iList[i].flags); + } + } else { + TRACE0("Connect: error polling interface list size\n"); + } + } else { + TRACE0("Connect: No C_GetInterfaceList func\n"); + } +#endif + + if (jGetFunctionList != NULL) { + getFunctionListStr = (*env)->GetStringUTFChars(env, + jGetFunctionList, 0); + if (getFunctionListStr == NULL) { + goto cleanup; + } + C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule, + getFunctionListStr); + if (C_GetFunctionList == NULL) { + TRACE1("Connect: No %s func\n", getFunctionListStr); + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + 0, /* Default language */ + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + throwIOException(env, (LPTSTR) lpMsgBuf); + goto cleanup; + } + TRACE1("Connect: Found %s func\n", getFunctionListStr); + } else { + // if none specified, then we try 3.0 API first before trying 2.40 + C_GetInterface = (CK_C_GetInterface) GetProcAddress(hModule, + "C_GetInterface"); + if (C_GetInterface != NULL) { + TRACE0("Connect: Found C_GetInterface func\n"); + rv = (C_GetInterface)(NULL, NULL, &interface, 0); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + goto setModuleData; + } + } + C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule, + "C_GetFunctionList"); + if (C_GetFunctionList == NULL) { + TRACE0("Connect: No C_GetFunctionList func\n"); + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + 0, /* Default language */ + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + throwIOException(env, (LPTSTR) lpMsgBuf); + goto cleanup; + } + TRACE0("Connect: Found C_GetFunctionList func\n"); } +setModuleData: /* * Get function pointers to all PKCS #11 functions */ @@ -153,12 +222,31 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect } moduleData->hModule = hModule; moduleData->applicationMutexHandler = NULL; - rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr)); + if (C_GetFunctionList != NULL) { + rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr)); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { + goto cleanup; + } + } else if (interface != NULL) { + moduleData->ckFunctionListPtr = interface->pFunctionList; + } else { + // should never happen + throwIOException(env, "ERROR: No function list ptr found"); + goto cleanup; + } + if (((CK_VERSION *)moduleData->ckFunctionListPtr)->major == 3) { + moduleData->ckFunctionList30Ptr = interface->pFunctionList; + } else { + moduleData->ckFunctionList30Ptr = NULL; + } + + TRACE2("Connect: FunctionListPtr version = %d.%d\n", + ((CK_VERSION *)moduleData->ckFunctionListPtr)->major, + ((CK_VERSION *)moduleData->ckFunctionListPtr)->minor); + globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj); putModuleEntry(env, globalPKCS11ImplementationReference, moduleData); - TRACE0("FINISHED\n"); - cleanup: /* Free up allocated buffers we no longer need */ if (lpMsgBuf != NULL) { @@ -167,11 +255,21 @@ cleanup: if (libraryNameStr != NULL) { (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr); } + if (jGetFunctionList != NULL && getFunctionListStr != NULL) { + (*env)->ReleaseStringUTFChars(env, jGetFunctionList, + getFunctionListStr); + } if (exceptionMessage != NULL) { free(exceptionMessage); } + TRACE0("Connect: FINISHED\n"); + if (moduleData != NULL) { + return ckVersionPtrToJVersion(env, + (CK_VERSION *)moduleData->ckFunctionListPtr); + } else { + return NULL; + } - if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } } /* diff --git a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h index 7cff0c7c24907e0b799730410f96076c75e45ace..0a069d5bc977ff5ae71f7b1b73d7cdf07290e381 100644 --- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h +++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. */ /* @@ -93,8 +93,9 @@ struct ModuleData { HINSTANCE hModule; - /* The pointer to the PKCS#11 functions of this module. */ + /* The pointers to the PKCS#11 functions of this module. */ CK_FUNCTION_LIST_PTR ckFunctionListPtr; + CK_FUNCTION_LIST_3_0_PTR ckFunctionList30Ptr; /* Reference to the object to use for mutex handling. NULL, if not used. */ jobject applicationMutexHandler; diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDHKeyAgreement.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDHKeyAgreement.java index 8f69da0ac7ad64f7d892ed16e5b9977154189743..79eb9a1f7744f822446ef0260f2500cc0cb6023f 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDHKeyAgreement.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDHKeyAgreement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -197,7 +197,7 @@ public final class ECDHKeyAgreement extends KeyAgreementSpi { EllipticCurve curve = spec.getCurve(); BigInteger rhs = x.modPow(BigInteger.valueOf(3), p).add(curve.getA() .multiply(x)).add(curve.getB()).mod(p); - BigInteger lhs = y.modPow(BigInteger.valueOf(2), p).mod(p); + BigInteger lhs = y.modPow(BigInteger.TWO, p); if (!rhs.equals(lhs)) { throw new InvalidKeyException("Point is not on curve"); } diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java index 8c9e4f9dbe625e2795a443fb704811417ce4c3e3..200ed63634f601e40a8baa7334170f52eeb7e6f7 100644 --- a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java +++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -208,9 +208,8 @@ public final class SunEC extends Provider { /* * Key Factory engine */ - putService(new ProviderService(this, "KeyFactory", - "EC", "sun.security.ec.ECKeyFactory", - List.of("EllipticCurve"), ATTRS)); + putService(new ProviderServiceA(this, "KeyFactory", + "EC", "sun.security.ec.ECKeyFactory", ATTRS)); /* * Algorithm Parameter engine @@ -319,9 +318,8 @@ public final class SunEC extends Provider { /* * Key Pair Generator engine */ - putService(new ProviderService(this, "KeyPairGenerator", - "EC", "sun.security.ec.ECKeyPairGenerator", - List.of("EllipticCurve"), ATTRS)); + putService(new ProviderServiceA(this, "KeyPairGenerator", + "EC", "sun.security.ec.ECKeyPairGenerator", ATTRS)); /* * Key Agreement engine diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java index 019f0ccac5619c8f6bc9e23b8adfa28d5d023d4e..e010e9717876d50112437ed6bca6ea5831cef72b 100644 --- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java +++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java @@ -55,7 +55,7 @@ abstract class CKey implements Key, Length { this.hCryptKey = hCryptKey; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { try { synchronized(this) { diff --git a/src/jdk.hotspot.agent/doc/clhsdb.html b/src/jdk.hotspot.agent/doc/clhsdb.html index 6d5c99afa6979087457aaaa402eab2f23feebb21..bff7b39017a2d382aef8ccb4517b47ad6a5b7f31 100644 --- a/src/jdk.hotspot.agent/doc/clhsdb.html +++ b/src/jdk.hotspot.agent/doc/clhsdb.html @@ -10,26 +10,17 @@ Command line HSDB

      When debugging remote core dumps it is easier to work with command line tools instead of GUI tools. Command line HSDB (CLHSDB) tool is alternative to SA GUI tool HSDB. +CLHSDB is launched from the command line using the "jhsdb clhsdb" command.

      -There is also JavaScript based SA command line interface called jsdb. -But, CLHSDB supports Unix shell-like (or dbx/gdb-like) command line interface with +CLHSDB supports Unix shell-like (or dbx/gdb-like) command line interface with support for output redirection/appending (familiar >, >>), command history and so on. Each CLHSDB command can have zero or more arguments and optionally end with output redirection (or append) to a file. Commands may be stored in a file and run using source command. help command prints usage message for all supported commands (or a specific command)

      -

      Shell/batch scripts to run command line HSDB

      - -
        -
      • clhsdbproc.sh -
      • clhsdbproc64.sh -
      • clhsdbwindbg.bat -
      • clhsdbwindbg64.bat -
      -

      Annotated output of CLHSDB help command

      @@ -51,7 +42,7 @@ Available commands:
         dumpilt -a | id dump inline tree for C2 compilation
         dumpreplaydata <address> | -a | <thread_id> [>replay.txt] dump replay data into a file
         echo [ true | false ] turn on/off command echo mode
      -  examine [ address/count ] | [ address,address] show contents of memory from given address
      +  examine { address[/count] | address,address } show contents of memory range
         field [ type [ name fieldtype isStatic offset address ] ] print info about a field of HotSpot type
         findpc address print info about pointer location
         findsym name print address of symbol in the executable or shared library
      @@ -62,12 +53,10 @@ Available commands:
         intConstant [ name [ value ] ] print out hotspot integer constant(s)
         jdis address show bytecode disassembly of a given Method*
         jhisto show Java heap histogram
      -  jseval script evaluate a given string as JavaScript code
      -  jsload file load and evaluate a JavaScript file
         jstack [-v] show Java stack trace of all Java threads. -v is verbose mode
         livenmethods show all live nmethods
         longConstant [ name [ value ] ] print out hotspot long constant(s)s
      -  mem address [ length ] show contents of memory -- also shows closest ELF/COFF symbol if found
      +  mem [ -v ] { address[/count] | address,address } show contents of memory range. -v adds "findpc" info for addresses
         pmap show Solaris pmap-like output
         print expression print given Klass*, Method* or arbitrary address
         printas type expression print given address as given HotSpot type. eg. print JavaThread <address>
      @@ -90,44 +79,11 @@ Available commands:
         vmstructsdump dump hotspot type library in text
         verbose true | false turn on/off verbose mode
         versioncheck [ true | false ] turn on/off debuggee VM version check
      -  whatis address print info about any arbitrary address
      +  whatis address print info about any arbitrary address. alias for findpc command
         where { -a | id } print Java stack trace of given Java thread or all Java threads (-a)
       
       
      -

      JavaScript integration

      - -

      Few CLHSDB commands are already implemented in JavaScript. It is possible to extend CLHSDB command set -by implementing more commands in a JavaScript file and by loading it by jsload command. jseval -command may be used to evaluate arbitrary JavaScript expression from a string. Any JavaScript function -may be exposed as a CLHSDB command by registering it using JavaScript registerCommand -function. This function accepts command name, usage and name of the JavaScript implementation function -as arguments. -

      - -

      Simple CLHSDB command implemented in JavaScript

      - -File: test.js -
      -
      -function helloImpl(name) {
      -    println("hello, " + name);
      -}
      -
      -// register the above JavaScript function as CLHSDB command
      -registerCommand("hello", "hello name", "helloImpl");
      -
      -
      ----------
      - -"test.js" can be loaded in CLHSDB prompt using jsload command using - -
      -
      -hsdb> jsload test.js
      -
      -
      -

      Compilation Replay

      When a java process crashes in compiled method, usually a core file is saved. diff --git a/src/jdk.hotspot.agent/doc/index.html b/src/jdk.hotspot.agent/doc/index.html index fb72fd695811094e7cf1e9a880df79affb6e56ac..9a67ad1bf7735c2aa5d94e27a63a333d660c1183 100644 --- a/src/jdk.hotspot.agent/doc/index.html +++ b/src/jdk.hotspot.agent/doc/index.html @@ -10,224 +10,55 @@ Using HotSpot Serviceability Agent (SA)

      HSDB GUI

      The top-level GUI program using the HotSpot Serviceability Agent APIs is -called HSDB, the "HotSpot Debugger". To run it, type "hsdbproc.sh" -or "hsdbwindbg.bat" or 64-bit variants (on Unix, Windows platforms -respectively). More info. on HSDB GUI are in hsdb.html. +called HSDB, the "HotSpot Debugger". To run it, type "jhsdb hsdb". +More info on HSDB GUI are in hsdb.html. Also +see the "jhsdb" man page.

      SA Modes

      -There are three modes for the SA debugger: +There are three modes for the SA debugger:

        -
      • attaching to a local process, -
      • opening a core file, and -
      • attaching to a remote "debug server". +
      • attaching to a local process +
      • opening a core file +
      • attaching to a remote "debug server"

      -The remote case requires two programs to be running on the remote machine: -the rmiregistry (see the script "start-rmiregistry.sh" in this directory; -run this in the background) and the debug server (see the script -"start-debug-server-proc.sh"), in that order. start-rmiregistry.sh takes no -arguments; start-debug-server-proc.sh (or -windbg.bat) takes as argument -the process ID or the executable and core file names to allow remote debugging -of. +The remote case requires running the debug server on the remote machine. This +is done by running "jhsdb debugd", and also adding arguments specifying the core +file or process to debug. Once this is done you can connect remotely +to the debug server by running various other "jhsdb" subcommands, and specifying +which debug server to connect to. See the "jhsdb" man page for details.

      Command line HSDB

      -There are also command line HSDB variants ("clhsdbproc.sh" or "clhsdbwindbg.bat" -or 64-bit variants). There is also a JavaScript based command line interface -called "jsdbproc.sh" [or "jsdbwindbg.bat" or 64-bit variants]. More details on -command line interfaces can be found in -

        +There is also a command line HSDB variant. It is launched using "jhsdb clhsdb". +More details on the command line interface can be found in the "jhsdb" man page and also in: -

        - -

        Other command line tools

        -

        -The following table lists all SA command line tools. <xxx>windbg.bat -files are for Windows. .sh files are for Solaris. <xxx>64.sh are for -64 bit debugees. +

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -Tool - -Description -
      -dumpflagsproc.sh, -dumpflagsproc64.sh, -dumpflagswindbg.bat -dumpflagswindbg64.bat - -dumps name and value of all -XX JVM command line arguments passed -to debuggee. -
      - -dumpsyspropsproc.sh, -dumpsyspropsproc64.sh, -dumpsyspropswindbg.bat -dumpsyspropswindbg64.bat - -This prints name and value of Java level System properties. -
      - -heapdumpproc.sh, -heapdumpproc64.sh, -heapdumpwindbg.bat -heapdumpwindbg64.bat - -Dumps heap in a file in hprof binary format. -
      - -heapsumproc.sh, -heapsumproc64.sh, -heapsumwindbg.bat -heapsumwindbg64.bat - -Prints summary information on Java heap. -
      -jcoreproc.sh, -jcoreproc64.sh, -jcorewindbg.bat -jcorewindbg64.bat - -This can retrieve .class files from the debuggee. -set the environment variable JCORE_PACKAGES to comman separated list of -packages whose classes have to be retrieved from the core file. -
      -jstackproc.sh, -jstackproc64.sh, -jstackwindbg.bat -jstackwindbg64.bat - -used to get java stack trace for all java threads. -
      -jhistoproc.sh, -jhistoproc64.sh, -jhistowindbg.bat -jhistowindbg64.bat - -used to get object histogram of java heap. -
      -permstatproc.sh, -permstatproc64.sh, -permstatwindbg.bat -permstatwindbg64.bat - -To gather statistics on perm. generation. -
      -pstackproc.sh, -pstackproc64.sh, -pstackwindbg.bat -pstackwindbg64.bat - -This is cross platform mixed mode pstack utility. This works on any (non-java as well) process, core dump. For java process and core dumps, this prints both java and C/C++ frames. -
      -pmapproc.sh, -pmapproc64.sh, -pmapwindbg.bat -pmapwindbg64.bat - -This is cross platform Solaris pmap-like utility. -
      -start-debug-server-proc.sh, -start-debug-server-proc64.sh, -start-debug-server-windbg.bat, -start-debug-server-windbg64.bat, -start-rmiregistry.bat, -start-rmiregistry64.bat, -start-rmiregistry.sh -start-rmiregistry64.sh - -These scripts are used to run SA remotely. -
      - -

      C2 Compilation Replay

      +

      Compilation Replay

      -When a java process crashes in compiled method, usually a core file is saved. -The C2 replay function can reproduce the compiling process in the core. -c2replay.html +When a java process crashes in a compiled method, usually a core file is saved. +The compiler replay function can reproduce the compiling process in the core. +See cireplay.html

      Debugging transported core dumps

      When a core dump is moved from the machine where it was produced to a -difference machine, it may not always be possible for SA to debug the same. -More info. on debugging on transported core dumps is in +different machine, it may not always be possible for SA to debug it. +More info on debugging on transported core dumps is in transported_core.html.

      SA Bugs

      Not all of the possible states of target VMs have been tested (or -supportable) with SA. For example, the SA will probably not work at all -if it freezes the target VM during certain phases of GC. When filing bugs -a pointer to a core file (see gcore(1)) which the SA can not handle well +are supportable) with SA. For example, the SA will probably not work at all +if it freezes the target VM during certain phases of GC. When filing bugs, +a pointer to a core file (see gcore(1)) which the SA can not handle well is best.

      diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java index d02909aaea3f8e717b1a1321d59b08a28c981f95..7693a1493a0da9ec4980e260e8cdc7a50692ac5c 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -364,6 +364,54 @@ public class CommandProcessor { return VM.getVM().getDebugger().parseAddress(addr); } + String fillHexString(Address a, int width) { + String s = "0x0"; + if (a != null) { + s = a.toString(); + } + if (s.length() != width) { + return s.substring(0, 2) + "000000000000000000000".substring(0, width - s.length()) + s.substring(2); + } + return s; + } + + class AddressRange { + private Address start; + private Address end; + AddressRange(Address start, Address end) { + this.start = start; + this.end = end; + } + Address getStart() {return start;} + Address getEnd() {return end;} + } + + // Parses either address[/count] or address,address into address start/end values + AddressRange parseAddressRange(String arg, int formatSize) { + Pattern args1 = Pattern.compile("^(0x[0-9a-f]+)(/([0-9]*))?$"); + Pattern args2 = Pattern.compile("^(0x[0-9a-f]+),(0x[0-9a-f]+)$"); + Matcher m1 = args1.matcher(arg); + Matcher m2 = args2.matcher(arg); + Address start = null; + Address end = null; + + if (m1.matches()) { + start = VM.getVM().getDebugger().parseAddress(m1.group(1)); + int count = 1; + if (m1.group(2) != null) { + count = Integer.parseInt(m1.group(3)); + } + end = start.addOffsetTo(count * formatSize); + return new AddressRange(start, end); + } else if (m2.matches()) { + start = VM.getVM().getDebugger().parseAddress(m2.group(1)); + end = VM.getVM().getDebugger().parseAddress(m2.group(2)); + return new AddressRange(start, end); + } else { + return null; + } + } + private final Command[] commandList = { new Command("reattach", true) { public void doit(Tokens t) { @@ -409,57 +457,32 @@ public class CommandProcessor { } } }, - new Command("examine", "examine [ address/count ] | [ address,address]", false) { - Pattern args1 = Pattern.compile("^(0x[0-9a-f]+)(/([0-9]*)([a-z]*))?$"); - Pattern args2 = Pattern.compile("^(0x[0-9a-f]+),(0x[0-9a-f]+)(/[a-z]*)?$"); - - String fill(Address a, int width) { - String s = "0x0"; - if (a != null) { - s = a.toString(); - } - if (s.length() != width) { - return s.substring(0, 2) + "000000000000000000000".substring(0, width - s.length()) + s.substring(2); - } - return s; - } - + new Command("examine", "examine { address[/count] | address,address }", false) { public void doit(Tokens t) { if (t.countTokens() != 1) { usage(); } else { String arg = t.nextToken(); - Matcher m1 = args1.matcher(arg); - Matcher m2 = args2.matcher(arg); - Address start = null; - Address end = null; int formatSize = (int)VM.getVM().getAddressSize(); - - if (m1.matches()) { - start = VM.getVM().getDebugger().parseAddress(m1.group(1)); - int count = 1; - if (m1.group(2) != null) { - count = Integer.parseInt(m1.group(3)); - } - end = start.addOffsetTo(count * formatSize); - } else if (m2.matches()) { - start = VM.getVM().getDebugger().parseAddress(m2.group(1)); - end = VM.getVM().getDebugger().parseAddress(m2.group(2)); - } else { + AddressRange addressRange = parseAddressRange(arg, formatSize); + if (addressRange == null) { usage(); return; } + Address start = addressRange.getStart(); + Address end = addressRange.getEnd(); + int line = 80; int formatWidth = formatSize * 8 / 4 + 2; - out.print(fill(start, formatWidth)); + out.print(fillHexString(start, formatWidth)); out.print(": "); int width = line - formatWidth - 2; boolean needsPrintln = true; while (start != null && start.lessThan(end)) { Address val = start.getAddressAt(0); - out.print(fill(val, formatWidth)); + out.print(fillHexString(val, formatWidth)); needsPrintln = true; width -= formatWidth; start = start.addOffsetTo(formatSize); @@ -467,7 +490,7 @@ public class CommandProcessor { out.println(); needsPrintln = false; if (start.lessThan(end)) { - out.print(fill(start, formatWidth)); + out.print(fillHexString(start, formatWidth)); out.print(": "); width = line - formatWidth - 2; } @@ -482,6 +505,63 @@ public class CommandProcessor { } } }, + new Command("mem", "mem [-v] { address[/count] | address,address }", false) { + public void doit(Tokens t) { + int formatSize = (int)VM.getVM().getAddressSize(); + boolean verbose = false; + String arg; + + if (t.countTokens() == 2) { + arg = t.nextToken(); + if (arg.equals("-v")) { + verbose = true; + } else { + usage(); + return; + } + } + if (t.countTokens() != 1) { + usage(); + return; + } + + arg = t.nextToken(); + AddressRange addressRange = parseAddressRange(arg, formatSize); + if (addressRange == null) { + usage(); + return; + } + Address start = addressRange.getStart(); + Address end = addressRange.getEnd(); + + if (verbose) { + // Do the equivalent of a findpc on the start address. + PointerLocation loc = PointerFinder.find(start); + loc.printOn(out); + } + + int formatWidth = formatSize * 8 / 4 + 2; + while (start != null && start.lessThan(end)) { + out.print(fillHexString(start, formatWidth)); + out.print(": "); + Address val = start.getAddressAt(0); + out.print(fillHexString(val, formatWidth)); + if (verbose) { + // If we know what this is a pointer to, then print additional information. + PointerLocation loc = PointerFinder.find(val); + if (!loc.isUnknown()) { + out.print(" "); + loc.printOn(out, false, false); + } else { + out.println(); + } + } else { + out.println(); + } + start = start.addOffsetTo(formatSize); + } + } + }, new Command("dumpreplaydata", "dumpreplaydata {
      | -a | }", false) { // This is used to dump replay data from ciInstanceKlass, ciMethodData etc // default file name is replay.txt, also if java crashes in compiler @@ -608,6 +688,18 @@ public class CommandProcessor { } } }, + // "whatis" is just an alias for "findpc". It's kept around for compatiblity reasons. + new Command("whatis", "whatis address", false) { + public void doit(Tokens t) { + if (t.countTokens() != 1) { + usage(); + } else { + Address a = VM.getVM().getDebugger().parseAddress(t.nextToken()); + PointerLocation loc = PointerFinder.find(a); + loc.printOn(out); + } + } + }, new Command("symbol", "symbol address", false) { public void doit(Tokens t) { if (t.countTokens() != 1) { @@ -1579,19 +1671,54 @@ public class CommandProcessor { } } }, + new Command("threadcontext", "threadcontext [-v] { -a | id }", false) { + public void doit(Tokens t) { + boolean verbose = false; + if (t.countTokens() == 2) { + if (t.nextToken().equals("-v")) { + verbose = true; + } else { + usage(); + return; + } + } + if (t.countTokens() != 1) { + usage(); + return; + } + String id = t.nextToken(); + Threads threads = VM.getVM().getThreads(); + boolean all = id.equals("-a"); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + thread.printThreadIDOn(new PrintStream(bos)); + if (all || bos.toString().equals(id)) { + out.format("Thread \"%s\" id=%s Address=%s\n", + thread.getThreadName(), bos.toString(), thread.getAddress()); + thread.printThreadContextOn(out, verbose); + out.println(" "); + if (!all) return; + } + } + if (!all) { + out.println("Couldn't find thread " + id); + } + } + }, new Command("thread", "thread { -a | id }", false) { public void doit(Tokens t) { if (t.countTokens() != 1) { usage(); } else { - String name = t.nextToken(); + String id = t.nextToken(); Threads threads = VM.getVM().getThreads(); - boolean all = name.equals("-a"); + boolean all = id.equals("-a"); for (int i = 0; i < threads.getNumberOfThreads(); i++) { JavaThread thread = threads.getJavaThreadAt(i); ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); - if (all || bos.toString().equals(name)) { + if (all || bos.toString().equals(id)) { out.println("Thread " + bos.toString() + " Address " + thread.getAddress()); thread.printInfoOn(out); out.println(" "); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java index c530cb67b3593b6e26aa613a9d3bfda4a09282c0..4baa00fc000cee9da44e532a4923610aade1c389 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -337,6 +337,15 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { item.setMnemonic(KeyEvent.VK_M); toolsMenu.add(item); + item = createMenuItem("Annotated Memory Viewer", + new ActionListener() { + public void actionPerformed(ActionEvent e) { + showAnnotatedMemoryViewer(); + } + }); + item.setMnemonic(KeyEvent.VK_W); + toolsMenu.add(item); + item = createMenuItem("Monitor Cache Dump", new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -1611,7 +1620,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { } public void showMemoryViewer() { - showPanel("Memory Viewer", new MemoryViewer(agent.getDebugger(), agent.getTypeDataBase().getAddressSize() == 8)); + showPanel("Memory Viewer", new MemoryViewer(agent.getDebugger(), false, agent.getTypeDataBase().getAddressSize() == 8)); + } + + public void showAnnotatedMemoryViewer() { + showPanel("Annotated Memory Viewer", new MemoryViewer(agent.getDebugger(), true, agent.getTypeDataBase().getAddressSize() == 8)); } public void showCommandLineFlags() { diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java index aa021510567ef5a160a11d07b7e7b2239a4218d7..04db854c84d03f2e064e3ee8305a437e19856478 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -390,17 +390,6 @@ public class HotSpotAgent { // Remote mode (client attaching to server) // - // Create and install a security manager - - // FIXME: currently commented out because we were having - // security problems since we're "in the sun.* hierarchy" here. - // Perhaps a permissive policy file would work around this. In - // the long run, will probably have to move into com.sun.*. - - // if (System.getSecurityManager() == null) { - // System.setSecurityManager(new RMISecurityManager()); - // } - connectRemoteDebugger(); } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java index e11e336d436a9ebad4c0e0daf37551a4ca1ffa4c..00adf9c285b6e31eb328ea13ba2bb26f92646180 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -481,6 +481,25 @@ public class JavaThread extends Thread { return access.getLastSP(addr); } + // Print the contents of all registers in the thread's context + public void printThreadContextOn(PrintStream out, boolean verbose){ + ThreadContext tc = getThreadProxy().getContext(); + for (int r = 0; r < tc.getNumRegisters(); r++) { + Address regAddr = tc.getRegisterAsAddress(r); + System.out.format("%s: %s", tc.getRegisterName(r), regAddr); + if (regAddr == null) { + System.out.println(); + } else { + PointerLocation l = PointerFinder.find(regAddr); + if (l.isUnknown()) { + System.out.println(); + } else { + System.out.print(": "); + l.printOn(System.out, false, verbose); + } + } + } + } public void printThreadInfoOn(PrintStream out){ Oop threadOop = this.getThreadObj(); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java index 820ca17ec9743f80e0b36a9620920ad08e839040..677d6e4cedfad06974e8ca14e82c09faedf39174 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java @@ -943,9 +943,13 @@ public class VM { public boolean isSharingEnabled() { if (sharingEnabled == null) { - Flag flag = getCommandLineFlag("UseSharedSpaces"); - sharingEnabled = (flag == null)? Boolean.FALSE : - (flag.getBool()? Boolean.TRUE: Boolean.FALSE); + Address address = VM.getVM().getDebugger().lookup(null, "UseSharedSpaces"); + if (address == null && getOS().equals("win32")) { + // On Win32 symbols are prefixed with the dll name. So look for + // UseSharedSpaces as a symbol in jvm.dll. + address = VM.getVM().getDebugger().lookup(null, "jvm!UseSharedSpaces"); + } + sharingEnabled = address.getJBooleanAt(0); } return sharingEnabled.booleanValue(); } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java index 0944d59fc7154fdc92fc421b34b8e7b51370d023..e544db9e767a64965d84f0ba4b22456f7193f3db 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java @@ -175,7 +175,7 @@ public class BasicTypeDataBase implements TypeDataBase { } // This implementation should be suitably platform-independent; we - // search nearby memory for the vtbl value of the given type. + // search the first word for the vtbl value of the given type. Address vtblAddr = vtblForType(type); @@ -231,12 +231,9 @@ public class BasicTypeDataBase implements TypeDataBase { // switch to this logic but in the interests of stability it will // be separate for the moment. - // Assuming that the base type is truly the first polymorphic type - // then the vtbl for all subclasss should be at several defined - // locations so only those locations will be checked. It's also - // required that the caller knows that the static type is at least - // baseType. See the notes in guessTypeForAddress for the logic of - // the locations searched. + // Assuming that the base type is truly the first polymorphic type, + // then the vtbl for all subclassses should be in the first word of + // the object. Address loc1 = addr.getAddressAt(0); @@ -248,50 +245,25 @@ public class BasicTypeDataBase implements TypeDataBase { } } - Address loc2 = null; - Address loc3 = null; - long offset2 = baseType.getSize(); - // I don't think this should be misaligned under any - // circumstances, but I'm not sure (FIXME: also not sure which - // way to go here, up or down -- assuming down) - offset2 = offset2 - (offset2 % getAddressSize()) - getAddressSize(); - if (offset2 > 0) { - loc2 = addr.getAddressAt(offset2); - } - long offset3 = offset2 - getAddressSize(); - if (offset3 > 0) { - loc3 = addr.getAddressAt(offset3); - } - - Type loc2Match = null; - Type loc3Match = null; for (Iterator iter = getTypes(); iter.hasNext(); ) { Type type = (Type) iter.next(); Type superClass = type; while (superClass != baseType && superClass != null) { superClass = superClass.getSuperclass(); } - if (superClass == null) continue; + if (superClass == null) continue; // type is not a subclass of baseType Address vtblAddr = vtblForType(type); if (vtblAddr == null) { - // This occurs sometimes for intermediate types that are never - // instantiated. + // This occurs sometimes for intermediate types that are never instantiated. if (DEBUG) { System.err.println("null vtbl for " + type); } continue; } - // Prefer loc1 match - if (vtblAddr.equals(loc1)) return type; - if (loc2 != null && loc2Match == null && vtblAddr.equals(loc2)) { - loc2Match = type; - } - if (loc3 != null && loc3Match == null && vtblAddr.equals(loc3)) { - loc3Match = type; + if (vtblAddr.equals(loc1)) { + return type; } } - if (loc2Match != null) return loc2Match; - if (loc3Match != null) return loc3Match; return null; } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MemoryPanel.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MemoryPanel.java index 20408f4add455d9866aee246d622fcde9920f599..76522a6676c19f63bf3107d38c94eced6fb085ad 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MemoryPanel.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MemoryPanel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,9 @@ package sun.jvm.hotspot.ui; import java.awt.*; import java.awt.datatransfer.*; import java.awt.event.*; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.PrintStream; import java.math.*; import java.util.*; import javax.swing.*; @@ -35,9 +37,12 @@ import javax.swing.event.*; import javax.swing.table.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.ui.*; +import sun.jvm.hotspot.utilities.PointerFinder; +import sun.jvm.hotspot.utilities.PointerLocation; public class MemoryPanel extends JPanel { private boolean is64Bit; + private boolean isAnnotated; private Debugger debugger; private int addressSize; private String unmappedAddrString; @@ -78,10 +83,11 @@ public class MemoryPanel extends JPanel { } } - public MemoryPanel(final Debugger debugger, boolean is64Bit) { + public MemoryPanel(final Debugger debugger, boolean isAnnotated, boolean is64Bit) { super(); this.debugger = debugger; this.is64Bit = is64Bit; + this.isAnnotated = isAnnotated; if (is64Bit) { addressSize = 8; unmappedAddrString = "??????????????????"; @@ -98,23 +104,58 @@ public class MemoryPanel extends JPanel { return numVisibleRows; } public int getColumnCount() { - return 2; + return isAnnotated ? 1 : 2; } public Object getValueAt(int row, int column) { - switch (column) { - case 0: return bigIntToHexString(startVal.add(new BigInteger(Integer.toString((row * addressSize))))); - case 1: { - try { - Address addr = bigIntToAddress(startVal.add(new BigInteger(Integer.toString((row * addressSize))))); + // When not annotated, we just display the address followed by its contents in two + // separate columns. When annotated the format is just one column which contains: + //
      : + // For example: + // 0x00007f7eb010c330: 0x00007f7eb6c9dfb0 vtable for os::PlatformMonitor + 0x10 + if (!isAnnotated) { + switch (column) { + case 0: return bigIntToHexString(startVal.add(new BigInteger(Integer.toString((row * addressSize))))); + case 1: { + try { + Address addr = bigIntToAddress(startVal.add(new BigInteger(Integer.toString((row * addressSize))))); + if (addr != null) { + return addressToString(addr.getAddressAt(0)); + } + return unmappedAddrString; + } catch (UnmappedAddressException e) { + return unmappedAddrString; + } + } + default: throw new RuntimeException("Column " + column + " out of bounds"); + } + } else { + switch (column) { + case 0: { + BigInteger bigaddr = startVal.add(new BigInteger(Integer.toString((row * addressSize)))); + Address addr = bigIntToAddress(bigaddr); + + String col1 = bigIntToHexString(bigaddr); + String col2 = unmappedAddrString; + String col3 = ""; + if (addr != null) { - return addressToString(addr.getAddressAt(0)); + try { + col2 = addressToString(addr.getAddressAt(0)); + PointerLocation loc = PointerFinder.find(addr.getAddressAt(0)); + if (!loc.isUnknown()) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + PrintStream tty = new PrintStream(bos); + loc.printOn(tty, false, false); + col3 = bos.toString(); + } + } catch (UnmappedAddressException e) { + } } - return unmappedAddrString; - } catch (UnmappedAddressException e) { - return unmappedAddrString; + + return col1 + ": " + col2 + " " + col3; + } + default: throw new RuntimeException("Column " + column + " out of bounds"); } - } - default: throw new RuntimeException("Column " + column + " out of bounds"); } } public boolean isCellEditable(int row, int col) { @@ -198,6 +239,15 @@ public class MemoryPanel extends JPanel { private void handleImport(JComponent c, String str) { // do whatever you want with the string here try { + // If someone drag-n-dropped a selection from the Annotated Memory Viewer, + // window, it will look like this: + // 0x00007f7eb010c330: 0x00007f7eb6c9dfb0 vtable for os::PlatformMonitor + 0x10 + // We need to grab the second address. + int secondAddrStartIndex = str.indexOf("0x", 2); + if (secondAddrStartIndex != -1) { + str = str.substring(secondAddrStartIndex); + str = str.split("\\s")[0]; + } makeVisible(debugger.parseAddress(str)); clearSelection(); table.clearSelection(); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MemoryViewer.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MemoryViewer.java index f6193a37f1606b9f8928cf50f57f8bd859cb78c8..e475292c29c5b3a22e6fb1e591edba5ea992391c 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MemoryViewer.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MemoryViewer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,9 +33,9 @@ import sun.jvm.hotspot.debugger.*; address. */ public class MemoryViewer extends JPanel { - public MemoryViewer(final Debugger debugger, boolean is64Bit) { + public MemoryViewer(final Debugger debugger, boolean isAnnotated, boolean is64Bit) { super(); - final MemoryPanel memory = new MemoryPanel(debugger, is64Bit); + final MemoryPanel memory = new MemoryPanel(debugger, isAnnotated, is64Bit); memory.setBorder(GraphicsUtilities.newBorder(5)); JPanel addressPanel = new JPanel(); addressPanel.setLayout(new BoxLayout(addressPanel, BoxLayout.X_AXIS)); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java index 90572eefb796ed7cc77a8b31fb2594da8c757915..cd9e8264f28b5c23994fa3a4a9ecaee01fe7355f 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -135,9 +135,17 @@ public class PointerFinder { CodeCache c = VM.getVM().getCodeCache(); if (c.contains(a)) { loc.inCodeCache = true; - loc.blob = c.findBlobUnsafe(a); - if (Assert.ASSERTS_ENABLED) { - Assert.that(loc.blob != null, "Should have found CodeBlob"); + try { + loc.blob = c.findBlobUnsafe(a); + } catch (Exception e) { + // Since we potentially have a random address in the codecache and therefore could + // be dealing with a freed or partialy intialized blob, exceptions are possible. + } + if (loc.blob == null) { + // It's possible that there is no CodeBlob for this address. Let + // PointerLocation deal with it. + loc.inBlobUnknownLocation = true; + return loc; } loc.inBlobCode = loc.blob.codeContains(a); loc.inBlobData = loc.blob.dataContains(a); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java index aa2da619b461d4af254c96eac2cb3a8703abf2d0..a7cfa5de983cc74d5fe855a233f8a4de9fab41f6 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -301,18 +301,25 @@ public class PointerLocation { } else if (isInBlobOops()) { tty.print("oops"); } else { - if (Assert.ASSERTS_ENABLED) { - Assert.that(isInBlobUnknownLocation(), "Should have known location in CodeBlob"); - } - tty.print("unknown location"); + tty.print("unknown CodeCache location"); } - tty.print(" in "); - if (verbose) { - b.printOn(tty); // includes "\n" + if (b == null) { + tty.println(); } else { - tty.println(b.toString()); + tty.print(" in "); + // Since we potentially have a random address in the codecache and therefore could + // be dealing with a freed or partialy intialized blob, exceptions are possible. + // One known case is an NMethod where the method is still null, resulting in an NPE. + try { + if (verbose) { + b.printOn(tty); // includes "\n" + } else { + tty.println(b.toString()); + } + } catch (Exception e) { + tty.println(""); + } } - // FIXME: add more detail } else if (isInStrongGlobalJNIHandles()) { tty.println("In JNI strong global"); diff --git a/src/jdk.hotspot.agent/share/man/jhsdb.1 b/src/jdk.hotspot.agent/share/man/jhsdb.1 index 920c92a0377aec2b8f234263947262aa01af6696..b26c41d876212a408665bee5191365313f4a7f67 100644 --- a/src/jdk.hotspot.agent/share/man/jhsdb.1 +++ b/src/jdk.hotspot.agent/share/man/jhsdb.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JHSDB" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JHSDB" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c b/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c index e821ec2f4938d149ad640737b33c00a57523db60..79394a424d5672077f116425d56da7012251abcf 100644 --- a/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c +++ b/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -300,7 +300,7 @@ bool init_classsharing_workaround(struct ps_prochandle* ph) { jvm_name = lib->name; useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM); if (useSharedSpacesAddr == 0) { - print_debug("can't lookup 'UseSharedSpaces' flag\n"); + print_debug("can't lookup 'UseSharedSpaces' symbol\n"); return false; } @@ -308,7 +308,7 @@ bool init_classsharing_workaround(struct ps_prochandle* ph) { // using equivalent type jboolean to read the value of // UseSharedSpaces which is same as hotspot type "bool". if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) { - print_debug("can't read the value of 'UseSharedSpaces' flag\n"); + print_debug("can't read the value of 'UseSharedSpaces' symbol\n"); return false; } diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/SimpleFileServer.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/SimpleFileServer.java index a08f48567c9420f47e8a80c528661e22ce15fbbc..2952a40b142700a3d03b2a6aa02d0c99ec225f91 100644 --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/SimpleFileServer.java +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/SimpleFileServer.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java index c875a1ab9b497b58730e741e21adf22f33315ec3..ac6fb7be00542f6c9086e4c95613a86fe1cfae82 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java @@ -41,6 +41,9 @@ class FixedLengthInputStream extends LeftOverInputStream { FixedLengthInputStream (ExchangeImpl t, InputStream src, long len) { super (t, src); + if (len < 0) { + throw new IllegalArgumentException("Content-Length: " + len); + } this.remaining = len; } diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java index 8b431645ceb1c1c3740da5986b78bdada049bcd2..4935214c2e15246294d90351bb9834f94ad2fd70 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java @@ -47,6 +47,9 @@ class FixedLengthOutputStream extends FilterOutputStream FixedLengthOutputStream (ExchangeImpl t, OutputStream src, long len) { super (src); + if (len < 0) { + throw new IllegalArgumentException("Content-Length: " + len); + } this.t = t; this.remaining = len; } diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java index 265b5c82718a6ca93a9202a6a366566e441cf05a..92b2f709c3476031622f77bb521a726a2e72913f 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -208,7 +208,9 @@ class Request { "sun.net.httpserver.maxReqHeaders) exceeded, " + ServerConfig.getMaxReqHeaders() + "."); } - + if (k == null) { // Headers disallows null keys, use empty string + k = ""; // instead to represent invalid key + } hdrs.add (k,v); len = 0; } diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java index ec6b99ab8bea06ee6f5b253167f8abdfd622989d..c2ed3e0e9c6cb9a5ff98ec0b74b7bd25c41d65ef 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -521,6 +521,18 @@ class ServerImpl implements TimeSource { public void run () { /* context will be null for new connections */ logger.log(Level.TRACE, "exchange started"); + + if (dispatcherThread == Thread.currentThread()) { + try { + // call selector to process cancelled keys + selector.selectNow(); + } catch (IOException ioe) { + logger.log(Level.DEBUG, "processing of cancelled keys failed: closing"); + closeConnection(connection); + return; + } + } + context = connection.getHttpContext(); boolean newconnection; SSLEngine engine = null; @@ -618,6 +630,11 @@ class ServerImpl implements TimeSource { headerValue = headers.getFirst("Content-Length"); if (headerValue != null) { clen = Long.parseLong(headerValue); + if (clen < 0) { + reject(Code.HTTP_BAD_REQUEST, requestLine, + "Illegal Content-Length value"); + return; + } } if (clen == 0) { requestCompleted(connection); diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java index b1b28446b4d3931ef2c07216ec1ae63d22662e05..e0e9736cad47ef226b666c75410f7f03d2f7125d 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java index c338e4844e6b3d88ee08bac52ae65c1ce3cd7aae..015d1b95244b4deaead56263450f77208c84809c 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or @@ -28,11 +30,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; /** * Programmatic entry point to start the jwebserver tool. - * - *

      This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interface are subject to change or deletion - * without notice. */ public class JWebServer { @@ -51,11 +48,18 @@ public class JWebServer { * or an I/O error occurs, the server is not started and this method invokes * System::exit with an appropriate exit code. * + *

      If the system property "sun.net.httpserver.maxReqTime" has not been + * set by the user, it is set to a value of 5 seconds. This is to prevent + * the server from hanging indefinitely, for example in the case of an HTTPS + * request. + * * @param args the command-line options * @throws NullPointerException if {@code args} is {@code null}, or if there * are any {@code null} values in the {@code args} array */ public static void main(String... args) { + setMaxReqTime(); + int ec = SimpleFileServerImpl.start(new PrintWriter(System.out, true, UTF_8), "jwebserver", args); if (ec != 0) { System.exit(ec); @@ -63,4 +67,13 @@ public class JWebServer { // runs in another non-daemon thread, or -h or -version have been // passed and the main thread has exited normally. } + + public static final String MAXREQTIME_KEY = "sun.net.httpserver.maxReqTime"; + public static final String MAXREQTIME_VAL = "5"; + + private static void setMaxReqTime() { + if (System.getProperty(MAXREQTIME_KEY) == null) { + System.setProperty(MAXREQTIME_KEY, MAXREQTIME_VAL); + } + } } diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/Main.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/Main.java index 9f76be48abdfd39265b9504ca082951091dc2f6f..30535c9296d8d6299ebc840a4b99a73c0d7c4a12 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/Main.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/Main.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or @@ -28,11 +30,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; /** * Programmatic entry point to start "java -m jdk.httpserver". - * - *

      This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interface are subject to change or deletion - * without notice. */ public class Main { @@ -51,11 +48,18 @@ public class Main { * or an I/O error occurs, the server is not started and this method invokes * System::exit with an appropriate exit code. * + *

      If the system property "sun.net.httpserver.maxReqTime" has not been + * set by the user, it is set to a value of 5 seconds. This is to prevent + * the server from hanging indefinitely, for example in the case of an HTTPS + * request. + * * @param args the command-line options * @throws NullPointerException if {@code args} is {@code null}, or if there * are any {@code null} values in the {@code args} array */ public static void main(String... args) { + setMaxReqTime(); + int ec = SimpleFileServerImpl.start(new PrintWriter(System.out, true, UTF_8), "java", args); if (ec != 0) { System.exit(ec); @@ -63,4 +67,13 @@ public class Main { // runs in another non-daemon thread, or -h or -version have been // passed and the main thread has exited normally. } + + public static final String MAXREQTIME_KEY = "sun.net.httpserver.maxReqTime"; + public static final String MAXREQTIME_VAL = "5"; + + private static void setMaxReqTime() { + if (System.getProperty(MAXREQTIME_KEY) == null) { + System.setProperty(MAXREQTIME_KEY, MAXREQTIME_VAL); + } + } } diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/OutputFilter.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/OutputFilter.java index bdbcf2361eea6668528b191ec42919e9a85e20a7..0a4d901303e561a15ffecce60bed5290a4a68692 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/OutputFilter.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/OutputFilter.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/ResourceBundleHelper.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/ResourceBundleHelper.java index 99349fe34748f0d6b4a8c35eb4c4350b375b6566..690722bddb9403047c85e91ee32fa4f425e18b1a 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/ResourceBundleHelper.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/ResourceBundleHelper.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/SimpleFileServerImpl.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/SimpleFileServerImpl.java index 852aae5a83832e3bcb12cf780bb1952c875ff5da..7e97d203b6c4ef7254f58e036587fa8b48a6640a 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/SimpleFileServerImpl.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/SimpleFileServerImpl.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * 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. + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/src/jdk.httpserver/share/man/jwebserver.1 b/src/jdk.httpserver/share/man/jwebserver.1 index c0c1341a0f801cfc66224252faa86220057b3326..4f255c2a74af3b4cd2ed80205ca768ac4137123b 100644 --- a/src/jdk.httpserver/share/man/jwebserver.1 +++ b/src/jdk.httpserver/share/man/jwebserver.1 @@ -1,6 +1,27 @@ +.\" Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +.\" 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. +.\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JWEBSERVER" "1" "2021" "JDK 18\-internal" "JDK Commands" +.TH "JWEBSERVER" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Addressable.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Addressable.java index 39f61e76122446b4b333b332e9176eba7dbcd035..17d417bee519e73a369e35aa60ce5aa923054fdd 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Addressable.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Addressable.java @@ -40,8 +40,7 @@ package jdk.incubator.foreign; public sealed interface Addressable permits MemorySegment, MemoryAddress, NativeSymbol, VaList { /** - * Returns the memory address associated with this addressable. - * @return The memory address associated with this addressable. + * {@return the {@linkplain MemoryAddress memory address} associated with this addressable} */ MemoryAddress address(); } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java index f5f1a6dc31383d97fb407c487e3375a3fe84bdc4..4ba44bd2dc6d2e83d40fce7a6434e9bd22af7a61 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java @@ -55,7 +55,7 @@ import java.util.Optional; * {@linkplain #downcallHandle(FunctionDescriptor) Linking a foreign function} is a process which requires a function descriptor, * a set of memory layouts which, together, specify the signature of the foreign function to be linked, and returns, * when complete, a downcall method handle, that is, a method handle that can be used to invoke the target native function. - * The Java {@link java.lang.invoke.MethodType method type} associated with the returned method handle is + * The Java {@linkplain java.lang.invoke.MethodType method type} associated with the returned method handle is * {@linkplain #downcallType(FunctionDescriptor) derived} from the argument and return layouts in the function descriptor. * More specifically, given each layout {@code L} in the function descriptor, a corresponding carrier {@code C} is inferred, * as described below: @@ -69,7 +69,8 @@ import java.util.Optional; *

    • or, if {@code L} is a {@link GroupLayout}, then {@code C} is set to {@code MemorySegment.class}
    • * *

      - * The downcall method handle type, derived as above, might be decorated by additional leading parameters: + * The downcall method handle type, derived as above, might be decorated by additional leading parameters, + * in the given order if both are present: *

        *
      • If the downcall method handle is created {@linkplain #downcallHandle(FunctionDescriptor) without specifying a native symbol}, * the downcall method handle type features a leading parameter of type {@link NativeSymbol}, from which the @@ -91,7 +92,7 @@ import java.util.Optional; * handle and a function descriptor; in this case, the set of memory layouts in the function descriptor * specify the signature of the function pointer associated with the upcall stub. *

        - * The type of the provided method handle has to match the Java {@link java.lang.invoke.MethodType method type} + * The type of the provided method handle has to match the Java {@linkplain java.lang.invoke.MethodType method type} * associated with the upcall stub, which is derived from the argument and return layouts in the function descriptor. * More specifically, given each layout {@code L} in the function descriptor, a corresponding carrier {@code C} is inferred, as described below: *

          @@ -109,7 +110,7 @@ import java.util.Optional; * *

          System lookup

          * - * This class implements the {@link SymbolLookup} interface; as such clients can {@linkplain #lookup(String) lookup} symbols + * This class implements the {@link SymbolLookup} interface; as such clients can {@linkplain #lookup(String) look up} symbols * in the standard libraries associated with this linker. The set of symbols available for lookup is unspecified, * as it depends on the platform and on the operating system. * @@ -163,7 +164,7 @@ public sealed interface CLinker extends SymbolLookup permits Windowsx64Linker, S } /** - * Lookup a symbol in the standard libraries associated with this linker. + * Look up a symbol in the standard libraries associated with this linker. * The set of symbols available for lookup is unspecified, as it depends on the platform and on the operating system. * @return a symbol in the standard libraries associated with this linker. */ @@ -181,9 +182,9 @@ public sealed interface CLinker extends SymbolLookup permits Windowsx64Linker, S * to allocate structs returned by-value. *

          * Calling this method is equivalent to the following code: -

          {@code
          -    linker.downcallHandle(function).bindTo(symbol);
          -}
          + * {@snippet lang=java : + * linker.downcallHandle(function).bindTo(symbol); + * } * * @param symbol downcall symbol. * @param function the function descriptor. diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/FunctionDescriptor.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/FunctionDescriptor.java index 9c557ec9e9e90c49d045e4922d907b64ed851c0d..6bedfc4c16aaa1aef7ad209400cedaac047536b6 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/FunctionDescriptor.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/FunctionDescriptor.java @@ -54,16 +54,14 @@ public sealed class FunctionDescriptor implements Constable permits FunctionDesc } /** - * Returns the return layout associated with this function. - * @return the return layout. + * {@return the return layout (if any) associated with this function descriptor} */ public Optional returnLayout() { return Optional.ofNullable(resLayout); } /** - * Returns the argument layouts associated with this function. - * @return the argument layouts. + * {@return the argument layouts associated with this function descriptor}. */ public List argumentLayouts() { return argLayouts; @@ -166,8 +164,7 @@ public sealed class FunctionDescriptor implements Constable permits FunctionDesc } /** - * Returns a string representation of this function descriptor. - * @return a string representation of this function descriptor. + * {@return the string representation of this function descriptor} */ @Override public String toString() { @@ -201,8 +198,7 @@ public sealed class FunctionDescriptor implements Constable permits FunctionDesc } /** - * Returns the hash code value for this function descriptor. - * @return the hash code value for this function descriptor. + * {@return the hash code value for this function descriptor} */ @Override public int hashCode() { diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java index d08bb716ae893520e5ba7071c4ce0e9ed931f540..6fc9baad7fff7a9841673ed4949efe7d220ee99c 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java @@ -133,18 +133,14 @@ public final class GroupLayout extends AbstractLayout implements MemoryLayout { } /** - * Is this group layout a struct? - * - * @return true, if this group layout is a struct. + * {@return {@code true}, if this group layout is a struct} */ public boolean isStruct() { return kind == Kind.STRUCT; } /** - * Is this group layout a union? - * - * @return true, if this group layout is a union. + * {@return {@code true}, if this group layout is a union} */ public boolean isUnion() { return kind == Kind.UNION; diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java index ce1a77c41b3e3477597dad3e2b3015b673a5fd13..007464d1691aacbf197f41e7eab9fb64c201da8b 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,14 +29,16 @@ package jdk.incubator.foreign; import jdk.internal.foreign.MemoryAddressImpl; import jdk.internal.reflect.CallerSensitive; +import java.lang.invoke.MethodHandle; import java.nio.ByteOrder; /** - * A memory address models a reference into a memory location. Memory addresses are typically obtained in three ways: + * A memory address models a reference into a memory location. Memory addresses are typically obtained in one of the following ways: *
            *
          • By calling {@link Addressable#address()} on an instance of type {@link Addressable} (e.g. a memory segment);
          • *
          • By invoking a {@linkplain CLinker#downcallHandle(FunctionDescriptor) downcall method handle} which returns a pointer;
          • *
          • By reading an address from memory, e.g. via {@link MemorySegment#get(ValueLayout.OfAddress, long)}.
          • + *
          • By the invocation of an {@linkplain CLinker#upcallStub(MethodHandle, FunctionDescriptor, ResourceScope) upcall stub} which accepts a pointer. *
          * A memory address is backed by a raw machine pointer, expressed as a {@linkplain #toRawLongValue() long value}. * @@ -46,17 +48,17 @@ import java.nio.ByteOrder; * Each dereference method takes a {@linkplain jdk.incubator.foreign.ValueLayout value layout}, which specifies the size, * alignment constraints, byte order as well as the Java type associated with the dereference operation, and an offset. * For instance, to read an int from a segment, using {@link ByteOrder#nativeOrder() default endianness}, the following code can be used: - *
          {@code
          -MemoryAddress address = ...
          -int value = address.get(ValueLayout.JAVA_INT, 0);
          - * }
          + * {@snippet lang=java : + * MemoryAddress address = ... + * int value = address.get(ValueLayout.JAVA_INT, 0); + * } * * If the value to be read is stored in memory using {@link ByteOrder#BIG_ENDIAN big-endian} encoding, the dereference operation * can be expressed as follows: - *
          {@code
          -MemoryAddress address = ...
          -int value = address.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
          - * }
          + * {@snippet lang=java : + * MemoryAddress address = ... + * int value = address.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); + * } * * All the dereference methods in this class are restricted: since * a memory address does not feature temporal nor spatial bounds, the runtime has no way to check the correctness @@ -76,8 +78,7 @@ int value = address.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); public sealed interface MemoryAddress extends Addressable permits MemoryAddressImpl { /** - * Returns the raw long value associated with this memory address. - * @return The raw long value associated with this memory address. + * {@return the raw long value associated with this memory address} */ long toRawLongValue(); @@ -139,8 +140,7 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI boolean equals(Object that); /** - * Returns the hash code value for this address. - * @return the hash code value for this address. + * {@return the hash code value for this address} */ @Override int hashCode(); @@ -172,6 +172,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return a byte value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -190,6 +192,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the byte value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -208,6 +212,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return a boolean value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -226,6 +232,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the boolean value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -244,6 +252,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return a char value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -262,6 +272,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the char value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -280,6 +292,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return a short value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -298,6 +312,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the short value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -316,6 +332,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return an int value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -334,6 +352,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the int value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -352,6 +372,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return a float value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -370,6 +392,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the float value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -388,6 +412,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return a long value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -406,6 +432,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the long value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -424,6 +452,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return a double value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -442,6 +472,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the double value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -460,6 +492,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param offset offset in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + offset}. * @return an address value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -478,6 +512,8 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param offset offset in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + offset}. * @param value the address value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -496,6 +532,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param index index in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @return a char value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -514,6 +553,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param index index in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @param value the char value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -532,6 +574,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param index index in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @return a short value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -550,6 +595,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param index index in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @param value the short value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -568,6 +616,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param index index in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @return an int value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -586,6 +637,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param index index in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @param value the int value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -604,6 +658,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param index index in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @return a float value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -622,6 +679,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param index index in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @param value the float value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -640,6 +700,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param index index in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @return a long value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -658,6 +721,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param index index in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @param value the long value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -676,6 +742,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param index index in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @return a double value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -694,6 +763,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param index index in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @param value the double value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -712,6 +784,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be read. * @param index index in bytes (relative to this address). The final address of this read operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @return an address value read from this address. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. @@ -730,6 +805,9 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI * @param layout the layout of the memory region to be written. * @param index index in bytes (relative to this address). The final address of this write operation can be expressed as {@code toRowLongValue() + (index * layout.byteSize())}. * @param value the address value to be written. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or * {@code ALL-UNNAMED} in case {@code M} is an unnamed module. diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java index f4489ecd601c9d813819a3336323c76989a991f5..f24f5c7bc6ea3b96169eaf6c3318e3690b6e4761 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,17 +47,17 @@ import java.util.Objects; * to the segment, at which dereference should occur. *

          * As an example, consider the memory layout expressed by a {@link GroupLayout} instance constructed as follows: - *

          {@code
          -GroupLayout seq = MemoryLayout.structLayout(
          -        MemoryLayout.paddingLayout(32),
          -        ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
          -);
          - * }
          + * {@snippet lang=java : + * GroupLayout seq = MemoryLayout.structLayout( + * MemoryLayout.paddingLayout(32), + * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value") + * ); + * } * To access the member layout named {@code value}, we can construct a memory access var handle as follows: - *
          {@code
          -VarHandle handle = MemoryHandles.varHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int
          -handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
          - * }
          + * {@snippet lang=java : + * VarHandle handle = MemoryHandles.varHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int + * handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int + * } * *

          Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null} * elements to a method in this class causes a {@link NullPointerException NullPointerException} to be thrown.

          @@ -177,13 +177,13 @@ public final class MemoryHandles { * example, it is often convenient to model an unsigned short as a * Java {@code int} to avoid dealing with negative values, which would be * the case if modeled as a Java {@code short}. This is illustrated in the following example: - *
          {@code
          -    MemorySegment segment = MemorySegment.allocateNative(2, ResourceScope.newImplicitScope());
          -    VarHandle SHORT_VH = ValueLayout.JAVA_SHORT.varHandle();
          -    VarHandle INT_VH = MemoryHandles.asUnsigned(SHORT_VH, int.class);
          -    SHORT_VH.set(segment, (short)-1);
          -    INT_VH.get(segment); // returns 65535
          -     * }
          + * {@snippet lang=java : + * MemorySegment segment = MemorySegment.allocateNative(2, ResourceScope.newImplicitScope()); + * VarHandle SHORT_VH = ValueLayout.JAVA_SHORT.varHandle(); + * VarHandle INT_VH = MemoryHandles.asUnsigned(SHORT_VH, int.class); + * SHORT_VH.set(segment, (short)-1); + * INT_VH.get(segment); // returns 65535 + * } *

          * When calling e.g. {@link VarHandle#set(Object...)} on the resulting var * handle, the incoming value (of type {@code adaptedType}) is converted by a diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java index 8319f22c2ab04ad87826cb8124bdecb870bf9fef..991897c367d12fd9d2d3e3aa6ccc739678151e7a 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,24 +58,24 @@ import java.util.stream.Stream; *

          * For instance, consider the following struct declaration in C: * - *

          {@code
          - typedef struct {
          -     char kind;
          -     int value;
          - } TaggedValues[5];
          - * }
          + * {@snippet lang=c : + * typedef struct { + * char kind; + * int value; + * } TaggedValues[5]; + * } * * The above declaration can be modelled using a layout object, as follows: * - *
          {@code
          -SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5,
          -    MemoryLayout.structLayout(
          -        ValueLayout.JAVA_BYTE.withName("kind"),
          -        MemoryLayout.paddingLayout(24),
          -        ValueLayout.JAVA_INT.withName("value")
          -    )
          -).withName("TaggedValues");
          - * }
          + * {@snippet lang=java : + * SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5, + * MemoryLayout.structLayout( + * ValueLayout.JAVA_BYTE.withName("kind"), + * MemoryLayout.paddingLayout(24), + * ValueLayout.JAVA_INT.withName("value") + * ) + * ).withName("TaggedValues"); + * } *

          * All implementations of this interface must be value-based; * programmers should treat instances that are {@linkplain #equals(Object) equal} as interchangeable and should not @@ -129,42 +129,42 @@ SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5, * Such layout paths can be constructed programmatically using the methods in this class. * For instance, given the {@code taggedValues} layout instance constructed as above, we can obtain the offset, * in bits, of the member layout named value in the first sequence element, as follows: - *

          {@code
          -long valueOffset = taggedValues.bitOffset(PathElement.sequenceElement(0),
          -                                          PathElement.groupElement("value")); // yields 32
          - * }
          + * {@snippet lang=java : + * long valueOffset = taggedValues.bitOffset(PathElement.sequenceElement(0), + * PathElement.groupElement("value")); // yields 32 + * } * * Similarly, we can select the member layout named {@code value}, as follows: - *
          {@code
          -MemoryLayout value = taggedValues.select(PathElement.sequenceElement(),
          -                                         PathElement.groupElement("value"));
          - * }
          + * {@snippet lang=java : + * MemoryLayout value = taggedValues.select(PathElement.sequenceElement(), + * PathElement.groupElement("value")); + * } * * And, we can also replace the layout named {@code value} with another layout, as follows: - *
          {@code
          -MemoryLayout taggedValuesWithHole = taggedValues.map(l -> MemoryLayout.paddingLayout(32),
          -                                            PathElement.sequenceElement(), PathElement.groupElement("value"));
          - * }
          + * {@snippet lang=java : + * MemoryLayout taggedValuesWithHole = taggedValues.map(l -> MemoryLayout.paddingLayout(32), + * PathElement.sequenceElement(), PathElement.groupElement("value")); + * } * * That is, the above declaration is identical to the following, more verbose one: - *
          {@code
          -MemoryLayout taggedValuesWithHole = MemoryLayout.sequenceLayout(5,
          -    MemoryLayout.structLayout(
          -        ValueLayout.JAVA_BYTE.withName("kind"),
          -        MemoryLayout.paddingLayout(32),
          -        MemoryLayout.paddingLayout(32)
          -));
          - * }
          + * {@snippet lang=java : + * MemoryLayout taggedValuesWithHole = MemoryLayout.sequenceLayout(5, + * MemoryLayout.structLayout( + * ValueLayout.JAVA_BYTE.withName("kind"), + * MemoryLayout.paddingLayout(32), + * MemoryLayout.paddingLayout(32) + * )); + * } * * Layout paths can feature one or more free dimensions. For instance, a layout path traversing * an unspecified sequence element (that is, where one of the path component was obtained with the * {@link PathElement#sequenceElement()} method) features an additional free dimension, which will have to be bound at runtime. * This is important when obtaining memory access var handle from layouts, as in the following code: * - *
          {@code
          -VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(),
          -                                               PathElement.groupElement("value"));
          - * }
          + * {@snippet lang=java : + * VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(), + * PathElement.groupElement("value")); + * } * * Since the layout path constructed in the above example features exactly one free dimension (as it doesn't specify * which member layout named {@code value} should be selected from the enclosing sequence layout), @@ -177,12 +177,12 @@ VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(), * offsets of elements of a sequence at different indices, by supplying these indices when invoking the method handle. * For instance: * - *
          {@code
          -MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(),
          -                                                          PathElement.groupElement("kind"));
          -long offset1 = (long) offsetHandle.invokeExact(1L); // 8
          -long offset2 = (long) offsetHandle.invokeExact(2L); // 16
          - * }
          + * {@snippet lang=java : + * MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(), + * PathElement.groupElement("kind")); + * long offset1 = (long) offsetHandle.invokeExact(1L); // 8 + * long offset2 = (long) offsetHandle.invokeExact(2L); // 16 + * } * *

          Layout attributes

          * @@ -195,18 +195,15 @@ long offset2 = (long) offsetHandle.invokeExact(2L); // 16 public sealed interface MemoryLayout extends Constable permits AbstractLayout, SequenceLayout, GroupLayout, PaddingLayout, ValueLayout { /** - * Returns an {@link Optional} containing the nominal descriptor for this + * {@return an {@link Optional} containing the nominal descriptor for this * layout, if one can be constructed, or an empty {@link Optional} - * if one cannot be constructed. - * - * @return An {@link Optional} containing the resulting nominal descriptor, - * or an empty {@link Optional} if one cannot be constructed. + * if one cannot be constructed} */ @Override Optional> describeConstable(); /** - * Does this layout have a specified size? A layout does not have a specified size if it is (or contains) a sequence layout whose + * Returns {@code true} if this layout has a specified size. A layout does not have a specified size if it is (or contains) a sequence layout whose * size is unspecified (see {@link SequenceLayout#elementCount()}). * * Value layouts (see {@link ValueLayout}) and padding layouts (see {@link MemoryLayout#paddingLayout(long)}) @@ -217,26 +214,20 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S boolean hasSize(); /** - * Computes the layout size, in bits. - * - * @return the layout size, in bits. + * {@return the layout size, in bits} * @throws UnsupportedOperationException if the layout is, or contains, a sequence layout with unspecified size (see {@link SequenceLayout}). */ long bitSize(); /** - * Computes the layout size, in bytes. - * - * @return the layout size, in bytes. + * {@return the layout size, in bytes} * @throws UnsupportedOperationException if the layout is, or contains, a sequence layout with unspecified size (see {@link SequenceLayout}), * or if {@code bitSize()} is not a multiple of 8. */ long byteSize(); /** - * Return the name (if any) associated with this layout. - * - * @return the layout name (if any). + * {@return the name (if any) associated with this layout} * @see MemoryLayout#withName(String) */ Optional name(); @@ -330,7 +321,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S *

          The final offset returned by the method handle is computed as follows: * *

          {@code
          -    offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
          +     * offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
                * }
          * * where {@code x_1}, {@code x_2}, ... {@code x_n} are dynamic values provided as {@code long} @@ -381,8 +372,8 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S *

          The final offset returned by the method handle is computed as follows: * *

          {@code
          -    bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
          -    offset = bitOffset / 8
          +     * bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
          +     * offset = bitOffset / 8
                * }
          * * where {@code x_1}, {@code x_2}, ... {@code x_n} are dynamic values provided as {@code long} @@ -413,7 +404,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S * The final memory location accessed by the returned memory access var handle can be computed as follows: * *
          {@code
          -    address = base + offset
          +     * address = base + offset
                * }
          * * where {@code base} denotes the base address expressed by the {@link MemorySegment} access coordinate @@ -421,7 +412,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S * can be expressed in the following form: * *
          {@code
          -    offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
          +     * offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
                * }
          * * where {@code x_1}, {@code x_2}, ... {@code x_n} are dynamic values provided as {@code long} @@ -458,8 +449,8 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S *

          The offset of the returned segment is computed as follows: * *

          {@code
          -    bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
          -    offset = bitOffset / 8
          +     * bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
          +     * offset = bitOffset / 8
                * }
          * * where {@code x_1}, {@code x_2}, ... {@code x_n} are dynamic values provided as {@code long} @@ -468,9 +459,9 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S * the layout path. * *

          After the offset is computed, the returned segment is created as if by calling: - *

          {@code
          -    segment.asSlice(offset, layout.byteSize());
          -     * }
          + * {@snippet lang=java : + * segment.asSlice(offset, layout.byteSize()); + * } * * where {@code segment} is the segment to be sliced, and where {@code layout} is the layout selected by the given * layout path, as per {@link MemoryLayout#select(PathElement...)}. @@ -534,8 +525,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S } /** - * Is this a {@linkplain #paddingLayout(long) padding layout} ? - * @return true, if this layout is a padding layout. + * {@return true, if this layout is a padding layout} */ boolean isPadding(); @@ -599,7 +589,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S * with this path is bound by an index {@code I}, the resulting accessed offset can be obtained with the following * formula: *
          {@code
          -E * (S + I * F)
          +         * E * (S + I * F)
                    * }
          * where {@code E} is the size (in bytes) of the sequence element layout. * @@ -651,16 +641,12 @@ E * (S + I * F) boolean equals(Object that); /** - * Returns the hash code value for this layout. - * - * @return the hash code value for this layout. + * {@return the hash code value for this layout} */ int hashCode(); /** - * Returns a string representation of this layout. - * - * @return a string representation of this layout. + * {@return the string representation of this layout} */ @Override String toString(); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java index cd0f11818636b91a0639addfd61e3b6c18ec17c4..a450853073478dbc93d2ba1604c4396d0d51e348 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java @@ -56,7 +56,7 @@ import java.util.stream.Stream; * A memory segment models a contiguous region of memory. A memory segment is associated with both spatial * and temporal bounds (e.g. a {@link ResourceScope}). Spatial bounds ensure that memory access operations on a memory segment cannot affect a memory location * which falls outside the boundaries of the memory segment being accessed. Temporal bounds ensure that memory access - * operations on a segment cannot occur after the resource scope associated with a memory segment has been closed (see {@link ResourceScope#close()}). + * operations on a segment cannot occur after the resource scope associated with a memory segment has been closed (see {@link ResourceScope#close()}). *

          * All implementations of this interface must be value-based; * programmers should treat instances that are {@linkplain Object#equals(Object) equal} as interchangeable and should not @@ -119,17 +119,17 @@ import java.util.stream.Stream; * Each dereference method takes a {@linkplain jdk.incubator.foreign.ValueLayout value layout}, which specifies the size, * alignment constraints, byte order as well as the Java type associated with the dereference operation, and an offset. * For instance, to read an int from a segment, using {@link ByteOrder#nativeOrder() default endianness}, the following code can be used: - *

          {@code
          -MemorySegment segment = ...
          -int value = segment.get(ValueLayout.JAVA_INT, 0);
          - * }
          + * {@snippet lang=java : + * MemorySegment segment = ... + * int value = segment.get(ValueLayout.JAVA_INT, 0); + * } * * If the value to be read is stored in memory using {@link ByteOrder#BIG_ENDIAN big-endian} encoding, the dereference operation * can be expressed as follows: - *
          {@code
          -MemorySegment segment = ...
          -int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
          - * }
          + * {@snippet lang=java : + * MemorySegment segment = ... + * int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); + * } * * For more complex dereference operations (e.g. structured memory access), clients can obtain a memory access var handle, * that is, a var handle that accepts a segment and, optionally, one or more additional {@code long} coordinates. Memory @@ -139,33 +139,83 @@ int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); * {@linkplain MemoryHandles#varHandle(ValueLayout) value layout}, and then adapt it using the var handle combinator * functions defined in the {@link MemoryHandles} class. * + *

          Alignment

          + * + * When dereferencing a memory segment using a layout, the runtime must check that the segment address being dereferenced + * matches the layout's {@linkplain MemoryLayout#byteAlignment() alignment constraints}. If the segment being + * dereferenced is a native segment, then it has a concrete {@linkplain #address() base address}, which can + * be used to perform the alignment check. The pseudo-function below demonstrates this: + * + *
          {@code
          +boolean isAligned(MemorySegment segment, long offset, MemoryLayout layout) {
          +   return ((segment.address().toRawLongValue() + offset) % layout.byteAlignment()) == 0
          +}
          + * }
          + * + * If, however, the segment being dereferenced is a heap segment, the above function will not work: a heap + * segment's base address is virtualized and, as such, cannot be used to construct an alignment check. Instead, + * heap segments are assumed to produce addresses which are never more aligned than the element size of the Java array from which + * they have originated from, as shown in the following table: + * + *
          + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
          Array type of an array backing a segment and its address alignment
          Array typeAlignment
          {@code boolean[]}{@code 1}
          {@code byte[]}{@code 1}
          {@code char[]}{@code 2}
          {@code short[]}{@code 2}
          {@code int[]}{@code 4}
          {@code float[]}{@code 4}
          {@code long[]}{@code 8}
          {@code double[]}{@code 8}
          + * + * Note that the above definition is conservative: it might be possible, for instance, that a heap segment + * constructed from a {@code byte[]} might have a subset of addresses {@code S} which happen to be 8-byte aligned. But determining + * which segment addresses belong to {@code S} requires reasoning about details which are ultimately implementation-dependent. + * *

          Lifecycle and confinement

          * * Memory segments are associated with a resource scope (see {@link ResourceScope}), which can be accessed using * the {@link #scope()} method. As for all resources associated with a resource scope, a segment cannot be * accessed after its corresponding scope has been closed. For instance, the following code will result in an * exception: - *
          {@code
          -MemorySegment segment = null;
          -try (ResourceScope scope = ResourceScope.newConfinedScope()) {
          -    segment = MemorySegment.allocateNative(8, scope);
          -}
          -segment.get(ValueLayout.JAVA_LONG, 0); // already closed!
          - * }
          + * {@snippet lang=java : + * MemorySegment segment = null; + * try (ResourceScope scope = ResourceScope.newConfinedScope()) { + * segment = MemorySegment.allocateNative(8, scope); + * } + * segment.get(ValueLayout.JAVA_LONG, 0); // already closed! + * } * Additionally, access to a memory segment is subject to the thread-confinement checks enforced by the owning scope; that is, * if the segment is associated with a shared scope, it can be accessed by multiple threads; if it is associated with a confined * scope, it can only be accessed by the thread which owns the scope. *

          * Heap and buffer segments are always associated with a global, shared scope. This scope cannot be closed, - * and can be considered as always alive. + * and segments associated with it can be considered as always alive. * *

          Memory segment views

          * * Memory segments support views. For instance, it is possible to create an immutable view of a memory segment, as follows: - *
          {@code
          -MemorySegment segment = ...
          -MemorySegment roSegment = segment.asReadOnly();
          - * }
          + * {@snippet lang=java : + * MemorySegment segment = ... + * MemorySegment roSegment = segment.asReadOnly(); + * } * It is also possible to create views whose spatial bounds are stricter than the ones of the original segment * (see {@link MemorySegment#asSlice(long, long)}). *

          @@ -184,15 +234,15 @@ MemorySegment roSegment = segment.asReadOnly(); * (to do this, the segment has to be associated with a shared scope). The following code can be used to sum all int * values in a memory segment in parallel: * - *

          {@code
          -try (ResourceScope scope = ResourceScope.newSharedScope()) {
          -    SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT);
          -    MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope);
          -    int sum = segment.elements(ValueLayout.JAVA_INT).parallel()
          -                           .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0))
          -                           .sum();
          -}
          - * }
          + * {@snippet lang=java : + * try (ResourceScope scope = ResourceScope.newSharedScope()) { + * SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT); + * MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope); + * int sum = segment.elements(ValueLayout.JAVA_INT).parallel() + * .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0)) + * .sum(); + * } + * } * * @implSpec * Implementations of this interface are immutable, thread-safe and value-based. @@ -200,11 +250,10 @@ try (ResourceScope scope = ResourceScope.newSharedScope()) { public sealed interface MemorySegment extends Addressable permits AbstractMemorySegmentImpl { /** - * The base memory address associated with this native memory segment. + * {@return the base memory address associated with this native memory segment} * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. - * @return The base memory address. */ @Override MemoryAddress address(); @@ -216,43 +265,45 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory *

          * The returned spliterator splits this segment according to the specified element layout; that is, * if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving - * approximately {@code S/N/2} elements (depending on whether N is even or not), where {@code S} is the size of - * this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that feature the same - * scope as this given segment. + * approximately {@code S/N} elements (depending on whether N is even or not), where {@code S} is the size of + * this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that + * are associated with the same scope as this segment. *

          - * The returned spliterator effectively allows to slice this segment into disjoint sub-segments, which can then - * be processed in parallel by multiple threads. + * The returned spliterator effectively allows to slice this segment into disjoint {@linkplain #asSlice(long, long) slices}, + * which can then be processed in parallel by multiple threads. * * @param elementLayout the layout to be used for splitting. * @return the element spliterator for this segment * @throws IllegalArgumentException if the {@code elementLayout} size is zero, or the segment size modulo the - * {@code elementLayout} size is greater than zero. + * {@code elementLayout} size is greater than zero, if this segment is + * incompatible with the alignment constraints in the provided layout, + * or if the {@code elementLayout} alignment is greater than its size. */ Spliterator spliterator(MemoryLayout elementLayout); /** * Returns a sequential {@code Stream} over disjoint slices (whose size matches that of the specified layout) * in this segment. Calling this method is equivalent to the following code: - *

          {@code
          -    StreamSupport.stream(segment.spliterator(elementLayout), false);
          -     * }
          + * {@snippet lang=java : + * StreamSupport.stream(segment.spliterator(elementLayout), false); + * } * * @param elementLayout the layout to be used for splitting. * @return a sequential {@code Stream} over disjoint slices in this segment. * @throws IllegalArgumentException if the {@code elementLayout} size is zero, or the segment size modulo the - * {@code elementLayout} size is greater than zero. + * {@code elementLayout} size is greater than zero, if this segment is + * incompatible with the alignment constraints in the provided layout, + * or if the {@code elementLayout} alignment is greater than its size. */ Stream elements(MemoryLayout elementLayout); /** - * Returns the resource scope associated with this memory segment. - * @return the resource scope associated with this memory segment. + * {@return the resource scope associated with this memory segment} */ ResourceScope scope(); /** - * The size (in bytes) of this memory segment. - * @return The size (in bytes) of this memory segment. + * {@return the size (in bytes) of this memory segment} */ long byteSize(); @@ -274,9 +325,9 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory * and whose new size is computed by subtracting the specified offset from this segment size. *

          * Equivalent to the following code: - *

          {@code
          -    asSlice(offset, byteSize() - offset);
          -     * }
          + * {@snippet lang=java : + * asSlice(offset, byteSize() - offset); + * } * * @see #asSlice(long, long) * @@ -289,8 +340,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory } /** - * Is this segment read-only? - * @return {@code true}, if this segment is read-only. + * {@return {@code true}, if this segment is read-only} * @see #asReadOnly() */ boolean isReadOnly(); @@ -304,7 +354,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory MemorySegment asReadOnly(); /** - * Is this a native segment? Returns true if this segment is a native memory segment, + * Returns {@code true} if this segment is a native segment. A native memory segment is * created using the {@link #allocateNative(long, ResourceScope)} (and related) factory, or a buffer segment * derived from a direct {@link java.nio.ByteBuffer} using the {@link #ofByteBuffer(ByteBuffer)} factory, * or if this is a {@linkplain #isMapped() mapped} segment. @@ -313,7 +363,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory boolean isNative(); /** - * Is this a mapped segment? Returns true if this segment is a mapped memory segment, + * Returns {@code true} if this segment is a mapped segment. A mapped memory segment is * created using the {@link #mapFile(Path, long, long, FileChannel.MapMode, ResourceScope)} factory, or a buffer segment * derived from a {@link java.nio.MappedByteBuffer} using the {@link #ofByteBuffer(ByteBuffer)} factory. * @return {@code true} if this segment is a mapped segment. @@ -343,9 +393,9 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory * a negative or positive value. For instance, if both segments are native * segments, the resulting offset can be computed as follows: * - *
          {@code
          +     * {@snippet lang=java :
                * other.baseAddress().toRawLongValue() - segment.baseAddress().toRawLongValue()
          -     * }
          + * } * * If the segments share the same base address, {@code 0} is returned. If * {@code other} is a slice of this segment, the offset is always @@ -362,13 +412,13 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory * More specifically, the given value is filled into each address of this * segment. Equivalent to (but likely more efficient than) the following code: * - *
          {@code
          -byteHandle = MemoryLayout.ofSequence(ValueLayout.JAVA_BYTE)
          -         .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement());
          -for (long l = 0; l < segment.byteSize(); l++) {
          -     byteHandle.set(segment.address(), l, value);
          -}
          -     * }
          + * {@snippet lang=java : + * byteHandle = MemoryLayout.ofSequence(ValueLayout.JAVA_BYTE) + * .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement()); + * for (long l = 0; l < segment.byteSize(); l++) { + * byteHandle.set(segment.address(), l, value); + * } + * } * * without any regard or guarantees on the ordering of particular memory * elements being set. @@ -389,9 +439,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * at offset {@code 0} through {@code src.byteSize() - 1}. *

          * Calling this method is equivalent to the following code: - *

          {@code
          -    MemorySegment.copy(src, 0, this, 0, src.byteSize);
          -     * }
          + * {@snippet lang=java : + * MemorySegment.copy(src, 0, this, 0, src.byteSize); + * } * @param src the source segment. * @throws IndexOutOfBoundsException if {@code src.byteSize() > this.byteSize()}. * @throws IllegalStateException if either the scope associated with the source segment or the scope associated @@ -430,7 +480,7 @@ for (long l = 0; l < segment.byteSize(); l++) { long mismatch(MemorySegment other); /** - * Tells whether the contents of this mapped segment is resident in physical + * Determines whether the contents of this mapped segment is resident in physical * memory. * *

          A return value of {@code true} implies that it is highly likely @@ -679,7 +729,7 @@ for (long l = 0; l < segment.byteSize(); l++) { /** * Creates a new array memory segment that models the memory associated with a given heap-allocated byte array. - * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope. + * The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -690,7 +740,7 @@ for (long l = 0; l < segment.byteSize(); l++) { /** * Creates a new array memory segment that models the memory associated with a given heap-allocated char array. - * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope. + * The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -701,7 +751,7 @@ for (long l = 0; l < segment.byteSize(); l++) { /** * Creates a new array memory segment that models the memory associated with a given heap-allocated short array. - * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope. + * The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -712,7 +762,7 @@ for (long l = 0; l < segment.byteSize(); l++) { /** * Creates a new array memory segment that models the memory associated with a given heap-allocated int array. - * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope. + * The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -723,7 +773,7 @@ for (long l = 0; l < segment.byteSize(); l++) { /** * Creates a new array memory segment that models the memory associated with a given heap-allocated float array. - * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope. + * The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -734,7 +784,7 @@ for (long l = 0; l < segment.byteSize(); l++) { /** * Creates a new array memory segment that models the memory associated with a given heap-allocated long array. - * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope. + * The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -745,7 +795,7 @@ for (long l = 0; l < segment.byteSize(); l++) { /** * Creates a new array memory segment that models the memory associated with a given heap-allocated double array. - * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope. + * The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope. * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -801,9 +851,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * when the segment is no longer in use. Failure to do so will result in off-heap memory leaks. *

          * This is equivalent to the following code: - *

          {@code
          -    allocateNative(layout.bytesSize(), layout.bytesAlignment(), scope);
          -     * }
          + * {@snippet lang=java : + * allocateNative(layout.bytesSize(), layout.bytesAlignment(), scope); + * } *

          * The block of off-heap memory associated with the returned native memory segment is initialized to zero. * @@ -826,9 +876,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * when the segment is no longer in use. Failure to do so will result in off-heap memory leaks. *

          * This is equivalent to the following code: - *

          {@code
          -    allocateNative(bytesSize, 1, scope);
          -     * }
          + * {@snippet lang=java : + * allocateNative(bytesSize, 1, scope); + * } *

          * The block of off-heap memory associated with the returned native memory segment is initialized to zero. * @@ -935,9 +985,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * For example, this may occur if the same file is {@linkplain MemorySegment#mapFile mapped} to two segments. *

          * Calling this method is equivalent to the following code: - *

          {@code
          -    MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
          -     * }
          + * {@snippet lang=java : + * MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes); + * } * @param srcSegment the source segment. * @param srcOffset the starting offset, in bytes, of the source segment. * @param dstSegment the destination segment. @@ -982,9 +1032,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param dstElementLayout the element layout associated with the destination segment. * @param dstOffset the starting offset, in bytes, of the destination segment. * @param elementCount the number of elements to be copied. - * @throws IllegalArgumentException if the element layouts have different sizes, if the source offset is incompatible - * with the alignment constraints in the source element layout, or if the destination offset is incompatible with the - * alignment constraints in the destination element layout. + * @throws IllegalArgumentException if the element layouts have different sizes, if the source (resp. destination) segment/offset are + * incompatible with the alignment constraints in the source + * (resp. destination) element layout, or if the source (resp. destination) element layout alignment is greater than its size. * @throws IllegalStateException if either the scope associated with the source segment or the scope associated * with the destination segment have been already closed, or if access occurs from a thread other than the thread * owning either scopes. @@ -1003,13 +1053,15 @@ for (long l = 0; l < segment.byteSize(); l++) { AbstractMemorySegmentImpl srcImpl = (AbstractMemorySegmentImpl)srcSegment; AbstractMemorySegmentImpl dstImpl = (AbstractMemorySegmentImpl)dstSegment; if (srcElementLayout.byteSize() != dstElementLayout.byteSize()) { - throw new IllegalArgumentException("Source and destination layouts must have same sizes"); + throw new IllegalArgumentException("Source and destination layouts must have same size"); } - if (srcOffset % srcElementLayout.byteAlignment() != 0) { + Utils.checkElementAlignment(srcElementLayout, "Source layout alignment greater than its size"); + Utils.checkElementAlignment(dstElementLayout, "Destination layout alignment greater than its size"); + if (!srcImpl.isAlignedForElement(srcOffset, srcElementLayout)) { throw new IllegalArgumentException("Source segment incompatible with alignment constraints"); } - if (dstOffset % dstElementLayout.byteAlignment() != 0) { - throw new IllegalArgumentException("Target segment incompatible with alignment constraints"); + if (!dstImpl.isAlignedForElement(dstOffset, dstElementLayout)) { + throw new IllegalArgumentException("Destination segment incompatible with alignment constraints"); } long size = elementCount * srcElementLayout.byteSize(); srcImpl.checkAccess(srcOffset, size, true); @@ -1034,6 +1086,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a byte value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1051,6 +1105,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the byte value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1069,6 +1125,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a boolean value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1086,6 +1144,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the boolean value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1104,6 +1164,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a char value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1121,6 +1183,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the char value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1139,6 +1203,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a short value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1156,6 +1222,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the short value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1174,6 +1242,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return an int value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1191,6 +1261,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the int value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1209,6 +1281,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a float value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1226,6 +1300,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the float value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1244,6 +1320,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a long value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1261,6 +1339,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the long value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1279,6 +1359,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a double value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1296,6 +1378,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the double value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1314,6 +1398,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return an address value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @@ -1331,6 +1417,8 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the address value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. @@ -1349,11 +1437,15 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a char value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @ForceInline default char getAtIndex(ValueLayout.OfChar layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return (char)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize())); } @@ -1366,12 +1458,16 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the char value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. */ @ForceInline default void setAtIndex(ValueLayout.OfChar layout, long index, char value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value); } @@ -1384,11 +1480,15 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a short value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @ForceInline default short getAtIndex(ValueLayout.OfShort layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return (short)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize())); } @@ -1401,12 +1501,16 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the short value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. */ @ForceInline default void setAtIndex(ValueLayout.OfShort layout, long index, short value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value); } @@ -1419,11 +1523,15 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return an int value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @ForceInline default int getAtIndex(ValueLayout.OfInt layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return (int)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize())); } @@ -1436,12 +1544,16 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the int value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. */ @ForceInline default void setAtIndex(ValueLayout.OfInt layout, long index, int value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value); } @@ -1454,11 +1566,15 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a float value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @ForceInline default float getAtIndex(ValueLayout.OfFloat layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return (float)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize())); } @@ -1471,12 +1587,16 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the float value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. */ @ForceInline default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value); } @@ -1489,11 +1609,15 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a long value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @ForceInline default long getAtIndex(ValueLayout.OfLong layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return (long)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize())); } @@ -1506,12 +1630,16 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the long value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. */ @ForceInline default void setAtIndex(ValueLayout.OfLong layout, long index, long value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value); } @@ -1524,11 +1652,15 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return a double value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @ForceInline default double getAtIndex(ValueLayout.OfDouble layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return (double)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize())); } @@ -1541,12 +1673,16 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the double value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. */ @ForceInline default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value); } @@ -1559,11 +1695,15 @@ for (long l = 0; l < segment.byteSize(); l++) { * @return an address value read from this address. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. */ @ForceInline default MemoryAddress getAtIndex(ValueLayout.OfAddress layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return (MemoryAddress)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize())); } @@ -1576,12 +1716,16 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param value the address value to be written. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. + * @throws IllegalArgumentException if the dereference operation is + * incompatible with the alignment constraints in the provided layout, + * or if the layout alignment is greater than its size. * @throws IndexOutOfBoundsException when the dereference operation falls outside the spatial bounds of the * memory segment. * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. */ @ForceInline default void setAtIndex(ValueLayout.OfAddress layout, long index, Addressable value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value.address()); } @@ -1598,7 +1742,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param dstIndex the starting index of the destination array. * @param elementCount the number of array elements to be copied. * @throws IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported, - * or if the destination array component type does not match the carrier of the source element layout. + * if the destination array component type does not match the carrier of the source element layout, if the source + * segment/offset are incompatible with the alignment constraints in the source element layout, + * or if the destination element layout alignment is greater than its size. */ @ForceInline static void copy( @@ -1614,6 +1760,10 @@ for (long l = 0; l < segment.byteSize(); l++) { int dstBase = (int)baseAndScale; int dstWidth = (int)(baseAndScale >> 32); AbstractMemorySegmentImpl srcImpl = (AbstractMemorySegmentImpl)srcSegment; + Utils.checkElementAlignment(srcLayout, "Source layout alignment greater than its size"); + if (!srcImpl.isAlignedForElement(srcOffset, srcLayout)) { + throw new IllegalArgumentException("Source segment incompatible with alignment constraints"); + } srcImpl.checkAccess(srcOffset, elementCount * dstWidth, true); Objects.checkFromIndexSize(dstIndex, elementCount, Array.getLength(dstArray)); if (dstWidth == 1 || srcLayout.order() == ByteOrder.nativeOrder()) { @@ -1639,7 +1789,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * @param dstOffset the starting offset, in bytes, of the destination segment. * @param elementCount the number of array elements to be copied. * @throws IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported, - * or if the source array component type does not match the carrier of the destination element layout. + * if the source array component type does not match the carrier of the destination element layout, if the destination + * segment/offset are incompatible with the alignment constraints in the destination element layout, + * or if the destination element layout alignment is greater than its size. */ @ForceInline static void copy( @@ -1656,6 +1808,10 @@ for (long l = 0; l < segment.byteSize(); l++) { int srcWidth = (int)(baseAndScale >> 32); Objects.checkFromIndexSize(srcIndex, elementCount, Array.getLength(srcArray)); AbstractMemorySegmentImpl destImpl = (AbstractMemorySegmentImpl)dstSegment; + Utils.checkElementAlignment(dstLayout, "Destination layout alignment greater than its size"); + if (!destImpl.isAlignedForElement(dstOffset, dstLayout)) { + throw new IllegalArgumentException("Destination segment incompatible with alignment constraints"); + } destImpl.checkAccess(dstOffset, elementCount * srcWidth, false); if (srcWidth == 1 || dstLayout.order() == ByteOrder.nativeOrder()) { ScopedMemoryAccess.getScopedMemoryAccess().copyMemory(null, destImpl.scope(), diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/NativeSymbol.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/NativeSymbol.java index bf137e965d74c3e699c50b4bd6a8800474cf866f..3dc583f98fc0273e742b9f5d812101df561072a2 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/NativeSymbol.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/NativeSymbol.java @@ -43,22 +43,19 @@ import java.util.Objects; sealed public interface NativeSymbol extends Addressable permits NativeSymbolImpl { /** - * Returns the name of this symbol. - * @return the name of this symbol. + * {@return the name of this symbol} */ String name(); /** - * Returns the resource scope associated with this symbol. - * @return the resource scope associated with this symbol. + * {@return the resource scope associated with this symbol} */ ResourceScope scope(); /** - * Returns the memory address associated with this symbol. + * {@return the memory address associated with this symbol} * @throws IllegalStateException if the scope associated with this symbol has been closed, or if access occurs from * a thread other than the thread owning that scope. - * @return The memory address associated with this symbol. */ @Override MemoryAddress address(); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java index f2fb32a059439c00392c3c8fcd0e36790f923152..6c5d6b2b66fc24f598115b40e0bae5f8617cdf84 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java @@ -103,15 +103,15 @@ import java.util.Spliterator; * segment and allow multiple threads to work in parallel on disjoint segment slices. The following code can be used to sum * all int values in a memory segment in parallel: * - *
          {@code
          -try (ResourceScope scope = ResourceScope.newSharedScope()) {
          -    SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT);
          -    MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope);
          -    int sum = segment.elements(ValueLayout.JAVA_INT).parallel()
          -                        .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0))
          -                        .sum();
          -}
          - * }
          + * {@snippet lang=java : + * try (ResourceScope scope = ResourceScope.newSharedScope()) { + * SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT); + * MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope); + * int sum = segment.elements(ValueLayout.JAVA_INT).parallel() + * .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0)) + * .sum(); + * } + * } * *

          * Shared resource scopes, while powerful, must be used with caution: if one or more threads accesses @@ -131,13 +131,13 @@ try (ResourceScope scope = ResourceScope.newSharedScope()) { * This can be useful when clients need to perform a critical operation on a memory segment, during which they have * to ensure that the scope associated with that segment will not be closed; this can be done as follows: * - *

          {@code
          -MemorySegment segment = ...
          -try (ResourceScope criticalScope = ResourceScope.newConfinedScope()) {
          -    criticalScope.keepAlive(segment.scope());
          -    
          -}
          - * }
          + * {@snippet lang=java : + * MemorySegment segment = ... + * try (ResourceScope criticalScope = ResourceScope.newConfinedScope()) { + * criticalScope.keepAlive(segment.scope()); + * + * } + * } * * Note that a resource scope does not become unreachable * until all the scopes it depends on have been closed. @@ -147,8 +147,7 @@ try (ResourceScope criticalScope = ResourceScope.newConfinedScope()) { */ public sealed interface ResourceScope extends AutoCloseable permits ResourceScopeImpl { /** - * Is this resource scope alive? - * @return true, if this resource scope is alive. + * {@return {@code true}, if this resource scope is alive} * @see ResourceScope#close() */ boolean isAlive(); @@ -239,9 +238,9 @@ public sealed interface ResourceScope extends AutoCloseable permits ResourceScop /** * Creates a new shared scope, managed by a private {@link Cleaner} instance. Equivalent to (but likely more efficient than) * the following code: - *
          {@code
          -    newSharedScope(Cleaner.create());
          -     * }
          + * {@snippet lang=java : + * newSharedScope(Cleaner.create()); + * } * @return a shared scope, managed by a private {@link Cleaner} instance. */ static ResourceScope newImplicitScope() { diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SegmentAllocator.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SegmentAllocator.java index 622308da0886358888e9874f4d193204b4bf576a..4e2ad3255200bd4dc4797823853a280c862aa71d 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SegmentAllocator.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SegmentAllocator.java @@ -339,9 +339,9 @@ public interface SegmentAllocator { /** * Returns a native unbounded arena-based allocator, with predefined block size and maximum arena size, * associated with the provided scope. Equivalent to the following code: - *
          {@code
          -    SegmentAllocator.newNativeArena(Long.MAX_VALUE, predefinedBlockSize, scope);
          -     * }
          + * {@snippet lang=java : + * SegmentAllocator.newNativeArena(Long.MAX_VALUE, predefinedBlockSize, scope); + * } * * @param scope the scope associated with the segments returned by the arena-based allocator. * @return a new unbounded arena-based allocator @@ -355,9 +355,9 @@ public interface SegmentAllocator { /** * Returns a native unbounded arena-based allocator, with block size set to the specified arena size, associated with * the provided scope, with given arena size. Equivalent to the following code: - *
          {@code
          -    SegmentAllocator.newNativeArena(arenaSize, arenaSize, scope);
          -     * }
          + * {@snippet lang=java : + * SegmentAllocator.newNativeArena(arenaSize, arenaSize, scope); + * } * * @param arenaSize the size (in bytes) of the allocation arena. * @param scope the scope associated with the segments returned by the arena-based allocator. @@ -416,10 +416,10 @@ public interface SegmentAllocator { * each new allocation request will return a new slice starting at the segment offset {@code 0} (alignment * constraints are ignored by this allocator), hence the name prefix allocator. * Equivalent to (but likely more efficient than) the following code: - *
          {@code
          -    MemorySegment segment = ...
          -    SegmentAllocator prefixAllocator = (size, align) -> segment.asSlice(0, size);
          -     * }
          + * {@snippet lang=java : + * MemorySegment segment = ... + * SegmentAllocator prefixAllocator = (size, align) -> segment.asSlice(0, size); + * } *

          * This allocator can be useful to limit allocation requests in case a client * knows that they have fully processed the contents of the allocated segment before the subsequent allocation request @@ -439,10 +439,10 @@ public interface SegmentAllocator { /** * Returns a native allocator, associated with the provided scope. Equivalent to (but likely more efficient than) * the following code: - *

          {@code
          -    ResourceScope scope = ...
          -    SegmentAllocator nativeAllocator = (size, align) -> MemorySegment.allocateNative(size, align, scope);
          -     * }
          + * {@snippet lang=java : + * ResourceScope scope = ... + * SegmentAllocator nativeAllocator = (size, align) -> MemorySegment.allocateNative(size, align, scope); + * } * * @param scope the scope associated with the returned allocator. * @return a native allocator, associated with the provided scope. @@ -455,10 +455,9 @@ public interface SegmentAllocator { /** * Returns a native allocator which allocates segments in independent {@linkplain ResourceScope#newImplicitScope() implicit scopes}. * Equivalent to (but likely more efficient than) the following code: - *
          {@code
          -    ResourceScope scope = ...
          -    SegmentAllocator implicitAllocator = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());
          -     * }
          + * {@snippet lang=java : + * SegmentAllocator implicitAllocator = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope()); + * } * * @return a native allocator which allocates segments in independent {@linkplain ResourceScope#newImplicitScope() implicit scopes}. */ diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java index e751830313bb9c658be48a0f73cd63967f4983b5..8143d2929cea6fc073cf9a2d7e2464c7a239bebd 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,18 +37,18 @@ import java.util.OptionalLong; * A finite sequence layout can be thought of as a group layout where the sequence layout's element layout is repeated a number of times * that is equal to the sequence layout's element count. In other words this layout: * - *
          {@code
          -MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN));
          - * }
          + * {@snippet lang=java : + * MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); + * } * * is equivalent to the following layout: * - *
          {@code
          -MemoryLayout.structLayout(
          -    ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN),
          -    ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN),
          -    ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN));
          - * }
          + * {@snippet lang=java : + * MemoryLayout.structLayout( + * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), + * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), + * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); + * } * *

          * This is a value-based @@ -82,18 +82,14 @@ public final class SequenceLayout extends AbstractLayout implements MemoryLayout } /** - * Returns the element layout associated with this sequence layout. - * - * @return The element layout associated with this sequence layout. + * {@return the element layout associated with this sequence layout} */ public MemoryLayout elementLayout() { return elementLayout; } /** - * Returns the element count of this sequence layout (if any). - * - * @return the element count of this sequence layout (if any). + * {@return the element count of this sequence layout (if any)} */ public OptionalLong elementCount() { return elemCount; @@ -119,22 +115,22 @@ public final class SequenceLayout extends AbstractLayout implements MemoryLayout * as the flattened projection of this sequence layout. *

          * For instance, given a sequence layout of the kind: - *

          {@code
          -    var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT));
          -     * }
          + * {@snippet lang=java : + * var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT)); + * } * calling {@code seq.reshape(2, 6)} will yield the following sequence layout: - *
          {@code
          -    var reshapeSeq = MemoryLayout.sequenceLayout(2, MemoryLayout.sequenceLayout(6, ValueLayout.JAVA_INT));
          -     * }
          + * {@snippet lang=java : + * var reshapeSeq = MemoryLayout.sequenceLayout(2, MemoryLayout.sequenceLayout(6, ValueLayout.JAVA_INT)); + * } *

          * If one of the provided element count is the special value {@code -1}, then the element * count in that position will be inferred from the remaining element counts and the * element count of the flattened projection of this layout. For instance, a layout equivalent to * the above {@code reshapeSeq} can also be computed in the following ways: - *

          {@code
          -    var reshapeSeqImplicit1 = seq.reshape(-1, 6);
          -    var reshapeSeqImplicit2 = seq.reshape(2, -1);
          -     * }
          + * {@snippet lang=java : + * var reshapeSeqImplicit1 = seq.reshape(-1, 6); + * var reshapeSeqImplicit2 = seq.reshape(2, -1); + * } * @param elementCounts an array of element counts, of which at most one can be {@code -1}. * @return a new sequence layout where element layouts in the flattened projection of this * sequence layout (see {@link #flatten()}) are re-arranged into one or more nested sequence layouts. @@ -195,13 +191,13 @@ public final class SequenceLayout extends AbstractLayout implements MemoryLayout * This transformation preserves the layout size; nested sequence layout in this sequence layout will * be dropped and their element counts will be incorporated into that of the returned sequence layout. * For instance, given a sequence layout of the kind: - *
          {@code
          -    var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT));
          -     * }
          + * {@snippet lang=java : + * var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT)); + * } * calling {@code seq.flatten()} will yield the following sequence layout: - *
          {@code
          -    var flattenedSeq = MemoryLayout.sequenceLayout(12, ValueLayout.JAVA_INT);
          -     * }
          + * {@snippet lang=java : + * var flattenedSeq = MemoryLayout.sequenceLayout(12, ValueLayout.JAVA_INT); + * } * @return a new sequence layout with the same size as this layout (but, possibly, with different * element count), whose element layout is not a sequence layout. * @throws UnsupportedOperationException if this sequence layout, or one of the nested sequence layouts being diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java index 7543dac95d0d278e3c033bb23fbef1d24df01185..73ede4e4e9a4242585017a71a9fa1fce80726f6d 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java @@ -59,7 +59,8 @@ import java.util.function.Consumer; sealed public interface VaList extends Addressable permits WinVaList, SysVVaList, LinuxAArch64VaList, MacOsAArch64VaList, SharedUtils.EmptyVaList { /** - * Reads the next value as an {@code int} and advances this variable argument list's position. + * Reads the next value as an {@code int} and advances this variable argument list's position. The behavior of this + * method is equivalent to the C {@code va_arg} function. * * @param layout the layout of the value to be read. * @return the {@code int} value read from this variable argument list. @@ -69,7 +70,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList int nextVarg(ValueLayout.OfInt layout); /** - * Reads the next value as a {@code long} and advances this variable argument list's position. + * Reads the next value as a {@code long} and advances this variable argument list's position. The behavior of this + * method is equivalent to the C {@code va_arg} function. * * @param layout the layout of the value to be read. * @return the {@code long} value read from this variable argument list. @@ -79,7 +81,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList long nextVarg(ValueLayout.OfLong layout); /** - * Reads the next value as a {@code double} and advances this variable argument list's position. + * Reads the next value as a {@code double} and advances this variable argument list's position. The behavior of this + * method is equivalent to the C {@code va_arg} function. * * @param layout the layout of the value * @return the {@code double} value read from this variable argument list. @@ -89,7 +92,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList double nextVarg(ValueLayout.OfDouble layout); /** - * Reads the next value as a {@code MemoryAddress} and advances this variable argument list's position. + * Reads the next value as a {@code MemoryAddress} and advances this variable argument list's position. The behavior of this + * method is equivalent to the C {@code va_arg} function. * * @param layout the layout of the value to be read. * @return the {@code MemoryAddress} value read from this variable argument list. @@ -99,7 +103,13 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList MemoryAddress nextVarg(ValueLayout.OfAddress layout); /** - * Reads the next value as a {@code MemorySegment}, and advances this variable argument list's position. + * Reads the next value as a {@code MemorySegment}, and advances this variable argument list's position. The behavior of this + * method is equivalent to the C {@code va_arg} function. The provided group layout must correspond to a C struct or union + * type. + *

          + * How the value is read in the returned segment is ABI-dependent: calling this method on a group layout + * with member layouts {@code L_1, L_2, ... L_n} is not guaranteed to be semantically equivalent to perform distinct + * calls to {@code nextVarg} for each of the layouts in {@code L_1, L_2, ... L_n}. *

          * The memory segment returned by this method will be allocated using the given {@link SegmentAllocator}. * @@ -122,16 +132,18 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList void skip(MemoryLayout... layouts); /** - * Returns the resource scope associated with this variable argument list. - * @return the resource scope associated with this variable argument list. + * {@return the resource scope associated with this variable argument list} */ ResourceScope scope(); /** * Copies this variable argument list at its current position into a new variable argument list associated - * with the same scope as this variable argument list. Copying is useful to - * traverse the variable argument list elements, starting from the current position, without affecting the state - * of the original variable argument list, essentially allowing the elements to be traversed multiple times. + * with the same scope as this variable argument list. The behavior of this method is equivalent to the C + * {@code va_copy} function. + *

          + * Copying is useful to traverse the variable argument list elements, starting from the current position, + * without affecting the state of the original variable argument list, essentially allowing the elements to be + * traversed multiple times. * * @return a copy of this variable argument list. * @throws IllegalStateException if the scope associated with this variable argument list has been closed, or if access occurs from @@ -140,10 +152,9 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList VaList copy(); /** - * Returns the memory address associated with this variable argument list. + * {@return the {@linkplain MemoryAddress memory address} associated with this variable argument list} * @throws IllegalStateException if the scope associated with this variable argument list has been closed, or if access occurs from * a thread other than the thread owning that scope. - * @return The memory address associated with this variable argument list. */ @Override MemoryAddress address(); @@ -187,8 +198,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList * of the underlying variable argument list. * @param scope scope the scope to be associated with the new variable arity list. * @return a new variable argument list. - * @throws IllegalStateException if the scope associated with {@code allocator} has been already closed, - * or if access occurs from a thread other than the thread owning that scope. + * @throws IllegalStateException if {@code scope} has been already closed, or if access occurs from a thread other + * than the thread owning {@code scope}. */ static VaList make(Consumer actions, ResourceScope scope) { Objects.requireNonNull(actions); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java index 36a3c6b5b9d0a3b9872fad1f769bb7927ba3f826..c2df9e1b25f972f3202b5320874c59e47fc261af 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,9 +41,9 @@ import java.util.OptionalLong; /** * A value layout. A value layout is used to model the memory layout associated with values of basic data types, such as integral types - * (either signed or unsigned) and floating-point types. Each value layout has a size, a {@linkplain ByteOrder byte order}) - * and a carrier, that is, the Java type that should be used when {@linkplain MemorySegment#get(OfInt, long) accessing} - * a memory region using the value layout. + * (either signed or unsigned) and floating-point types. Each value layout has a size, an alignment (in bits), + * a {@linkplain ByteOrder byte order}, and a carrier, that is, the Java type that should be used when + * {@linkplain MemorySegment#get(OfInt, long) accessing} a memory region using the value layout. *

          * This class defines useful value layout constants for Java primitive types and addresses. * The layout constants in this class make implicit alignment and byte-ordering assumption: all layout @@ -82,9 +82,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { } /** - * Returns the value's byte order. - * - * @return the value's byte order. + * {@return the value's byte order} */ public ByteOrder order() { return order; @@ -125,8 +123,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { } /** - * Returns the carrier associated with this value layout. - * @return the carrier associated with this value layout. + * {@return the carrier associated with this value layout} */ public Class carrier() { return carrier; @@ -513,93 +510,93 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { } /** - * A value layout constant whose size is the same as that of a machine address (e.g. {@code size_t}), - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * A value layout constant whose size is the same as that of a machine address ({@code size_t}), + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *

          {@code
          -    MemoryLayout.valueLayout(MemoryAddress.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(MemoryAddress.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfAddress ADDRESS = new OfAddress(ByteOrder.nativeOrder()).withBitAlignment(8); /** * A value layout constant whose size is the same as that of a Java {@code byte}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
          {@code
          -    MemoryLayout.valueLayout(byte.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(byte.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfByte JAVA_BYTE = new OfByte(ByteOrder.nativeOrder()).withBitAlignment(8); /** * A value layout constant whose size is the same as that of a Java {@code boolean}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
          {@code
          -    MemoryLayout.valueLayout(boolean.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(boolean.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfBoolean JAVA_BOOLEAN = new OfBoolean(ByteOrder.nativeOrder()).withBitAlignment(8); /** * A value layout constant whose size is the same as that of a Java {@code char}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
          {@code
          -    MemoryLayout.valueLayout(char.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(char.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfChar JAVA_CHAR = new OfChar(ByteOrder.nativeOrder()).withBitAlignment(8); /** * A value layout constant whose size is the same as that of a Java {@code short}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
          {@code
          -    MemoryLayout.valueLayout(short.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(short.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfShort JAVA_SHORT = new OfShort(ByteOrder.nativeOrder()).withBitAlignment(8); /** * A value layout constant whose size is the same as that of a Java {@code int}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
          {@code
          -    MemoryLayout.valueLayout(int.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(int.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfInt JAVA_INT = new OfInt(ByteOrder.nativeOrder()).withBitAlignment(8); /** * A value layout constant whose size is the same as that of a Java {@code long}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
          {@code
          -    MemoryLayout.valueLayout(long.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(long.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfLong JAVA_LONG = new OfLong(ByteOrder.nativeOrder()) .withBitAlignment(8); /** * A value layout constant whose size is the same as that of a Java {@code float}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
          {@code
          -    MemoryLayout.valueLayout(float.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(float.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfFloat JAVA_FLOAT = new OfFloat(ByteOrder.nativeOrder()).withBitAlignment(8); /** * A value layout constant whose size is the same as that of a Java {@code double}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
          {@code
          -    MemoryLayout.valueLayout(double.class, ByteOrder.nativeOrder()).withBitAlignment(8);
          -     * }
          + * {@snippet lang=java : + * MemoryLayout.valueLayout(double.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfDouble JAVA_DOUBLE = new OfDouble(ByteOrder.nativeOrder()).withBitAlignment(8); } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java index 82bc2f53d4b2b5f146a43c24e65f446f4fa9377c..a74c6d3a55d7d2a80dd49caa5459245de2a8ea48 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java @@ -30,7 +30,7 @@ *

          Foreign memory access

          * *

          - * The main abstractions introduced to support foreign memory access is {@link jdk.incubator.foreign.MemorySegment}, which + * The main abstraction introduced to support foreign memory access is {@link jdk.incubator.foreign.MemorySegment}, which * models a contiguous memory region, which can reside either inside or outside the Java heap. * A memory segment represents the main access coordinate of a memory access var handle, which can be obtained * using the combinator methods defined in the {@link jdk.incubator.foreign.MemoryHandles} class; a set of @@ -43,12 +43,12 @@ * For example, to allocate an off-heap memory region big enough to hold 10 values of the primitive type {@code int}, and fill it with values * ranging from {@code 0} to {@code 9}, we can use the following code: * - *

          {@code
          -MemorySegment segment = MemorySegment.allocateNative(10 * 4, ResourceScope.newImplicitScope());
          -for (int i = 0 ; i < 10 ; i++) {
          -   segment.setAtIndex(ValueLayout.JAVA_INT, i, i);
          -}
          - * }
          + * {@snippet lang=java : + * MemorySegment segment = MemorySegment.allocateNative(10 * 4, ResourceScope.newImplicitScope()); + * for (int i = 0 ; i < 10 ; i++) { + * segment.setAtIndex(ValueLayout.JAVA_INT, i, i); + * } + * } * * This code creates a native memory segment, that is, a memory segment backed by * off-heap memory; the size of the segment is 40 bytes, enough to store 10 values of the primitive type {@code int}. @@ -69,14 +69,14 @@ for (int i = 0 ; i < 10 ; i++) { * Clients that operate under these assumptions might want to programmatically release the memory associated * with a memory segment. This can be done, using the {@link jdk.incubator.foreign.ResourceScope} abstraction, as shown below: * - *
          {@code
          -try (ResourceScope scope = ResourceScope.newConfinedScope()) {
          -    MemorySegment segment = MemorySegment.allocateNative(10 * 4, scope);
          -    for (int i = 0 ; i < 10 ; i++) {
          -        segment.setAtIndex(ValueLayout.JAVA_INT, i, i);
          -    }
          -}
          - * }
          + * {@snippet lang=java : + * try (ResourceScope scope = ResourceScope.newConfinedScope()) { + * MemorySegment segment = MemorySegment.allocateNative(10 * 4, scope); + * for (int i = 0 ; i < 10 ; i++) { + * segment.setAtIndex(ValueLayout.JAVA_INT, i, i); + * } + * } + * } * * This example is almost identical to the prior one; this time we first create a so called resource scope, * which is used to bind the life-cycle of the segment created immediately afterwards. Note the use of the @@ -86,7 +86,7 @@ try (ResourceScope scope = ResourceScope.newConfinedScope()) { *

          Safety

          * * This API provides strong safety guarantees when it comes to memory access. First, when dereferencing a memory segment, - * the access coordinates are validated (upon access), to make sure that access does not occur at an address which resides + * the access coordinates are validated (upon access), to make sure that access does not occur at any address which resides * outside the boundaries of the memory segment used by the dereference operation. We call this guarantee spatial safety; * in other words, access to memory segments is bounds-checked, in the same way as array access is, as described in * Section {@jls 15.10.4} of The Java Language Specification. @@ -99,30 +99,30 @@ try (ResourceScope scope = ResourceScope.newConfinedScope()) { *

          Foreign function access

          * The key abstractions introduced to support foreign function access are {@link jdk.incubator.foreign.SymbolLookup}, * {@link jdk.incubator.foreign.MemoryAddress} and {@link jdk.incubator.foreign.CLinker}. - * The first is used to lookup symbols inside native libraries; the second is used to model native addresses (more on that later), + * The first is used to look up symbols inside native libraries; the second is used to model native addresses (more on that later), * while the third provides linking capabilities which allows modelling foreign functions as {@link java.lang.invoke.MethodHandle} instances, * so that clients can perform foreign function calls directly in Java, without the need for intermediate layers of native - * code (as it's the case with the Java Native Interface (JNI)). + * code (as is the case with the Java Native Interface (JNI)). *

          * For example, to compute the length of a string using the C standard library function {@code strlen} on a Linux x64 platform, * we can use the following code: * - *

          {@code
          -      var linker = CLinker.systemCLinker();
          -      MethodHandle strlen = linker.downcallHandle(
          -        linker.lookup("strlen").get(),
          -        FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
          -      );
          -
          -      try (var scope = ResourceScope.newConfinedScope()) {
          -         var cString = MemorySegment.allocateNative(5 + 1, scope);
          -         cString.setUtf8String("Hello");
          -         long len = (long)strlen.invoke(cString); // 5
          -      }
          - * }
          + * {@snippet lang=java : + * var linker = CLinker.systemCLinker(); + * MethodHandle strlen = linker.downcallHandle( + * linker.lookup("strlen").get(), + * FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS) + * ); + * + * try (var scope = ResourceScope.newConfinedScope()) { + * var cString = MemorySegment.allocateNative(5 + 1, scope); + * cString.setUtf8String("Hello"); + * long len = (long)strlen.invoke(cString); // 5 + * } + * } * * Here, we obtain a {@linkplain jdk.incubator.foreign.CLinker#systemCLinker() linker instance} and we use it - * to {@linkplain jdk.incubator.foreign.CLinker#lookup(java.lang.String) lookup} the {@code strlen} symbol in the + * to {@linkplain jdk.incubator.foreign.CLinker#lookup(java.lang.String) look up} the {@code strlen} symbol in the * standard C library; a downcall method handle targeting said symbol is subsequently * {@linkplain jdk.incubator.foreign.CLinker#downcallHandle(jdk.incubator.foreign.FunctionDescriptor) obtained}. * To complete the linking successfully, we must provide a {@link jdk.incubator.foreign.FunctionDescriptor} instance, @@ -138,9 +138,9 @@ try (ResourceScope scope = ResourceScope.newConfinedScope()) { *

          Foreign addresses

          * * When a memory segment is created from Java code, the segment properties (spatial bounds, temporal bounds and confinement) - * are fully known at segment creation. But when interacting with native libraries, clients will often receive raw pointers; - * such pointers have no spatial bounds (example: does the C type {@code char*} refer to a single {@code char} value, - * or an array of {@code char} values, of given size?), no notion of temporal bounds, nor thread-confinement. + * are fully known at segment creation. But when interacting with native libraries, clients will often receive raw pointers. + * Such pointers have no spatial bounds. For example, the C type {@code char*} can refer to a single {@code char} value, + * or an array of {@code char} values, of given size. Nor do said pointers have any notion of temporal bounds or thread-confinement. *

          * Raw pointers are modelled using the {@link jdk.incubator.foreign.MemoryAddress} class. When clients receive a * memory address instance from a foreign function call, they can perform memory dereference on it directly, @@ -148,11 +148,10 @@ try (ResourceScope scope = ResourceScope.newConfinedScope()) { * {@linkplain jdk.incubator.foreign.MemoryAddress#get(jdk.incubator.foreign.ValueLayout.OfInt, long) dereference methods} * provided: * - *

          {@code
          -...
          -MemoryAddress addr = ... //obtain address from native code
          -int x = addr.get(ValueLayout.JAVA_INT, 0);
          - * }
          + * {@snippet lang=java : + * MemoryAddress addr = ... //obtain address from native code + * int x = addr.get(ValueLayout.JAVA_INT, 0); + * } * * Alternatively, the client can * {@linkplain jdk.incubator.foreign.MemorySegment#ofAddress(jdk.incubator.foreign.MemoryAddress, long, jdk.incubator.foreign.ResourceScope) create} @@ -160,51 +159,51 @@ int x = addr.get(ValueLayout.JAVA_INT, 0); * for instance, be available in the documentation of the foreign function which produced the native address. * Here is how an unsafe segment can be created from a native address: * - *
          {@code
          -ResourceScope scope = ... // initialize a resource scope object
          -MemoryAddress addr = ... //obtain address from native code
          -MemorySegment segment = MemorySegment.ofAddress(addr, 4, scope); // segment is 4 bytes long
          -int x = segment.get(ValueLayout.JAVA_INT, 0);
          - * }
          + * {@snippet lang=java : + * ResourceScope scope = ... // initialize a resource scope object + * MemoryAddress addr = ... //obtain address from native code + * MemorySegment segment = MemorySegment.ofAddress(addr, 4, scope); // segment is 4 bytes long + * int x = segment.get(ValueLayout.JAVA_INT, 0); + * } * *

          Upcalls

          - * The {@link jdk.incubator.foreign.CLinker} interface also allows to turn an existing method handle (which might point + * The {@link jdk.incubator.foreign.CLinker} interface also allows clients to turn an existing method handle (which might point * to a Java method) into a memory address, so that Java code can effectively be passed to other foreign functions. * For instance, we can write a method that compares two integer values, as follows: * - *
          {@code
          -class IntComparator {
          -    static int intCompare(MemoryAddress addr1, MemoryAddress addr2) {
          -        return addr1.get(ValueLayout.JAVA_INT, 0) - addr2.get(ValueLayout.JAVA_INT, 0);
          -    }
          -}
          - * }
          + * {@snippet lang=java : + * class IntComparator { + * static int intCompare(MemoryAddress addr1, MemoryAddress addr2) { + * return addr1.get(ValueLayout.JAVA_INT, 0) - addr2.get(ValueLayout.JAVA_INT, 0); + * } + * } + * } * * The above method dereferences two memory addresses containing an integer value, and performs a simple comparison * by returning the difference between such values. We can then obtain a method handle which targets the above static * method, as follows: * - *
          {@code
          -FunctionDescriptor intCompareDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
          -MethodHandle intCompareHandle = MethodHandles.lookup().findStatic(IntComparator.class,
          -                                                   "intCompare",
          -                                                   CLinker.upcallType(comparFunction));
          - * }
          + * {@snippet lang=java : + * FunctionDescriptor intCompareDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS); + * MethodHandle intCompareHandle = MethodHandles.lookup().findStatic(IntComparator.class, + * "intCompare", + * CLinker.upcallType(comparFunction)); + * } * * As before, we need to create a {@link jdk.incubator.foreign.FunctionDescriptor} instance, this time describing the signature * of the function pointer we want to create. The descriptor can be used to * {@linkplain jdk.incubator.foreign.CLinker#upcallType(jdk.incubator.foreign.FunctionDescriptor) derive} a method type - * that can be used to lookup the method handle for {@code IntComparator.intCompare}. + * that can be used to look up the method handle for {@code IntComparator.intCompare}. *

          * Now that we have a method handle instance, we can turn it into a fresh function pointer, * using the {@link jdk.incubator.foreign.CLinker} interface, as follows: * - *

          {@code
          -ResourceScope scope = ...
          -Addressable comparFunc = CLinker.systemCLinker().upcallStub(
          -     intCompareHandle, intCompareDescriptor, scope);
          -);
          - * }
          + * {@snippet lang=java : + * ResourceScope scope = ... + * Addressable comparFunc = CLinker.systemCLinker().upcallStub( + * intCompareHandle, intCompareDescriptor, scope); + * ); + * } * * The {@link jdk.incubator.foreign.FunctionDescriptor} instance created in the previous step is then used to * {@linkplain jdk.incubator.foreign.CLinker#upcallStub(java.lang.invoke.MethodHandle, jdk.incubator.foreign.FunctionDescriptor, jdk.incubator.foreign.ResourceScope) create} diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index eacbeb26a519282d878018cd55db213c47df531b..6ced72bc1af7b8204783a894dd293fe5e45956b3 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -124,8 +124,12 @@ public abstract non-sealed class AbstractMemorySegmentImpl extends MemorySegment if (elementLayout.byteSize() == 0) { throw new IllegalArgumentException("Element layout size cannot be zero"); } - if (byteSize() % elementLayout.byteSize() != 0) { - throw new IllegalArgumentException("Segment size is no a multiple of layout size"); + Utils.checkElementAlignment(elementLayout, "Element layout alignment greater than its size"); + if (!isAlignedForElement(0, elementLayout)) { + throw new IllegalArgumentException("Incompatible alignment constraints"); + } + if (!Utils.isAligned(byteSize(), elementLayout.byteSize())) { + throw new IllegalArgumentException("Segment size is not a multiple of layout size"); } return new SegmentSplitter(elementLayout.byteSize(), byteSize() / elementLayout.byteSize(), this); @@ -360,11 +364,7 @@ public abstract non-sealed class AbstractMemorySegmentImpl extends MemorySegment } void checkValidState() { - try { - scope.checkValidState(); - } catch (ScopedMemoryAccess.Scope.ScopedAccessError ex) { - throw new IllegalStateException("This segment is already closed"); - } + scope.checkValidStateSlow(); } @Override @@ -383,8 +383,13 @@ public abstract non-sealed class AbstractMemorySegmentImpl extends MemorySegment return (this.mask & mask) != 0; } + @ForceInline + public final boolean isAlignedForElement(long offset, MemoryLayout layout) { + return (((unsafeGetOffset() + offset) | maxAlignMask()) & (layout.byteAlignment() - 1)) == 0; + } + private int checkArraySize(String typeName, int elemSize) { - if (length % elemSize != 0) { + if (!Utils.isAligned(length, elemSize)) { throw new IllegalStateException(String.format("Segment size is not a multiple of %d. Size: %d", elemSize, length)); } long arraySize = length / elemSize; diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ConfinedScope.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ConfinedScope.java index ac8850258c15cf4842cac7b9493eef284987040d..a0a7d01cea6872aeb20454101c0b119ce161571f 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ConfinedScope.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ConfinedScope.java @@ -39,10 +39,7 @@ import java.lang.ref.Cleaner; */ final class ConfinedScope extends ResourceScopeImpl { - private boolean closed; // = false - private int lockCount = 0; private int asyncReleaseCount = 0; - private final Thread owner; static final VarHandle ASYNC_RELEASE_COUNT; @@ -55,40 +52,29 @@ final class ConfinedScope extends ResourceScopeImpl { } public ConfinedScope(Thread owner, Cleaner cleaner) { - super(new ConfinedResourceList(), cleaner); - this.owner = owner; - } - - @ForceInline - public final void checkValidState() { - if (owner != Thread.currentThread()) { - throw new IllegalStateException("Attempted access outside owning thread"); - } - if (closed) { - throw new IllegalStateException("Already closed"); - } + super(owner, new ConfinedResourceList(), cleaner); } @Override public boolean isAlive() { - return !closed; + return state != CLOSED; } @Override @ForceInline public void acquire0() { - checkValidState(); - if (lockCount == MAX_FORKS) { + checkValidStateSlow(); + if (state == MAX_FORKS) { throw new IllegalStateException("Scope keep alive limit exceeded"); } - lockCount++; + state++; } @Override @ForceInline public void release0() { if (Thread.currentThread() == owner) { - lockCount--; + state--; } else { // It is possible to end up here in two cases: this scope was kept alive by some other confined scope // which is implicitly released (in which case the release call comes from the cleaner thread). Or, @@ -99,19 +85,14 @@ final class ConfinedScope extends ResourceScopeImpl { } void justClose() { - this.checkValidState(); - if (lockCount == 0 || lockCount - ((int)ASYNC_RELEASE_COUNT.getVolatile(this)) == 0) { - closed = true; + checkValidStateSlow(); + if (state == 0 || state - ((int)ASYNC_RELEASE_COUNT.getVolatile(this)) == 0) { + state = CLOSED; } else { - throw new IllegalStateException("Scope is kept alive by " + lockCount + " scopes"); + throw new IllegalStateException("Scope is kept alive by " + state + " scopes"); } } - @Override - public Thread ownerThread() { - return owner; - } - /** * A confined resource list; no races are possible here. */ diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java index 755d6cb14dc247a31e89299741c6fb805dea7b37..4d2249261a3a892d0d32c3d632014ca70ebf150b 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java @@ -36,29 +36,38 @@ import java.nio.ByteBuffer; import java.util.Objects; /** - * Implementation for heap memory segments. An heap memory segment is composed by an offset and + * Implementation for heap memory segments. A heap memory segment is composed by an offset and * a base object (typically an array). To enhance performances, the access to the base object needs to feature * sharp type information, as well as sharp null-check information. For this reason, many concrete subclasses * of {@link HeapMemorySegmentImpl} are defined (e.g. {@link OfFloat}, so that each subclass can override the - * {@link HeapMemorySegmentImpl#base()} method so that it returns an array of the correct (sharp) type. + * {@link HeapMemorySegmentImpl#base()} method so that it returns an array of the correct (sharp) type. Note that + * the field type storing the 'base' coordinate is just Object; similarly, all the constructor in the subclasses + * accept an Object 'base' parameter instead of a sharper type (e.g. {@code byte[]}). This is deliberate, as + * using sharper types would require use of type-conversions, which in turn would inhibit some C2 optimizations, + * such as the elimination of store barriers in methods like {@link HeapMemorySegmentImpl#dup(long, long, int, ResourceScopeImpl)}. */ -public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl { +public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final int BYTE_ARR_BASE = UNSAFE.arrayBaseOffset(byte[].class); + private static final long MAX_ALIGN_1 = 1; + private static final long MAX_ALIGN_2 = 2; + private static final long MAX_ALIGN_4 = 4; + private static final long MAX_ALIGN_8 = 8; + final long offset; - final H base; + final Object base; @ForceInline - HeapMemorySegmentImpl(long offset, H base, long length, int mask) { + HeapMemorySegmentImpl(long offset, Object base, long length, int mask) { super(length, mask, ResourceScopeImpl.GLOBAL); this.offset = offset; this.base = base; } @Override - abstract H base(); + abstract Object base(); @Override long min() { @@ -66,7 +75,7 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl } @Override - abstract HeapMemorySegmentImpl dup(long offset, long size, int mask, ResourceScopeImpl scope); + abstract HeapMemorySegmentImpl dup(long offset, long size, int mask, ResourceScopeImpl scope); @Override ByteBuffer makeByteBuffer() { @@ -79,9 +88,9 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl // factories - public static class OfByte extends HeapMemorySegmentImpl { + public static class OfByte extends HeapMemorySegmentImpl { - OfByte(long offset, byte[] base, long length, int mask) { + OfByte(long offset, Object base, long length, int mask) { super(offset, base, length, mask); } @@ -92,7 +101,7 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl @Override byte[] base() { - return Objects.requireNonNull(base); + return (byte[])Objects.requireNonNull(base); } public static MemorySegment fromArray(byte[] arr) { @@ -100,11 +109,16 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl long byteSize = (long)arr.length * Unsafe.ARRAY_BYTE_INDEX_SCALE; return new OfByte(Unsafe.ARRAY_BYTE_BASE_OFFSET, arr, byteSize, defaultAccessModes(byteSize)); } + + @Override + public long maxAlignMask() { + return MAX_ALIGN_1; + } } - public static class OfChar extends HeapMemorySegmentImpl { + public static class OfChar extends HeapMemorySegmentImpl { - OfChar(long offset, char[] base, long length, int mask) { + OfChar(long offset, Object base, long length, int mask) { super(offset, base, length, mask); } @@ -115,7 +129,7 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl @Override char[] base() { - return Objects.requireNonNull(base); + return (char[])Objects.requireNonNull(base); } public static MemorySegment fromArray(char[] arr) { @@ -123,11 +137,16 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl long byteSize = (long)arr.length * Unsafe.ARRAY_CHAR_INDEX_SCALE; return new OfChar(Unsafe.ARRAY_CHAR_BASE_OFFSET, arr, byteSize, defaultAccessModes(byteSize)); } + + @Override + public long maxAlignMask() { + return MAX_ALIGN_2; + } } - public static class OfShort extends HeapMemorySegmentImpl { + public static class OfShort extends HeapMemorySegmentImpl { - OfShort(long offset, short[] base, long length, int mask) { + OfShort(long offset, Object base, long length, int mask) { super(offset, base, length, mask); } @@ -138,7 +157,7 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl @Override short[] base() { - return Objects.requireNonNull(base); + return (short[])Objects.requireNonNull(base); } public static MemorySegment fromArray(short[] arr) { @@ -146,11 +165,16 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl long byteSize = (long)arr.length * Unsafe.ARRAY_SHORT_INDEX_SCALE; return new OfShort(Unsafe.ARRAY_SHORT_BASE_OFFSET, arr, byteSize, defaultAccessModes(byteSize)); } + + @Override + public long maxAlignMask() { + return MAX_ALIGN_2; + } } - public static class OfInt extends HeapMemorySegmentImpl { + public static class OfInt extends HeapMemorySegmentImpl { - OfInt(long offset, int[] base, long length, int mask) { + OfInt(long offset, Object base, long length, int mask) { super(offset, base, length, mask); } @@ -161,7 +185,7 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl @Override int[] base() { - return Objects.requireNonNull(base); + return (int[])Objects.requireNonNull(base); } public static MemorySegment fromArray(int[] arr) { @@ -169,11 +193,16 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl long byteSize = (long)arr.length * Unsafe.ARRAY_INT_INDEX_SCALE; return new OfInt(Unsafe.ARRAY_INT_BASE_OFFSET, arr, byteSize, defaultAccessModes(byteSize)); } + + @Override + public long maxAlignMask() { + return MAX_ALIGN_4; + } } - public static class OfLong extends HeapMemorySegmentImpl { + public static class OfLong extends HeapMemorySegmentImpl { - OfLong(long offset, long[] base, long length, int mask) { + OfLong(long offset, Object base, long length, int mask) { super(offset, base, length, mask); } @@ -184,7 +213,7 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl @Override long[] base() { - return Objects.requireNonNull(base); + return (long[])Objects.requireNonNull(base); } public static MemorySegment fromArray(long[] arr) { @@ -192,11 +221,16 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl long byteSize = (long)arr.length * Unsafe.ARRAY_LONG_INDEX_SCALE; return new OfLong(Unsafe.ARRAY_LONG_BASE_OFFSET, arr, byteSize, defaultAccessModes(byteSize)); } + + @Override + public long maxAlignMask() { + return MAX_ALIGN_8; + } } - public static class OfFloat extends HeapMemorySegmentImpl { + public static class OfFloat extends HeapMemorySegmentImpl { - OfFloat(long offset, float[] base, long length, int mask) { + OfFloat(long offset, Object base, long length, int mask) { super(offset, base, length, mask); } @@ -207,7 +241,7 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl @Override float[] base() { - return Objects.requireNonNull(base); + return (float[])Objects.requireNonNull(base); } public static MemorySegment fromArray(float[] arr) { @@ -215,11 +249,16 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl long byteSize = (long)arr.length * Unsafe.ARRAY_FLOAT_INDEX_SCALE; return new OfFloat(Unsafe.ARRAY_FLOAT_BASE_OFFSET, arr, byteSize, defaultAccessModes(byteSize)); } + + @Override + public long maxAlignMask() { + return MAX_ALIGN_4; + } } - public static class OfDouble extends HeapMemorySegmentImpl { + public static class OfDouble extends HeapMemorySegmentImpl { - OfDouble(long offset, double[] base, long length, int mask) { + OfDouble(long offset, Object base, long length, int mask) { super(offset, base, length, mask); } @@ -230,7 +269,7 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl @Override double[] base() { - return Objects.requireNonNull(base); + return (double[])Objects.requireNonNull(base); } public static MemorySegment fromArray(double[] arr) { @@ -238,6 +277,11 @@ public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl long byteSize = (long)arr.length * Unsafe.ARRAY_DOUBLE_INDEX_SCALE; return new OfDouble(Unsafe.ARRAY_DOUBLE_BASE_OFFSET, arr, byteSize, defaultAccessModes(byteSize)); } + + @Override + public long maxAlignMask() { + return MAX_ALIGN_8; + } } } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/LayoutPath.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/LayoutPath.java index 1d8bb265c839f13bd51505ed5b56fc943284ce63..dbe52a697998049dbb2bc68b553c0c9224803a75 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/LayoutPath.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/LayoutPath.java @@ -282,11 +282,11 @@ public class LayoutPath { private static void checkAlignment(LayoutPath path) { MemoryLayout layout = path.layout; long alignment = layout.bitAlignment(); - if (path.offset % alignment != 0) { + if (!Utils.isAligned(path.offset, alignment)) { throw new UnsupportedOperationException("Invalid alignment requirements for layout " + layout); } for (long stride : path.strides) { - if (stride % alignment != 0) { + if (!Utils.isAligned(stride, alignment)) { throw new UnsupportedOperationException("Alignment requirements for layout " + layout + " do not match stride " + stride); } } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemoryAddressImpl.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemoryAddressImpl.java index 59d7105082cfc8876b2f0daa2db592adef99ca13..7bb5590757190b540d7bfecc12020ac2bf55cead 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemoryAddressImpl.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemoryAddressImpl.java @@ -267,6 +267,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public char getAtIndex(ValueLayout.OfChar layout, long index) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return NativeMemorySegmentImpl.EVERYTHING.get(layout, toRawLongValue() + (index * layout.byteSize())); } @@ -275,6 +276,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public void setAtIndex(ValueLayout.OfChar layout, long index, char value) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); NativeMemorySegmentImpl.EVERYTHING.set(layout, toRawLongValue() + (index * layout.byteSize()), value); } @@ -283,6 +285,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public short getAtIndex(ValueLayout.OfShort layout, long index) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return NativeMemorySegmentImpl.EVERYTHING.get(layout, toRawLongValue() + (index * layout.byteSize())); } @@ -291,6 +294,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public void setAtIndex(ValueLayout.OfShort layout, long index, short value) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); NativeMemorySegmentImpl.EVERYTHING.set(layout, toRawLongValue() + (index * layout.byteSize()), value); } @@ -299,6 +303,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public int getAtIndex(ValueLayout.OfInt layout, long index) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return NativeMemorySegmentImpl.EVERYTHING.get(layout, toRawLongValue() + (index * layout.byteSize())); } @@ -307,6 +312,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public void setAtIndex(ValueLayout.OfInt layout, long index, int value) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); NativeMemorySegmentImpl.EVERYTHING.set(layout, toRawLongValue() + (index * layout.byteSize()), value); } @@ -315,6 +321,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public float getAtIndex(ValueLayout.OfFloat layout, long index) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return NativeMemorySegmentImpl.EVERYTHING.get(layout, toRawLongValue() + (index * layout.byteSize())); } @@ -323,6 +330,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public void setAtIndex(ValueLayout.OfFloat layout, long index, float value) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); NativeMemorySegmentImpl.EVERYTHING.set(layout, toRawLongValue() + (index * layout.byteSize()), value); } @@ -331,6 +339,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public long getAtIndex(ValueLayout.OfLong layout, long index) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return NativeMemorySegmentImpl.EVERYTHING.get(layout, toRawLongValue() + (index * layout.byteSize())); } @@ -339,6 +348,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public void setAtIndex(ValueLayout.OfLong layout, long index, long value) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); NativeMemorySegmentImpl.EVERYTHING.set(layout, toRawLongValue() + (index * layout.byteSize()), value); } @@ -347,6 +357,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public double getAtIndex(ValueLayout.OfDouble layout, long index) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return NativeMemorySegmentImpl.EVERYTHING.get(layout, toRawLongValue() + (index * layout.byteSize())); } @@ -355,6 +366,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public void setAtIndex(ValueLayout.OfDouble layout, long index, double value) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); NativeMemorySegmentImpl.EVERYTHING.set(layout, toRawLongValue() + (index * layout.byteSize()), value); } @@ -363,6 +375,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public MemoryAddress getAtIndex(ValueLayout.OfAddress layout, long index) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); return NativeMemorySegmentImpl.EVERYTHING.get(layout, toRawLongValue() + (index * layout.byteSize())); } @@ -371,6 +384,7 @@ public final class MemoryAddressImpl implements MemoryAddress, Scoped { @CallerSensitive public void setAtIndex(ValueLayout.OfAddress layout, long index, Addressable value) { Reflection.ensureNativeAccess(Reflection.getCallerClass()); + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); NativeMemorySegmentImpl.EVERYTHING.set(layout, toRawLongValue() + (index * layout.byteSize()), value.address()); } } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java index 11f795a2f8434b936980bfb4f4c9dc0f980f4b71..bd06223b6ceb007447a824cf346ed142da65e10a 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java @@ -92,6 +92,11 @@ public class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl { return null; } + @Override + public long maxAlignMask() { + return 0; + } + // factories public static MemorySegment makeNativeSegment(long bytesSize, long alignmentBytes, ResourceScopeImpl scope) { diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/NativeSymbolImpl.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/NativeSymbolImpl.java index ede6a7ad5f8b3c6700d69bf55dd69b656d4d54d2..cb62a2c240f3e3ed3e455e2147f72c1dbd6cc72e 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/NativeSymbolImpl.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/NativeSymbolImpl.java @@ -28,11 +28,12 @@ package jdk.internal.foreign; import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.NativeSymbol; import jdk.incubator.foreign.ResourceScope; +import jdk.internal.misc.ScopedMemoryAccess; public record NativeSymbolImpl(String name, MemoryAddress address, ResourceScope scope) implements NativeSymbol, Scoped { @Override public MemoryAddress address() { - ((ResourceScopeImpl)scope).checkValidState(); + ((ResourceScopeImpl)scope).checkValidStateSlow(); return address; } } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ResourceScopeImpl.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ResourceScopeImpl.java index dbb830a1b531d057a386744c61a7313d60058afb..173753b15864f65d558f35a3b5b1ddb556eabb5c 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ResourceScopeImpl.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ResourceScopeImpl.java @@ -32,6 +32,8 @@ import jdk.incubator.foreign.SegmentAllocator; import jdk.internal.misc.ScopedMemoryAccess; import jdk.internal.vm.annotation.ForceInline; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; import java.lang.ref.Cleaner; import java.lang.ref.Reference; import java.util.Objects; @@ -53,6 +55,23 @@ public abstract non-sealed class ResourceScopeImpl implements ResourceScope, Seg final ResourceList resourceList; final Cleaner.Cleanable cleanable; + final Thread owner; + + static final int ALIVE = 0; + static final int CLOSING = -1; + static final int CLOSED = -2; + + int state = ALIVE; + + static final VarHandle STATE; + + static { + try { + STATE = MethodHandles.lookup().findVarHandle(ResourceScopeImpl.class, "state", int.class); + } catch (Throwable ex) { + throw new ExceptionInInitializerError(ex); + } + } static final int MAX_FORKS = Integer.MAX_VALUE; @@ -89,7 +108,8 @@ public abstract non-sealed class ResourceScopeImpl implements ResourceScope, Seg } } - protected ResourceScopeImpl(ResourceList resourceList, Cleaner cleaner) { + protected ResourceScopeImpl(Thread owner, ResourceList resourceList, Cleaner cleaner) { + this.owner = owner; this.resourceList = resourceList; cleanable = (cleaner != null) ? cleaner.register(this, resourceList) : null; @@ -147,7 +167,9 @@ public abstract non-sealed class ResourceScopeImpl implements ResourceScope, Seg * Returns "owner" thread of this scope. * @return owner thread (or null for a shared scope) */ - public abstract Thread ownerThread(); + public final Thread ownerThread() { + return owner; + } /** * Returns true, if this scope is still alive. This method may be called in any thread. @@ -155,14 +177,23 @@ public abstract non-sealed class ResourceScopeImpl implements ResourceScope, Seg */ public abstract boolean isAlive(); - /** * This is a faster version of {@link #checkValidStateSlow()}, which is called upon memory access, and which - * relies on invariants associated with the memory scope implementations (typically, volatile access - * to the closed state bit is replaced with plain access, and ownership check is removed where not needed. - * Should be used with care. + * relies on invariants associated with the memory scope implementations (volatile access + * to the closed state bit is replaced with plain access). This method should be monomorphic, + * to avoid virtual calls in the memory access hot path. This method is not intended as general purpose method + * and should only be used in the memory access handle hot path; for liveness checks triggered by other API methods, + * please use {@link #checkValidStateSlow()}. */ - public abstract void checkValidState(); + @ForceInline + public final void checkValidState() { + if (owner != null && owner != Thread.currentThread()) { + throw new IllegalStateException("Attempted access outside owning thread"); + } + if (state < ALIVE) { + throw ScopedAccessError.INSTANCE; + } + } /** * Checks that this scope is still alive (see {@link #isAlive()}). @@ -170,7 +201,7 @@ public abstract non-sealed class ResourceScopeImpl implements ResourceScope, Seg * a confined scope and this method is called outside of the owner thread. */ public final void checkValidStateSlow() { - if (ownerThread() != null && Thread.currentThread() != ownerThread()) { + if (owner != null && Thread.currentThread() != owner) { throw new IllegalStateException("Attempted access outside owning thread"); } else if (!isAlive()) { throw new IllegalStateException("Already closed"); @@ -217,6 +248,11 @@ public abstract non-sealed class ResourceScopeImpl implements ResourceScope, Seg void addInternal(ResourceList.ResourceCleanup resource) { // do nothing } + + @Override + public boolean isAlive() { + return true; + } } public static final ResourceScopeImpl GLOBAL = new GlobalScopeImpl(null); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SharedScope.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SharedScope.java index 93ecf08d468503e5d64823866f6bb854be5d2b71..4d80eb9bbe586ceed5beeff0841589f7ffea29c7 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SharedScope.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SharedScope.java @@ -45,36 +45,8 @@ class SharedScope extends ResourceScopeImpl { private static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess(); - private static final int ALIVE = 0; - private static final int CLOSING = -1; - private static final int CLOSED = -2; - - private int state = ALIVE; - - private static final VarHandle STATE; - - static { - try { - STATE = MethodHandles.lookup().findVarHandle(jdk.internal.foreign.SharedScope.class, "state", int.class); - } catch (Throwable ex) { - throw new ExceptionInInitializerError(ex); - } - } - SharedScope(Cleaner cleaner) { - super(new SharedResourceList(), cleaner); - } - - @Override - public Thread ownerThread() { - return null; - } - - @Override - public void checkValidState() { - if (state < ALIVE) { - throw ScopedAccessError.INSTANCE; - } + super(null, new SharedResourceList(), cleaner); } @Override diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/Utils.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/Utils.java index 6272e6e31005de03b6610013e831dd7c5dccfae9..bb9db16eff2514354806fe9475a253f4bca9f3d8 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/Utils.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/Utils.java @@ -98,7 +98,7 @@ public final class Utils { } public static long bitsToBytesOrThrow(long bits, Supplier exFactory) { - if (bits % 8 == 0) { + if (Utils.isAligned(bits, 8)) { return bits / 8; } else { throw exFactory.get(); @@ -173,4 +173,16 @@ public final class Utils { // note: we know size is a small value (as it comes from ValueLayout::byteSize()) return MemorySegmentProxy.multiplyOffsets(index, (int)size, (AbstractMemorySegmentImpl)segment); } + + @ForceInline + public static boolean isAligned(long offset, long align) { + return (offset & (align - 1)) == 0; + } + + @ForceInline + public static void checkElementAlignment(MemoryLayout layout, String msg) { + if (layout.byteAlignment() > layout.byteSize()) { + throw new IllegalArgumentException(msg); + } + } } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java index 3a2620583bfc4e336c55ea6845716398528bf342..e4fae8e0acfff259fe909123465055a6ca354adf 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java @@ -757,9 +757,9 @@ final class Byte128Vector extends ByteVector { @ForceInline /*package-private*/ static Byte128Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Byte128Mask.class, byte.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Byte128Mask.class, byte.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Byte128Mask TRUE_MASK = new Byte128Mask(true); private static final Byte128Mask FALSE_MASK = new Byte128Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java index 6fbe00dfdeac3213798401ac2b1b86cd59bf9430..7c123c893b4e8f8f8da0c3fbda772cc747621d57 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java @@ -789,9 +789,9 @@ final class Byte256Vector extends ByteVector { @ForceInline /*package-private*/ static Byte256Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Byte256Mask.class, byte.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Byte256Mask.class, byte.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Byte256Mask TRUE_MASK = new Byte256Mask(true); private static final Byte256Mask FALSE_MASK = new Byte256Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java index fd6117a7884b199afefb05e051088cfa821cf7eb..1b63838b14c8b2f57a0c397f0e1f495f133b4f84 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java @@ -853,9 +853,9 @@ final class Byte512Vector extends ByteVector { @ForceInline /*package-private*/ static Byte512Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Byte512Mask.class, byte.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Byte512Mask.class, byte.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Byte512Mask TRUE_MASK = new Byte512Mask(true); private static final Byte512Mask FALSE_MASK = new Byte512Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java index 309f54eaf7638a9f4b770a2aec99e80971676fb8..16010b7de0987ac2b4cab568a6b46e64cf7abfe5 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java @@ -741,9 +741,9 @@ final class Byte64Vector extends ByteVector { @ForceInline /*package-private*/ static Byte64Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Byte64Mask.class, byte.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Byte64Mask.class, byte.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Byte64Mask TRUE_MASK = new Byte64Mask(true); private static final Byte64Mask FALSE_MASK = new Byte64Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java index e27775d61c3982b111e001068cb341701b566c1b..fb36dab860ce21400f499e0e861cf59a21bb9cf8 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java @@ -727,9 +727,9 @@ final class ByteMaxVector extends ByteVector { @ForceInline /*package-private*/ static ByteMaxMask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(ByteMaxMask.class, byte.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(ByteMaxMask.class, byte.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final ByteMaxMask TRUE_MASK = new ByteMaxMask(true); private static final ByteMaxMask FALSE_MASK = new ByteMaxMask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java index 32b84aef14b9a46d9b66834736dc6e2aa9ea8164..256e1a5700f4154b4dd5fcab841fd6715c436564 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java @@ -455,8 +455,8 @@ public abstract class ByteVector extends AbstractVector { @ForceInline public static ByteVector zero(VectorSpecies species) { ByteSpecies vsp = (ByteSpecies) species; - return VectorSupport.broadcastCoerced(vsp.vectorType(), byte.class, species.length(), - 0, vsp, + return VectorSupport.fromBitsCoerced(vsp.vectorType(), byte.class, species.length(), + 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -4149,9 +4149,9 @@ public abstract class ByteVector extends AbstractVector { @ForceInline final ByteVector broadcastBits(long bits) { return (ByteVector) - VectorSupport.broadcastCoerced( + VectorSupport.fromBitsCoerced( vectorType, byte.class, laneCount, - bits, this, + bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java index 62f2eb5eff586a3f8f64c315ab1baf5a930b6862..d4762fe779659e522abb67ca10c604639c7cecb5 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java @@ -718,9 +718,9 @@ final class Double128Vector extends DoubleVector { @ForceInline /*package-private*/ static Double128Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Double128Mask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Double128Mask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Double128Mask TRUE_MASK = new Double128Mask(true); private static final Double128Mask FALSE_MASK = new Double128Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java index 547684af87d29652d788386febe4e02e35a6f490..147d6b866d63a1bd827bc3fd035695e6c88bdc83 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java @@ -722,9 +722,9 @@ final class Double256Vector extends DoubleVector { @ForceInline /*package-private*/ static Double256Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Double256Mask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Double256Mask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Double256Mask TRUE_MASK = new Double256Mask(true); private static final Double256Mask FALSE_MASK = new Double256Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java index bacc0cde0881f2a5dc4e8c7fd9395b07fb52012b..e091ca9b63fd4407e36323ec029c59dc3821dad6 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java @@ -730,9 +730,9 @@ final class Double512Vector extends DoubleVector { @ForceInline /*package-private*/ static Double512Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Double512Mask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Double512Mask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Double512Mask TRUE_MASK = new Double512Mask(true); private static final Double512Mask FALSE_MASK = new Double512Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java index 29977c72c6aeaf271a2888cbc67df202db0e1aec..a90ff9c761ca89a4ccedb06c239050046dc6c7a4 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java @@ -716,9 +716,9 @@ final class Double64Vector extends DoubleVector { @ForceInline /*package-private*/ static Double64Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Double64Mask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Double64Mask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Double64Mask TRUE_MASK = new Double64Mask(true); private static final Double64Mask FALSE_MASK = new Double64Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java index c9db9f93b40a9092288c6ba4e21ad5a6ff00d28f..bf4ce4e6422a8a4e5fadfba200a0be293e0e341b 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java @@ -715,9 +715,9 @@ final class DoubleMaxVector extends DoubleVector { @ForceInline /*package-private*/ static DoubleMaxMask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(DoubleMaxMask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(DoubleMaxMask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final DoubleMaxMask TRUE_MASK = new DoubleMaxMask(true); private static final DoubleMaxMask FALSE_MASK = new DoubleMaxMask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java index 691a4def745301984b2448f9e8527c8d2cc2b961..8455e35467890d85654b94123e8ac1b18c0c48d5 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java @@ -444,8 +444,8 @@ public abstract class DoubleVector extends AbstractVector { @ForceInline public static DoubleVector zero(VectorSpecies species) { DoubleSpecies vsp = (DoubleSpecies) species; - return VectorSupport.broadcastCoerced(vsp.vectorType(), double.class, species.length(), - toBits(0.0f), vsp, + return VectorSupport.fromBitsCoerced(vsp.vectorType(), double.class, species.length(), + toBits(0.0f), MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -3754,9 +3754,9 @@ public abstract class DoubleVector extends AbstractVector { @ForceInline final DoubleVector broadcastBits(long bits) { return (DoubleVector) - VectorSupport.broadcastCoerced( + VectorSupport.fromBitsCoerced( vectorType, double.class, laneCount, - bits, this, + bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java index 4e0dd018d269986843332e216b4ddafe64b72000..88f6d76d0cb76d0d8649c1913e1981299aff18a5 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java @@ -722,9 +722,9 @@ final class Float128Vector extends FloatVector { @ForceInline /*package-private*/ static Float128Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Float128Mask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Float128Mask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Float128Mask TRUE_MASK = new Float128Mask(true); private static final Float128Mask FALSE_MASK = new Float128Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java index 7812876f4eb59f8874ed9c977d653e22230681cb..4b039df7984ce16b136c1aa9d4d34eca9a3132d9 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java @@ -730,9 +730,9 @@ final class Float256Vector extends FloatVector { @ForceInline /*package-private*/ static Float256Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Float256Mask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Float256Mask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Float256Mask TRUE_MASK = new Float256Mask(true); private static final Float256Mask FALSE_MASK = new Float256Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java index a8936709baadb9c7e3a379b59fa7bae36376fda6..7864af72205406da5201a035e34b0c4ad5e5914a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java @@ -746,9 +746,9 @@ final class Float512Vector extends FloatVector { @ForceInline /*package-private*/ static Float512Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Float512Mask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Float512Mask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Float512Mask TRUE_MASK = new Float512Mask(true); private static final Float512Mask FALSE_MASK = new Float512Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java index 0c91d46e64e46788d840b52abbd186b2deb4f3bb..bbdbcee1c5fb38e85568c1ed3358040b7600a810 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java @@ -718,9 +718,9 @@ final class Float64Vector extends FloatVector { @ForceInline /*package-private*/ static Float64Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Float64Mask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Float64Mask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Float64Mask TRUE_MASK = new Float64Mask(true); private static final Float64Mask FALSE_MASK = new Float64Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java index f2e1bd05c13d290677c414ae909b4597f2b43e88..bba093b3b762e3d99ef6e621a1281b988eda9b9c 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java @@ -715,9 +715,9 @@ final class FloatMaxVector extends FloatVector { @ForceInline /*package-private*/ static FloatMaxMask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(FloatMaxMask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(FloatMaxMask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final FloatMaxMask TRUE_MASK = new FloatMaxMask(true); private static final FloatMaxMask FALSE_MASK = new FloatMaxMask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java index d5dbc2f9efa36fd125f5c3cf7d812ca0b6c2ca20..1dc63aa1de34feda1853fb7b20af06ccf0ee7ca4 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java @@ -444,8 +444,8 @@ public abstract class FloatVector extends AbstractVector { @ForceInline public static FloatVector zero(VectorSpecies species) { FloatSpecies vsp = (FloatSpecies) species; - return VectorSupport.broadcastCoerced(vsp.vectorType(), float.class, species.length(), - toBits(0.0f), vsp, + return VectorSupport.fromBitsCoerced(vsp.vectorType(), float.class, species.length(), + toBits(0.0f), MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -3704,9 +3704,9 @@ public abstract class FloatVector extends AbstractVector { @ForceInline final FloatVector broadcastBits(long bits) { return (FloatVector) - VectorSupport.broadcastCoerced( + VectorSupport.fromBitsCoerced( vectorType, float.class, laneCount, - bits, this, + bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java index f54042159699ce51d8bf954ec127399f501d6c8d..3a88ba76e8044a25ea1642b52d61fe375c4039a6 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java @@ -733,9 +733,9 @@ final class Int128Vector extends IntVector { @ForceInline /*package-private*/ static Int128Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Int128Mask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Int128Mask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Int128Mask TRUE_MASK = new Int128Mask(true); private static final Int128Mask FALSE_MASK = new Int128Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java index f5ed7ce09b87069317a722e64922e2e8c56bb7e5..ffc560e5f52ec6b0512886e12919fe141f719c3e 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java @@ -741,9 +741,9 @@ final class Int256Vector extends IntVector { @ForceInline /*package-private*/ static Int256Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Int256Mask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Int256Mask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Int256Mask TRUE_MASK = new Int256Mask(true); private static final Int256Mask FALSE_MASK = new Int256Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java index 6da5f59d602c040812e21ebd2053f88f66530e72..a2ff6d515e372a9bfa5164a9999b7b69f7bf6cf8 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java @@ -757,9 +757,9 @@ final class Int512Vector extends IntVector { @ForceInline /*package-private*/ static Int512Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Int512Mask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Int512Mask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Int512Mask TRUE_MASK = new Int512Mask(true); private static final Int512Mask FALSE_MASK = new Int512Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java index c9b1afb21b7a9c2e87f1696377aa09dc08b750fb..996f35ac15d480b07570c9ac01f6ccb9cc7feb76 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java @@ -729,9 +729,9 @@ final class Int64Vector extends IntVector { @ForceInline /*package-private*/ static Int64Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Int64Mask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Int64Mask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Int64Mask TRUE_MASK = new Int64Mask(true); private static final Int64Mask FALSE_MASK = new Int64Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java index 7b28a5947b067896540e5f31b6b92e45744535ef..cfc645fcd6b76a53402fc682b9b85c8bc446ccd4 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java @@ -727,9 +727,9 @@ final class IntMaxVector extends IntVector { @ForceInline /*package-private*/ static IntMaxMask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(IntMaxMask.class, int.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(IntMaxMask.class, int.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final IntMaxMask TRUE_MASK = new IntMaxMask(true); private static final IntMaxMask FALSE_MASK = new IntMaxMask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java index 3deb61e990403ac289c3187820c50699f29fff21..29dbfe5a796ee1e304bd71b4bd048adff2afe1e3 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java @@ -455,8 +455,8 @@ public abstract class IntVector extends AbstractVector { @ForceInline public static IntVector zero(VectorSpecies species) { IntSpecies vsp = (IntSpecies) species; - return VectorSupport.broadcastCoerced(vsp.vectorType(), int.class, species.length(), - 0, vsp, + return VectorSupport.fromBitsCoerced(vsp.vectorType(), int.class, species.length(), + 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -3874,9 +3874,9 @@ public abstract class IntVector extends AbstractVector { @ForceInline final IntVector broadcastBits(long bits) { return (IntVector) - VectorSupport.broadcastCoerced( + VectorSupport.fromBitsCoerced( vectorType, int.class, laneCount, - bits, this, + bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java index 81dbb215f0df0bfe3443c657dfbe12d8601a3af7..aad676d8fcebd4623e6ae8074c802a9157707d1a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java @@ -719,9 +719,9 @@ final class Long128Vector extends LongVector { @ForceInline /*package-private*/ static Long128Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Long128Mask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Long128Mask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Long128Mask TRUE_MASK = new Long128Mask(true); private static final Long128Mask FALSE_MASK = new Long128Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java index 569bd91eafa3a3845d72383b2224ae5267c65fa2..85f1e54f24290f5bdb38e1998ed9064b4526181d 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java @@ -723,9 +723,9 @@ final class Long256Vector extends LongVector { @ForceInline /*package-private*/ static Long256Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Long256Mask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Long256Mask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Long256Mask TRUE_MASK = new Long256Mask(true); private static final Long256Mask FALSE_MASK = new Long256Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java index 543baf97d47127ff11f06cdb9872f6e51695a884..1642b885f348a096bb9a3263d398abcceff97996 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java @@ -731,9 +731,9 @@ final class Long512Vector extends LongVector { @ForceInline /*package-private*/ static Long512Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Long512Mask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Long512Mask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Long512Mask TRUE_MASK = new Long512Mask(true); private static final Long512Mask FALSE_MASK = new Long512Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java index 328b399d59eb4c47b074427222f7e39a4c0ab5aa..3e67506c392157e666590640838cd45774343b66 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java @@ -717,9 +717,9 @@ final class Long64Vector extends LongVector { @ForceInline /*package-private*/ static Long64Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Long64Mask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Long64Mask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Long64Mask TRUE_MASK = new Long64Mask(true); private static final Long64Mask FALSE_MASK = new Long64Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java index 23e9d9f3fb68eaec6ac2189d882314b6c0eb892f..2078dbec65b432adfb6dcb138dcf682180dcb0e9 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java @@ -717,9 +717,9 @@ final class LongMaxVector extends LongVector { @ForceInline /*package-private*/ static LongMaxMask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(LongMaxMask.class, long.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(LongMaxMask.class, long.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final LongMaxMask TRUE_MASK = new LongMaxMask(true); private static final LongMaxMask FALSE_MASK = new LongMaxMask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java index b48778f5ec3a3252302b3f27336fe36cd9166d08..365740c90c27878454bb8581432e33ff77f0e841 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java @@ -455,8 +455,8 @@ public abstract class LongVector extends AbstractVector { @ForceInline public static LongVector zero(VectorSpecies species) { LongSpecies vsp = (LongSpecies) species; - return VectorSupport.broadcastCoerced(vsp.vectorType(), long.class, species.length(), - 0, vsp, + return VectorSupport.fromBitsCoerced(vsp.vectorType(), long.class, species.length(), + 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -3809,9 +3809,9 @@ public abstract class LongVector extends AbstractVector { @ForceInline final LongVector broadcastBits(long bits) { return (LongVector) - VectorSupport.broadcastCoerced( + VectorSupport.fromBitsCoerced( vectorType, long.class, laneCount, - bits, this, + bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java index cd52dc003b6b8ab589785bf41769debbe6fc62d3..93bf40153a7e4cfc7110ba2fddc90c168b118956 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java @@ -741,9 +741,9 @@ final class Short128Vector extends ShortVector { @ForceInline /*package-private*/ static Short128Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Short128Mask.class, short.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Short128Mask.class, short.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Short128Mask TRUE_MASK = new Short128Mask(true); private static final Short128Mask FALSE_MASK = new Short128Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java index 66f6d409e6aed546271d27f5313c42220661209e..805f89bcdd932b1f52efe54ee879938e8f748483 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java @@ -757,9 +757,9 @@ final class Short256Vector extends ShortVector { @ForceInline /*package-private*/ static Short256Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Short256Mask.class, short.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Short256Mask.class, short.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Short256Mask TRUE_MASK = new Short256Mask(true); private static final Short256Mask FALSE_MASK = new Short256Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java index a2a8a07ddd3eddbe084fe6a8569c5645b12b941a..51d728529380e2b27013b09f889a64f776b7948e 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java @@ -789,9 +789,9 @@ final class Short512Vector extends ShortVector { @ForceInline /*package-private*/ static Short512Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Short512Mask.class, short.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Short512Mask.class, short.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Short512Mask TRUE_MASK = new Short512Mask(true); private static final Short512Mask FALSE_MASK = new Short512Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java index ff2b2d7e063f3736f9f6b674770f4ada350aa4d6..97ac8fe07cb91f51042cbcb317a4c5a4dcd86d1e 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java @@ -733,9 +733,9 @@ final class Short64Vector extends ShortVector { @ForceInline /*package-private*/ static Short64Mask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(Short64Mask.class, short.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(Short64Mask.class, short.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final Short64Mask TRUE_MASK = new Short64Mask(true); private static final Short64Mask FALSE_MASK = new Short64Mask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java index 7aa01264a738deb58b1137119745700289a8fcd6..c0ec9ee8b4ecccc5110ef2aa9710f20c9326e1a2 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java @@ -727,9 +727,9 @@ final class ShortMaxVector extends ShortVector { @ForceInline /*package-private*/ static ShortMaxMask maskAll(boolean bit) { - return VectorSupport.broadcastCoerced(ShortMaxMask.class, short.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced(ShortMaxMask.class, short.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final ShortMaxMask TRUE_MASK = new ShortMaxMask(true); private static final ShortMaxMask FALSE_MASK = new ShortMaxMask(false); diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java index e1cada48f17ac18350bd8e015133628a646a57d2..d527500bb1a48713eb2b91f57ce7a71870fffba2 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java @@ -455,8 +455,8 @@ public abstract class ShortVector extends AbstractVector { @ForceInline public static ShortVector zero(VectorSpecies species) { ShortSpecies vsp = (ShortSpecies) species; - return VectorSupport.broadcastCoerced(vsp.vectorType(), short.class, species.length(), - 0, vsp, + return VectorSupport.fromBitsCoerced(vsp.vectorType(), short.class, species.length(), + 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); } @@ -4143,9 +4143,9 @@ public abstract class ShortVector extends AbstractVector { @ForceInline final ShortVector broadcastBits(long bits) { return (ShortVector) - VectorSupport.broadcastCoerced( + VectorSupport.fromBitsCoerced( vectorType, short.class, laneCount, - bits, this, + bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java index b57a2abbb1f1600728cbcf4db048ab295ad2a447..506535d030f99b202dccd69475f32c7e99ae837a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java @@ -237,26 +237,25 @@ public abstract class VectorMask extends jdk.internal.vm.vector.VectorSupport */ @ForceInline public static VectorMask fromLong(VectorSpecies species, long bits) { - AbstractSpecies vspecies = (AbstractSpecies) species; - int laneCount = vspecies.laneCount(); - if (laneCount < Long.SIZE) { - int extraSignBits = Long.SIZE - laneCount; - bits <<= extraSignBits; - bits >>= extraSignBits; - } - if (bits == (bits >> 1)) { - // Special case. - assert(bits == 0 || bits == -1); - return vspecies.maskAll(bits != 0); - } - // FIXME: Intrinsify this. - long shifted = bits; - boolean[] a = new boolean[laneCount]; - for (int i = 0; i < a.length; i++) { - a[i] = ((shifted & 1) != 0); - shifted >>= 1; // replicate sign bit - } - return fromValues(vspecies, a); + AbstractSpecies vsp = (AbstractSpecies) species; + bits = bits & (0xFFFFFFFFFFFFFFFFL >>> (64 - vsp.laneCount())); + return VectorSupport.fromBitsCoerced(vsp.maskType(), vsp.elementType(), vsp.laneCount(), bits, + VectorSupport.MODE_BITS_COERCED_LONG_TO_MASK, vsp, + (m, s) -> { + if (m == (m >> 1)) { + // Special case. + assert(m == 0 || m == -1); + return s.maskAll(m != 0); + } + + long shifted = m; + boolean[] a = new boolean[s.laneCount()]; + for (int i = 0; i < a.length; i++) { + a[i] = ((shifted & 1) != 0); + shifted >>= 1; // replicate sign bit + } + return fromValues(s, a); + }); } /** diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template index 45c2cf9267c798f6a4f6d33b748ac7a0d8b33ce6..ae12e5fecffb767c8cf29f7c12604aafd0341d8d 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template @@ -470,12 +470,12 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { public static $abstractvectortype$ zero(VectorSpecies<$Boxtype$> species) { $Type$Species vsp = ($Type$Species) species; #if[FP] - return VectorSupport.broadcastCoerced(vsp.vectorType(), $type$.class, species.length(), - toBits(0.0f), vsp, + return VectorSupport.fromBitsCoerced(vsp.vectorType(), $type$.class, species.length(), + toBits(0.0f), MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); #else[FP] - return VectorSupport.broadcastCoerced(vsp.vectorType(), $type$.class, species.length(), - 0, vsp, + return VectorSupport.fromBitsCoerced(vsp.vectorType(), $type$.class, species.length(), + 0, MODE_BROADCAST, vsp, ((bits_, s_) -> s_.rvOp(i -> bits_))); #end[FP] } @@ -5327,9 +5327,9 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { @ForceInline final $abstractvectortype$ broadcastBits(long bits) { return ($abstractvectortype$) - VectorSupport.broadcastCoerced( + VectorSupport.fromBitsCoerced( vectorType, $type$.class, laneCount, - bits, this, + bits, MODE_BROADCAST, this, (bits_, s_) -> s_.rvOp(i -> bits_)); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template index df15c85fcccc301c668efa9d2dde61da4c11b6a3..2f1004f645039436642988e28d3b09b4da02044a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template @@ -1000,9 +1000,9 @@ final class $vectortype$ extends $abstractvectortype$ { @ForceInline /*package-private*/ static $masktype$ maskAll(boolean bit) { - return VectorSupport.broadcastCoerced($masktype$.class, $bitstype$.class, VLENGTH, - (bit ? -1 : 0), null, - (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); + return VectorSupport.fromBitsCoerced($masktype$.class, $bitstype$.class, VLENGTH, + (bit ? -1 : 0), MODE_BROADCAST, null, + (v, __) -> (v != 0 ? TRUE_MASK : FALSE_MASK)); } private static final $masktype$ TRUE_MASK = new $masktype$(true); private static final $masktype$ FALSE_MASK = new $masktype$(false); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java index 074882c9054fcd3e0dd91899a268174ab7639ac7..08bc0856d3ed664774d1d0cd79ff54ecb71f04a5 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java index 50f35021ac8ae272b771331165c5fa9666cf5856..2c9097839b6bc560c4f6f4d5b342ceaa7e8f3f35 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -849,7 +849,7 @@ final class CompilerToVM { /** * @see HotSpotJVMCIRuntime#translate(Object) */ - native long translate(Object obj); + native long translate(Object obj, boolean callPostTranslation); /** * @see HotSpotJVMCIRuntime#unhand(Class, long) diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java index b554f17397228af599fe85d9c069c5e76ebda550..3a6f28ce2a9ef588aca63abf96f1c086df27e98b 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCallingConventionType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java index 6c642e84bbd027c6eddaf6893cd182c7898d0514..6dfca075566530714d35c2e7d17edc21c10fdf0b 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java @@ -109,22 +109,12 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider { HotSpotCompiledCode hsCompiledCode = (HotSpotCompiledCode) compiledCode; String name = hsCompiledCode.getName(); HotSpotCompiledNmethod hsCompiledNmethod = null; - if (method == null) { - // Must be a stub - resultInstalledCode = new HotSpotRuntimeStub(name); - } else { - hsCompiledNmethod = (HotSpotCompiledNmethod) hsCompiledCode; - HotSpotResolvedJavaMethodImpl hsMethod = (HotSpotResolvedJavaMethodImpl) method; - resultInstalledCode = new HotSpotNmethod(hsMethod, name, isDefault, hsCompiledNmethod.id); - } - HotSpotSpeculationLog speculationLog = null; if (log != null) { if (log.hasSpeculations()) { speculationLog = (HotSpotSpeculationLog) log; } } - byte[] speculations; long failedSpeculationsAddress; if (speculationLog != null) { @@ -134,6 +124,18 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider { speculations = new byte[0]; failedSpeculationsAddress = 0L; } + + if (method == null) { + // Must be a stub + resultInstalledCode = new HotSpotRuntimeStub(name); + } else { + hsCompiledNmethod = (HotSpotCompiledNmethod) hsCompiledCode; + HotSpotResolvedJavaMethodImpl hsMethod = (HotSpotResolvedJavaMethodImpl) method; + HotSpotNmethod nmethod = new HotSpotNmethod(hsMethod, name, isDefault, hsCompiledNmethod.id); + nmethod.setSpeculationLog(speculationLog); + resultInstalledCode = nmethod; + } + int result = runtime.getCompilerToVM().installCode(target, (HotSpotCompiledCode) compiledCode, resultInstalledCode, failedSpeculationsAddress, speculations); if (result != config.codeInstallResultOk) { String resultDesc = config.getCodeInstallResultDescription(result); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java index c7bfc83401c14987c780f82f730166d1e73cda85..b15035dd5cc74b30cd65d13dea406600c7ac9b71 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,8 @@ import java.util.Map; import java.util.Objects; import java.util.ServiceLoader; import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import jdk.internal.misc.Unsafe; import jdk.vm.ci.code.Architecture; @@ -66,6 +68,7 @@ import jdk.vm.ci.runtime.JVMCICompiler; import jdk.vm.ci.runtime.JVMCICompilerFactory; import jdk.vm.ci.runtime.JVMCIRuntime; import jdk.vm.ci.services.JVMCIServiceLocator; +import jdk.vm.ci.services.Services; /** * HotSpot implementation of a JVMCI runtime. @@ -199,14 +202,44 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime { return result; } + /** + * Decodes the exception encoded in {@code buffer} and throws it. + * + * @param buffer a native byte buffer containing an exception encoded by + * {@link #encodeThrowable} + */ @VMEntryPoint - static Throwable decodeThrowable(String encodedThrowable) throws Throwable { - return TranslatedException.decodeThrowable(encodedThrowable); + static void decodeAndThrowThrowable(long buffer) throws Throwable { + Unsafe unsafe = UnsafeAccess.UNSAFE; + int encodingLength = unsafe.getInt(buffer); + byte[] encoding = new byte[encodingLength]; + unsafe.copyMemory(null, buffer + 4, encoding, Unsafe.ARRAY_BYTE_BASE_OFFSET, encodingLength); + throw TranslatedException.decodeThrowable(encoding); } + /** + * If {@code bufferSize} is large enough, encodes {@code throwable} into a byte array and writes + * it to {@code buffer}. The encoding in {@code buffer} can be decoded by + * {@link #decodeAndThrowThrowable}. + * + * @param throwable the exception to encode + * @param buffer a native byte buffer + * @param bufferSize the size of {@code buffer} in bytes + * @return the number of bytes written into {@code buffer} if {@code bufferSize} is large + * enough, otherwise {@code -N} where {@code N} is the value {@code bufferSize} needs to + * be to fit the encoding + */ @VMEntryPoint - static String encodeThrowable(Throwable throwable) throws Throwable { - return TranslatedException.encodeThrowable(throwable); + static int encodeThrowable(Throwable throwable, long buffer, int bufferSize) throws Throwable { + byte[] encoding = TranslatedException.encodeThrowable(throwable); + int requiredSize = 4 + encoding.length; + if (bufferSize < requiredSize) { + return -requiredSize; + } + Unsafe unsafe = UnsafeAccess.UNSAFE; + unsafe.putInt(buffer, encoding.length); + unsafe.copyMemory(encoding, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, buffer + 4, encoding.length); + return requiredSize; } @VMEntryPoint @@ -235,6 +268,10 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime { // Note: The following one is not used (see InitTimer.ENABLED). It is added here // so that -XX:+JVMCIPrintProperties shows the option. InitTimer(Boolean.class, false, "Specifies if initialization timing is enabled."), + ForceTranslateFailure(String.class, null, "Forces HotSpotJVMCIRuntime.translate to throw an exception in the context " + + "of the peer runtime. The value is a filter that can restrict the forced failure to matching translated " + + "objects. See HotSpotJVMCIRuntime.postTranslation for more details. This option exists soley to test " + + "correct handling of translation failure."), PrintConfig(Boolean.class, false, "Prints VM configuration available via JVMCI."), AuditHandles(Boolean.class, false, "Record stack trace along with scoped foreign object reference wrappers " + "to debug issue with a wrapper being used after its scope has closed."), @@ -1180,7 +1217,88 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime { * @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#global_and_local_references" */ public long translate(Object obj) { - return compilerToVm.translate(obj); + return compilerToVm.translate(obj, Option.ForceTranslateFailure.getString() != null); + } + + private static final Pattern FORCE_TRANSLATE_FAILURE_FILTER_RE = Pattern.compile("(?:(method|type|nmethod)/)?([^:]+)(?::(hotspot|native))?"); + + /** + * Forces translation failure based on {@code translatedObject} and the value of + * {@link Option#ForceTranslateFailure}. The value is zero or more filters separated by a comma. + * The syntax for a filter is: + * + *
          +     *   Filter = [ TypeSelector "/" ] Substring [ ":" JVMCIEnvSelector ] .
          +     *   TypeSelector = "type" | "method" | "nmethod"
          +     *   JVMCIEnvSelector = "native" | "hotspot"
          +     * 
          + * + * For example: + * + *
          +     *   -Djvmci.ForceTranslateFailure=nmethod/StackOverflowError:native,method/computeHash,execute
          +     * 
          + * + * will cause failure of: + *
            + *
          • translating a {@link HotSpotNmethod} to the libjvmci heap whose fully qualified name + * contains "StackOverflowError"
          • + *
          • translating a {@link HotSpotResolvedJavaMethodImpl} to the libjvmci or HotSpot heap whose + * fully qualified name contains "computeHash"
          • + *
          • translating a {@link HotSpotNmethod}, {@link HotSpotResolvedJavaMethodImpl} or + * {@link HotSpotResolvedObjectTypeImpl} to the libjvmci or HotSpot heap whose fully qualified + * name contains "execute"
          • + *
          + */ + @VMEntryPoint + static void postTranslation(Object translatedObject) { + String value = Option.ForceTranslateFailure.getString(); + String toMatch; + String type; + if (translatedObject instanceof HotSpotResolvedJavaMethodImpl) { + toMatch = ((HotSpotResolvedJavaMethodImpl) translatedObject).format("%H.%n"); + type = "method"; + } else if (translatedObject instanceof HotSpotResolvedObjectTypeImpl) { + toMatch = ((HotSpotResolvedObjectTypeImpl) translatedObject).toJavaName(); + type = "type"; + } else if (translatedObject instanceof HotSpotNmethod) { + HotSpotNmethod nmethod = (HotSpotNmethod) translatedObject; + if (nmethod.getMethod() != null) { + toMatch = nmethod.getMethod().format("%H.%n"); + } else { + toMatch = String.valueOf(nmethod.getName()); + } + type = "nmethod"; + } else { + return; + } + String[] filters = value.split(","); + for (String filter : filters) { + Matcher m = FORCE_TRANSLATE_FAILURE_FILTER_RE.matcher(filter); + if (!m.matches()) { + throw new JVMCIError(Option.ForceTranslateFailure + " filter does not match " + FORCE_TRANSLATE_FAILURE_FILTER_RE + ": " + filter); + } + String typeSelector = m.group(1); + String substring = m.group(2); + String jvmciEnvSelector = m.group(3); + if (jvmciEnvSelector != null) { + if (jvmciEnvSelector.equals("native")) { + if (!Services.IS_IN_NATIVE_IMAGE) { + continue; + } + } else { + if (Services.IS_IN_NATIVE_IMAGE) { + continue; + } + } + } + if (typeSelector != null && !typeSelector.equals(type)) { + continue; + } + if (toMatch.contains(substring)) { + throw new JVMCIError("translation of " + translatedObject + " failed due to matching " + Option.ForceTranslateFailure + " filter \"" + filter + "\""); + } + } } /** diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java index 99fd3016f9834eb7ec54a3e2294901126c7bdb24..a18f7b556fafaacf04f27f1acccc37f989ea0c8e 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java @@ -68,8 +68,8 @@ public class HotSpotNmethod extends HotSpotInstalledCode { /** * If this field is 0, this object is in the oops table of the nmethod. Otherwise, the value of - * the field records the nmethod's compile identifier. This value is used to confirm an entry in - * the code cache retrieved by {@link #address} is indeed the nmethod represented by this + * the field records the nmethod's compile identifier. This value is used to confirm if an entry + * in the code cache retrieved by {@link #address} is indeed the nmethod represented by this * object. * * @see #inOopsTable @@ -85,6 +85,23 @@ public class HotSpotNmethod extends HotSpotInstalledCode { assert inOopsTable || compileId != 0L : this; } + /** + * Attaches {@code log} to this object. If {@code log.managesFailedSpeculations() == true}, this + * ensures the failed speculation list lives at least as long as this object. + */ + public void setSpeculationLog(HotSpotSpeculationLog log) { + this.speculationLog = log; + } + + /** + * The speculation log containing speculations embedded in the nmethod. + * + * If {@code speculationLog.managesFailedSpeculations() == true}, this field ensures the failed + * speculation list lives at least as long as this object. This prevents deoptimization from + * appending to an already freed list. + */ + @SuppressWarnings("unused") private HotSpotSpeculationLog speculationLog; + /** * Determines if the nmethod associated with this object is the compiled entry point for * {@link #getMethod()}. diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java index 1a477cf02b08507d2b00bbb33c089be969ea76ff..927dbed4297d16c4957ce687fa2ca412010bfd51 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -336,7 +336,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess { final int deoptReasonLoopLimitCheck = getConstant("Deoptimization::Reason_loop_limit_check", Integer.class); final int deoptReasonAliasing = getConstant("Deoptimization::Reason_aliasing", Integer.class); final int deoptReasonTransferToInterpreter = getConstant("Deoptimization::Reason_transfer_to_interpreter", Integer.class); - final int deoptReasonOSROffset = getConstant("Deoptimization::Reason_LIMIT", Integer.class); + final int deoptReasonOSROffset = getConstant("Deoptimization::Reason_TRAP_HISTORY_LENGTH", Integer.class); final int deoptActionNone = getConstant("Deoptimization::Action_none", Integer.class); final int deoptActionMaybeRecompile = getConstant("Deoptimization::Action_maybe_recompile", Integer.class); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java index a47735faf802006bf72031dc60ba6c5b6f235ec1..53f99733ba93f86d27059f525f7038a58f26598d 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * 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,13 +22,20 @@ */ package jdk.vm.ci.hotspot; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Formatter; import java.util.List; -import java.util.Objects; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import jdk.vm.ci.common.JVMCIError; /** * Support for translating exceptions between different runtime heaps. @@ -36,6 +43,26 @@ import java.util.Objects; @SuppressWarnings("serial") final class TranslatedException extends Exception { + /** + * The value returned by {@link #encodeThrowable(Throwable)} when encoding fails due to an + * {@link OutOfMemoryError}. + */ + private static final byte[] FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES; + + /** + * The value returned by {@link #encodeThrowable(Throwable)} when encoding fails for any reason + * other than {@link OutOfMemoryError}. + */ + private static final byte[] FALLBACK_ENCODED_THROWABLE_BYTES; + static { + try { + FALLBACK_ENCODED_THROWABLE_BYTES = encodeThrowable(new TranslatedException("error during encoding", ""), false); + FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES = encodeThrowable(new OutOfMemoryError(), false); + } catch (IOException e) { + throw new JVMCIError(e); + } + } + /** * Class name of exception that could not be instantiated. */ @@ -110,83 +137,74 @@ final class TranslatedException extends Exception { } } - /** - * Encodes an exception message to distinguish a null message from an empty message. - * - * @return {@code value} with a space prepended iff {@code value != null} - */ - private static String encodeMessage(String value) { - return value != null ? ' ' + value : value; - } - - private static String decodeMessage(String value) { - if (value.length() == 0) { - return null; - } - return value.substring(1); + private static String emptyIfNull(String value) { + return value == null ? "" : value; } - private static String encodedString(String value) { - return Objects.toString(value, "").replace('|', '_'); + private static String emptyAsNull(String value) { + return value.isEmpty() ? null : value; } /** - * Encodes {@code throwable} including its stack and causes as a string. The encoding format of - * a single exception is: - * - *
          -     *  '|'  '|'  '|' [  '|'  '|'  '|'  '|'  '|'  '|'  '|' ]*
          -     * 
          - * - * Each exception is encoded before the exception it causes. + * Encodes {@code throwable} including its stack and causes as a {@linkplain GZIPOutputStream + * compressed} byte array that can be decoded by {@link #decodeThrowable}. */ @VMEntryPoint - static String encodeThrowable(Throwable throwable) throws Throwable { + static byte[] encodeThrowable(Throwable throwable) throws Throwable { try { - Formatter enc = new Formatter(); + return encodeThrowable(throwable, true); + } catch (OutOfMemoryError e) { + return FALLBACK_ENCODED_OUTOFMEMORYERROR_BYTES; + } catch (Throwable e) { + return FALLBACK_ENCODED_THROWABLE_BYTES; + } + } + + private static byte[] encodeThrowable(Throwable throwable, boolean withCauseAndStack) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(new GZIPOutputStream(baos))) { List throwables = new ArrayList<>(); for (Throwable current = throwable; current != null; current = current.getCause()) { throwables.add(current); + if (!withCauseAndStack) { + break; + } } // Encode from inner most cause outwards Collections.reverse(throwables); for (Throwable current : throwables) { - enc.format("%s|%s|", current.getClass().getName(), encodedString(encodeMessage(current.getMessage()))); - StackTraceElement[] stackTrace = current.getStackTrace(); + dos.writeUTF(current.getClass().getName()); + dos.writeUTF(emptyIfNull(current.getMessage())); + StackTraceElement[] stackTrace = withCauseAndStack ? current.getStackTrace() : null; if (stackTrace == null) { stackTrace = new StackTraceElement[0]; } - enc.format("%d|", stackTrace.length); + dos.writeInt(stackTrace.length); for (int i = 0; i < stackTrace.length; i++) { StackTraceElement frame = stackTrace[i]; if (frame != null) { - enc.format("%s|%s|%s|%s|%s|%s|%d|", encodedString(frame.getClassLoaderName()), - encodedString(frame.getModuleName()), encodedString(frame.getModuleVersion()), - frame.getClassName(), frame.getMethodName(), - encodedString(frame.getFileName()), frame.getLineNumber()); + dos.writeUTF(emptyIfNull(frame.getClassLoaderName())); + dos.writeUTF(emptyIfNull(frame.getModuleName())); + dos.writeUTF(emptyIfNull(frame.getModuleVersion())); + dos.writeUTF(emptyIfNull(frame.getClassName())); + dos.writeUTF(emptyIfNull(frame.getMethodName())); + dos.writeUTF(emptyIfNull(frame.getFileName())); + dos.writeInt(frame.getLineNumber()); } } } - return enc.toString(); - } catch (Throwable e) { - assert printStackTrace(e); - try { - return e.getClass().getName() + "|" + encodedString(e.getMessage()) + "|0|"; - } catch (Throwable e2) { - assert printStackTrace(e2); - return "java.lang.Throwable|too many errors during encoding|0|"; - } } + return baos.toByteArray(); } /** * Gets the stack of the current thread without the frames between this call and the one just - * below the frame of the first method in {@link CompilerToVM}. The chopped frames are specific - * to the implementation of {@link HotSpotJVMCIRuntime#decodeThrowable(String)}. + * below the frame of the first method in {@link CompilerToVM}. The chopped frames are for the + * VM call to {@link HotSpotJVMCIRuntime#decodeAndThrowThrowable}. */ - private static StackTraceElement[] getStackTraceSuffix() { + private static StackTraceElement[] getMyStackTrace() { StackTraceElement[] stack = new Exception().getStackTrace(); for (int i = 0; i < stack.length; i++) { StackTraceElement e = stack[i]; @@ -206,43 +224,47 @@ final class TranslatedException extends Exception { * {@link #encodeThrowable} */ @VMEntryPoint - static Throwable decodeThrowable(String encodedThrowable) { - try { - int i = 0; - String[] parts = encodedThrowable.split("\\|"); + static Throwable decodeThrowable(byte[] encodedThrowable) { + try (DataInputStream dis = new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(encodedThrowable)))) { Throwable cause = null; Throwable throwable = null; - while (i != parts.length) { - String exceptionClassName = parts[i++]; - String exceptionMessage = decodeMessage(parts[i++]); + StackTraceElement[] myStack = getMyStackTrace(); + while (dis.available() != 0) { + String exceptionClassName = dis.readUTF(); + String exceptionMessage = emptyAsNull(dis.readUTF()); throwable = create(exceptionClassName, exceptionMessage, cause); - int stackTraceDepth = Integer.parseInt(parts[i++]); - - StackTraceElement[] suffix = getStackTraceSuffix(); - StackTraceElement[] stackTrace = new StackTraceElement[stackTraceDepth + suffix.length]; + int stackTraceDepth = dis.readInt(); + StackTraceElement[] stackTrace = new StackTraceElement[stackTraceDepth + myStack.length]; + int stackTraceIndex = 0; + int myStackIndex = 0; for (int j = 0; j < stackTraceDepth; j++) { - String classLoaderName = parts[i++]; - String moduleName = parts[i++]; - String moduleVersion = parts[i++]; - String className = parts[i++]; - String methodName = parts[i++]; - String fileName = parts[i++]; - int lineNumber = Integer.parseInt(parts[i++]); - if (classLoaderName.isEmpty()) { - classLoaderName = null; - } - if (moduleName.isEmpty()) { - moduleName = null; - } - if (moduleVersion.isEmpty()) { - moduleVersion = null; - } - if (fileName.isEmpty()) { - fileName = null; + String classLoaderName = emptyAsNull(dis.readUTF()); + String moduleName = emptyAsNull(dis.readUTF()); + String moduleVersion = emptyAsNull(dis.readUTF()); + String className = emptyAsNull(dis.readUTF()); + String methodName = emptyAsNull(dis.readUTF()); + String fileName = emptyAsNull(dis.readUTF()); + int lineNumber = dis.readInt(); + StackTraceElement ste = new StackTraceElement(classLoaderName, moduleName, moduleVersion, className, methodName, fileName, lineNumber); + + if (ste.isNativeMethod()) { + // Best effort attempt to weave stack traces from two heaps into + // a single stack trace using native method frames as stitching points. + // This is not 100% reliable as there's no guarantee that native method + // frames only exist for calls between HotSpot and libjvmci. + while (myStackIndex < myStack.length) { + StackTraceElement suffixSTE = myStack[myStackIndex++]; + if (suffixSTE.isNativeMethod()) { + break; + } + stackTrace[stackTraceIndex++] = suffixSTE; + } } - stackTrace[j] = new StackTraceElement(classLoaderName, moduleName, moduleVersion, className, methodName, fileName, lineNumber); + stackTrace[stackTraceIndex++] = ste; + } + while (myStackIndex < myStack.length) { + stackTrace[stackTraceIndex++] = myStack[myStackIndex++]; } - System.arraycopy(suffix, 0, stackTrace, stackTraceDepth, suffix.length); throwable.setStackTrace(stackTrace); cause = throwable; } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java index 61b0f949655b442c0f43bf064424c0ac9327a4dc..afdff7a88901b6b2d67c653d78911c6ec5391361 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/UnsafeAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java index c7cc38959877642fd49845808aee74d815001078..63002463fb595ff971266cc165957044459ce968 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Constant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java index bcefe66cc79151783ccaa11f4309f39674c75c88..36c422beda59b108a894ffaf3215f03675c7ce60 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DeoptimizationReason.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java index afaa0f635c6efd03447da74a3ba44998b5869252..d22d7a9d622d7b44acc657240d10faeb0c02885c 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/InvokeTarget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java index c533123ccd84d24ac894962bcd9951b0fa3ac57d..0faa2af57047457248331015120846cb3e20c3ae 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java index 2ba915c9892714d763bc6f5dfa0403dd42fa2cc5..7eaa8e966705652037085a9190915194a8fd57cb 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ProfilingInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java index e7b0484dbd3188e8db8e96f85cfcc5d3e3638027..ecd15057e97693a4ea88415b82c26d98717835b6 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index e24d53425a8e99c2de0f48e16b67ff285b3a078b..8758b99e18e1403bfa3967c0ac099352f998cb16 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -834,9 +834,9 @@ public class Main { } // Only used when -verbose provided - StringBuffer sb = null; + StringBuilder sb = null; if (verbose != null) { - sb = new StringBuffer(); + sb = new StringBuilder(); boolean inManifest = ((man.getAttributes(name) != null) || (man.getAttributes("./"+name) != null) || diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java b/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java index bcc4bb32f066af93b2951529842e234a37c4bddc..8686210b209bdc8c6ddb56d5633a76cd0c99076d 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java @@ -34,12 +34,21 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import jdk.internal.module.ModulePath; import jdk.internal.module.ModuleResolution; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; /** * Parser for GNU Style Options. */ class GNUStyleOptions { + // Valid --date range + static final ZonedDateTime DATE_MIN = ZonedDateTime.parse("1980-01-01T00:00:02Z"); + static final ZonedDateTime DATE_MAX = ZonedDateTime.parse("2099-12-31T23:59:59Z"); + static class BadArgs extends Exception { static final long serialVersionUID = 0L; @@ -188,6 +197,20 @@ class GNUStyleOptions { jartool.flag0 = true; } }, + new Option(true, OptionType.CREATE_UPDATE_INDEX, "--date") { + void process(Main jartool, String opt, String arg) throws BadArgs { + try { + ZonedDateTime date = ZonedDateTime.parse(arg, DateTimeFormatter.ISO_ZONED_DATE_TIME) + .withZoneSameInstant(ZoneOffset.UTC); + if (date.isBefore(DATE_MIN) || date.isAfter(DATE_MAX)) { + throw new BadArgs("error.date.out.of.range", arg); + } + jartool.date = date.toLocalDateTime(); + } catch (DateTimeParseException x) { + throw new BadArgs("error.date.notvalid", arg); + } + } + }, // Hidden options new Option(false, OptionType.OTHER, "-P") { diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java index 4e6df7e39bf402850243d1c1d76e46dc7d8f3590..3436c01928b98c3957b99c29705c56b712eaefa2 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java @@ -60,6 +60,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; +import java.util.concurrent.TimeUnit; import jdk.internal.module.Checks; import jdk.internal.module.ModuleHashes; import jdk.internal.module.ModuleHashesBuilder; @@ -68,6 +69,8 @@ import jdk.internal.module.ModuleInfoExtender; import jdk.internal.module.ModuleResolution; import jdk.internal.module.ModuleTarget; import jdk.internal.util.jar.JarIndex; +import java.time.LocalDateTime; +import java.time.ZoneOffset; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static java.util.jar.JarFile.MANIFEST_NAME; @@ -174,6 +177,9 @@ public class Main { static final int VERSIONS_DIR_LENGTH = VERSIONS_DIR.length(); private static ResourceBundle rsrc; + /* Date option for entry timestamps resolved to UTC Local time */ + LocalDateTime date; + /** * If true, maintain compatibility with JDK releases prior to 6.0 by * timestamping extracted files with the time at which they are extracted. @@ -862,12 +868,12 @@ public class Main { output(getMsg("out.added.manifest")); } ZipEntry e = new ZipEntry(MANIFEST_DIR); - e.setTime(System.currentTimeMillis()); + setZipEntryTime(e); e.setSize(0); e.setCrc(0); zos.putNextEntry(e); e = new ZipEntry(MANIFEST_NAME); - e.setTime(System.currentTimeMillis()); + setZipEntryTime(e); if (flag0) { crc32Manifest(e, manifest); } @@ -967,7 +973,7 @@ public class Main { // do our own compression ZipEntry e2 = new ZipEntry(name); e2.setMethod(e.getMethod()); - e2.setTime(e.getTime()); + setZipEntryTime(e2, e.getTime()); e2.setComment(e.getComment()); e2.setExtra(e.getExtra()); if (e.getMethod() == ZipEntry.STORED) { @@ -1033,7 +1039,7 @@ public class Main { throws IOException { ZipEntry e = new ZipEntry(INDEX_NAME); - e.setTime(System.currentTimeMillis()); + setZipEntryTime(e); if (flag0) { CRC32OutputStream os = new CRC32OutputStream(); index.write(os); @@ -1055,9 +1061,9 @@ public class Main { ZipEntry e = new ZipEntry(name); FileTime lastModified = mie.getLastModifiedTime(); if (lastModified != null) { - e.setLastModifiedTime(lastModified); + setZipEntryTime(e, lastModified.toMillis()); } else { - e.setLastModifiedTime(FileTime.fromMillis(System.currentTimeMillis())); + setZipEntryTime(e); } if (flag0) { crc32ModuleInfo(e, bytes); @@ -1083,7 +1089,7 @@ public class Main { addMultiRelease(m); } ZipEntry e = new ZipEntry(MANIFEST_NAME); - e.setTime(System.currentTimeMillis()); + setZipEntryTime(e); if (flag0) { crc32Manifest(e, m); } @@ -1204,7 +1210,7 @@ public class Main { out.print(formatMsg("out.adding", name)); } ZipEntry e = new ZipEntry(name); - e.setTime(file.lastModified()); + setZipEntryTime(e, file.lastModified()); if (size == 0) { e.setMethod(ZipEntry.STORED); e.setSize(0); @@ -2318,4 +2324,18 @@ public class Main { static Comparator ENTRY_COMPARATOR = Comparator.comparing(ZipEntry::getName, ENTRYNAME_COMPARATOR); + // Set the ZipEntry dostime using date if specified otherwise the current time + private void setZipEntryTime(ZipEntry e) { + setZipEntryTime(e, System.currentTimeMillis()); + } + + // Set the ZipEntry dostime using the date if specified + // otherwise the original time + private void setZipEntryTime(ZipEntry e, long origTime) { + if (date != null) { + e.setTimeLocal(date); + } else { + e.setTime(origTime); + } + } } diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties index 61b9ecc241299d08ae9754982b142b4613ddeafa..87bff6891029f7f05293c15fafc6bd5e8c76b0b3 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties +++ b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -82,6 +82,10 @@ error.release.value.toosmall=\ release {0} not valid, must be >= 9 error.release.unexpected.versioned.entry=\ unexpected versioned entry {0} for release {1} +error.date.notvalid=\ + date {0} is not a valid ISO-8601 extended offset date-time with optional time-zone +error.date.out.of.range=\ + date {0} is not within the valid range 1980-01-01T00:00:02Z to 2099-12-31T23:59:59Z error.validator.jarfile.exception=\ can not validate {0}: {1} error.validator.jarfile.invalid=\ @@ -290,6 +294,10 @@ main.help.opt.create.update.index=\ \ Operation modifiers valid only in create, update, and generate-index mode:\n main.help.opt.create.update.index.no-compress=\ \ -0, --no-compress Store only; use no ZIP compression +main.help.opt.create.update.index.date=\ +\ --date=TIMESTAMP The timestamp in ISO-8601 extended offset date-time with\n\ +\ optional time-zone format, to use for the timestamps of\n\ +\ entries, e.g. "2022-02-12T12:30:00-05:00" main.help.opt.other=\ \ Other options:\n main.help.opt.other.help=\ diff --git a/src/jdk.jartool/share/man/jar.1 b/src/jdk.jartool/share/man/jar.1 index 4a8c8f4ae6697fdbd7dadafc2ad4ff685e389ea9..fd134fe1467b0498f596924f082999597e96bd55 100644 --- a/src/jdk.jartool/share/man/jar.1 +++ b/src/jdk.jartool/share/man/jar.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAR" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JAR" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jartool/share/man/jarsigner.1 b/src/jdk.jartool/share/man/jarsigner.1 index 592a64ed8360dbcbedf35f801f8c518dec0b3f92..bcf457fb6f65603e70b40af8bc5150667766e584 100644 --- a/src/jdk.jartool/share/man/jarsigner.1 +++ b/src/jdk.jartool/share/man/jarsigner.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. .\" 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,7 +22,7 @@ .\"t .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JARSIGNER" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JARSIGNER" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP @@ -33,6 +33,8 @@ jarsigner \- sign and verify Java Archive (JAR) files .PP \f[CB]jarsigner\f[R] \f[CB]\-verify\f[R] [\f[I]options\f[R]] \f[I]jar\-file\f[R] [\f[I]alias\f[R] ...] +.PP +\f[CB]jarsigner\f[R] \f[CB]\-version\f[R] .TP .B \f[I]options\f[R] The command\-line options. @@ -69,6 +71,12 @@ The aliases are defined in the keystore specified by \f[CB]\-keystore\f[R] or the default keystore. .RS .RE +.TP +.B \f[CB]\-version\f[R] +The \f[CB]\-version\f[R] option prints the program version of +\f[CB]jarsigner\f[R]. +.RS +.RE .SH DESCRIPTION .PP The \f[CB]jarsigner\f[R] tool has two purposes: @@ -1079,6 +1087,11 @@ The property keys supported are "jarsigner.all" for all actions, name(s) cannot be set in this file. .RS .RE +.TP +.B \f[CB]\-version\f[R] +Prints the program version. +.RS +.RE .SH DEPRECATED OPTIONS .PP The following \f[CB]jarsigner\f[R] options are deprecated as of JDK 9 and diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java b/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java index 2e895024b93db50d4d35fbdef547fb987a4a5678..3658ed74d85febdcef6be556e1a0b49925ad7c3f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,9 +51,9 @@ * The invocation is defined by the interface {@link jdk.javadoc.doclet.Doclet} * -- the {@link jdk.javadoc.doclet.Doclet#run(DocletEnvironment) run} interface * method, defines the entry point. - *
          - *    public boolean run(DocletEnvironment environment)
          - * 
          + * {@snippet id="entry-point" lang=java : + * public boolean run(DocletEnvironment environment) // @highlight substring="run" + * } * The {@link jdk.javadoc.doclet.DocletEnvironment} instance holds the * environment that the doclet will be initialized with. From this environment * all other information can be extracted, in the form of @@ -185,120 +185,147 @@ * * The following is an example doclet that displays information of a class * and its members, supporting an option. - *
          - * // note imports deleted for clarity
          + *
          + * {@snippet lang=java id="Example.java" :
          + * // @replace region=imports replacement=" // Note: imports deleted for clarity"
          + * import com.sun.source.doctree.DocCommentTree;
          + * import com.sun.source.util.DocTrees;
          + * import jdk.javadoc.doclet.Doclet;
          + * import jdk.javadoc.doclet.DocletEnvironment;
          + * import jdk.javadoc.doclet.Reporter;
          + *
          + * import javax.lang.model.SourceVersion;
          + * import javax.lang.model.element.Element;
          + * import javax.lang.model.element.TypeElement;
          + * import javax.lang.model.util.ElementFilter;
          + * import javax.tools.Diagnostic.Kind;
          + * import java.io.IOException;
          + * import java.io.PrintWriter;
          + * import java.util.List;
          + * import java.util.Locale;
          + * import java.util.Set;
          + * // @end
          + *
          + *
            * public class Example implements Doclet {
          - *    Reporter reporter;
          - *    @Override
          - *    public void init(Locale locale, Reporter reporter) {
          - *        reporter.print(Kind.NOTE, "Doclet using locale: " + locale);
          - *        this.reporter = reporter;
          - *    }
          - *
          - *    public void printElement(DocTrees trees, Element e) {
          - *        DocCommentTree docCommentTree = trees.getDocCommentTree(e);
          - *        if (docCommentTree != null) {
          - *            System.out.println("Element (" + e.getKind() + ": "
          - *                    + e + ") has the following comments:");
          - *            System.out.println("Entire body: " + docCommentTree.getFullBody());
          - *            System.out.println("Block tags: " + docCommentTree.getBlockTags());
          - *        }
          - *    }
          - *
          - *    @Override
          - *    public boolean run(DocletEnvironment docEnv) {
          - *        reporter.print(Kind.NOTE, "overviewfile: " + overviewfile);
          - *        // get the DocTrees utility class to access document comments
          - *        DocTrees docTrees = docEnv.getDocTrees();
          - *
          - *        // location of an element in the same directory as overview.html
          - *        try {
          - *            Element e = ElementFilter.typesIn(docEnv.getSpecifiedElements()).iterator().next();
          - *            DocCommentTree docCommentTree
          - *                    = docTrees.getDocCommentTree(e, overviewfile);
          - *            if (docCommentTree != null) {
          - *                System.out.println("Overview html: " + docCommentTree.getFullBody());
          - *            }
          - *        } catch (IOException missing) {
          - *            reporter.print(Kind.ERROR, "No overview.html found.");
          - *        }
          - *
          - *        for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) {
          - *            System.out.println(t.getKind() + ":" + t);
          - *            for (Element e : t.getEnclosedElements()) {
          - *                printElement(docTrees, e);
          - *            }
          - *        }
          - *        return true;
          - *    }
          - *
          - *    @Override
          - *    public String getName() {
          - *        return "Example";
          - *    }
          - *
          - *    private String overviewfile;
          - *
          - *    @Override
          - *    public Set<? extends Option> getSupportedOptions() {
          - *        Option[] options = {
          - *            new Option() {
          - *                private final List<String> someOption = Arrays.asList(
          - *                        "-overviewfile",
          - *                        "--overview-file",
          - *                        "-o"
          - *                );
          - *
          - *                @Override
          - *                public int getArgumentCount() {
          - *                    return 1;
          - *                }
          - *
          - *                @Override
          - *                public String getDescription() {
          - *                    return "an option with aliases";
          - *                }
          - *
          - *                @Override
          - *                public Option.Kind getKind() {
          - *                    return Option.Kind.STANDARD;
          - *                }
          - *
          - *                @Override
          - *                public List<String> getNames() {
          - *                    return someOption;
          - *                }
          - *
          - *                @Override
          - *                public String getParameters() {
          - *                    return "file";
          - *                }
          - *
          - *                @Override
          - *                public boolean process(String opt, List<String> arguments) {
          - *                    overviewfile = arguments.get(0);
          - *                    return true;
          - *                }
          - *            }
          - *        };
          - *        return new HashSet<>(Arrays.asList(options));
          - *    }
          - *
          - *    @Override
          - *    public SourceVersion getSupportedSourceVersion() {
          - *        // support the latest release
          - *        return SourceVersion.latest();
          - *    }
          + *     private Reporter reporter;
          + *     private PrintWriter stdout;
          + *
          + *     @Override
          + *     public void init(Locale locale, Reporter reporter) {
          + *         reporter.print(Kind.NOTE, "Doclet using locale: " + locale);
          + *         this.reporter = reporter;
          + *         stdout = reporter.getStandardWriter();
          + *     }
          + *
          + *     public void printElement(DocTrees trees, Element e) {
          + *         DocCommentTree docCommentTree = trees.getDocCommentTree(e);
          + *         if (docCommentTree != null) {
          + *             stdout.println("Element (" + e.getKind() + ": "
          + *                     + e + ") has the following comments:");
          + *             stdout.println("Entire body: " + docCommentTree.getFullBody());
          + *             stdout.println("Block tags: " + docCommentTree.getBlockTags());
          + *         }
          + *     }
          + *
          + *     @Override
          + *     public boolean run(DocletEnvironment docEnv) {
          + *         reporter.print(Kind.NOTE, "overviewFile: " + overviewFile);
          + *
          + *         // get the DocTrees utility class to access document comments
          + *         DocTrees docTrees = docEnv.getDocTrees();
          + *
          + *         // location of an element in the same directory as overview.html
          + *         try {
          + *             Element e = ElementFilter.typesIn(docEnv.getSpecifiedElements()).iterator().next();
          + *             DocCommentTree docCommentTree
          + *                     = docTrees.getDocCommentTree(e, overviewFile);
          + *             if (docCommentTree != null) {
          + *                 stdout.println("Overview html: " + docCommentTree.getFullBody());
          + *             }
          + *         } catch (IOException missing) {
          + *             reporter.print(Kind.ERROR, "No overview.html found.");
          + *         }
          + *
          + *         for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) {
          + *             stdout.println(t.getKind() + ":" + t);
          + *             for (Element e : t.getEnclosedElements()) {
          + *                 printElement(docTrees, e);
          + *             }
          + *         }
          + *         return true;
          + *     }
          + *
          + *     @Override
          + *     public String getName() {
          + *         return "Example";
          + *     }
          + *
          + *     private String overviewFile;
          + *
          + *     @Override
          + *     public Set getSupportedOptions() {
          + *         Option[] options = {
          + *             new Option() {
          + *                 private final List someOption = List.of(
          + *                         "--overview-file",
          + *                         "-overviewfile",
          + *                         "-o"
          + *                 );
          + *
          + *                 @Override
          + *                 public int getArgumentCount() {
          + *                     return 1;
          + *                 }
          + *
          + *                 @Override
          + *                 public String getDescription() {
          + *                     return "an option with aliases";
          + *                 }
          + *
          + *                 @Override
          + *                 public Option.Kind getKind() {
          + *                     return Option.Kind.STANDARD;
          + *                 }
          + *
          + *                 @Override
          + *                 public List getNames() {
          + *                     return someOption;
          + *                 }
          + *
          + *                 @Override
          + *                 public String getParameters() {
          + *                     return "file";
          + *                 }
          + *
          + *                 @Override
          + *                 public boolean process(String opt, List arguments) {
          + *                     overviewFile = arguments.get(0);
          + *                     return true;
          + *                 }
          + *             }
          + *         };
          + *
          + *         return Set.of(options);
          + *     }
          + *
          + *     @Override
          + *     public SourceVersion getSupportedSourceVersion() {
          + *         // support the latest release
          + *         return SourceVersion.latest();
          + *     }
          + * }
            * }
          - * 
          + * *

          * This doclet can be invoked with a command line, such as: - *

          - *     javadoc -doclet Example \
          - *       -overviewfile overview.html \
          - *       -sourcepath source-location \
          - *       source-location/Example.java
          - * 
          + * {@snippet id="run-doclet": + * javadoc -docletpath doclet-classes \ // @highlight substring="doclet-classes " type=italic + * -doclet Example \ + * --overview-file overview.html \ + * --source-path source-location \ // @highlight region substring="source-location" type=italic + * source-location/Example.java // @end + * } * *

          Migration Guide

          * diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java index f91b06105a3a82d8043a6e1e6cd4be4123e74e5e..840676e875cab6ec486a4f948ddd24605c8e2004 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -296,8 +296,7 @@ public class ClassUseWriter extends SubWriterHolderWriter { * @param contentTree the content tree to which the class elements will be added */ protected void addClassList(Content contentTree) { - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); + HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList); for (PackageElement pkg : pkgSet) { HtmlTree htmlTree = HtmlTree.SECTION(HtmlStyle.detail) .setId(htmlIds.forPackage(pkg)); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java index 40db035c8b9a4263672d9c29545ebbf5c65d65d2..3b1b8537bf0a6933a8c1bdb816fded501f9ad8b6 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,8 +105,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite @Override public Content getHeader(String header) { HtmlTree bodyTree = getBody(getWindowTitle(utils.getSimpleName(typeElement))); - HtmlTree div = new HtmlTree(TagName.DIV); - div.setStyle(HtmlStyle.header); + HtmlTree div = HtmlTree.DIV(HtmlStyle.header); if (configuration.showModules) { ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(typeElement); Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInType, contents.moduleLabel); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java index 2bd163b24de86046c962b2522202ea4248682ef0..1723bc6ecfd5a93650116abae9618c3b4c8947ef 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -165,9 +165,7 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons @Override public Content getClassConstantHeader() { - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); - return ul; + return HtmlTree.UL(HtmlStyle.blockList); } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java index 167b24b622b8ede28cd7ab7bcde464eccdfb8e7d..11ed54c2d864f4eb9c6873b3533ea921a0194238 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -128,9 +128,7 @@ public class HelpWriter extends HtmlDocletWriter { *
        */ protected void addHelpFileContents(Content contentTree) { - HtmlTree mainTOC = new HtmlTree(TagName.UL).setStyle(HtmlStyle.helpTOC); - - + HtmlTree mainTOC = HtmlTree.UL(HtmlStyle.helpTOC); contentTree.add(HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, HtmlStyle.title, getContent("doclet.help.main_heading"))) @@ -185,7 +183,7 @@ public class HelpWriter extends HtmlDocletWriter { } content.add(navSection); - HtmlTree subTOC = new HtmlTree(TagName.UL).setStyle(HtmlStyle.helpSubTOC); + HtmlTree subTOC = HtmlTree.UL(HtmlStyle.helpSubTOC); HtmlTree section; @@ -193,7 +191,7 @@ public class HelpWriter extends HtmlDocletWriter { if (options.createIndex()) { section = newHelpSection(getContent("doclet.help.search.head"), subTOC, HtmlIds.HELP_SEARCH); Content searchIntro = HtmlTree.P(getContent("doclet.help.search.intro")); - Content searchExamples = new HtmlTree(TagName.UL).setStyle(HtmlStyle.helpSectionList); + Content searchExamples = HtmlTree.UL(HtmlStyle.helpSectionList); for (String[] example : SEARCH_EXAMPLES) { searchExamples.add(HtmlTree.LI( getContent("doclet.help.search.example", @@ -240,7 +238,7 @@ public class HelpWriter extends HtmlDocletWriter { .add(HtmlTree.HEADING(Headings.CONTENT_HEADING, pageKindsHeading).setId(HtmlIds.HELP_PAGES)) .add(contents.getContent("doclet.help.page_kinds.intro")); - HtmlTree subTOC = new HtmlTree(TagName.UL).setStyle(HtmlStyle.helpSubTOC); + HtmlTree subTOC = HtmlTree.UL(HtmlStyle.helpSubTOC); HtmlTree section; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java index 100ad33940b19d780525a88a042ba5bed448504c..a11ad5db0446d0d9d7fad9d113a4540736bd1e7e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package jdk.javadoc.internal.doclets.formats.html; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Date; import java.util.EnumSet; @@ -166,6 +167,11 @@ public class HtmlConfiguration extends BaseConfiguration { */ public final Set conditionalPages; + /** + * The build date, to be recorded in generated files. + */ + private ZonedDateTime buildDate; + /** * Constructs the full configuration needed by the doclet, including * the format-specific part, defined in this class, and the format-independent @@ -215,6 +221,7 @@ public class HtmlConfiguration extends BaseConfiguration { conditionalPages = EnumSet.noneOf(ConditionalPage.class); } + protected void initConfiguration(DocletEnvironment docEnv, Function resourceKeyMapper) { super.initConfiguration(docEnv, resourceKeyMapper); @@ -223,7 +230,6 @@ public class HtmlConfiguration extends BaseConfiguration { } private final Runtime.Version docletVersion; - public final Date startTime = new Date(); @Override public Runtime.Version getDocletVersion() { @@ -259,6 +265,10 @@ public class HtmlConfiguration extends BaseConfiguration { if (!options.validateOptions()) { return false; } + + ZonedDateTime zdt = options.date(); + buildDate = zdt != null ? zdt : ZonedDateTime.now(); + if (!getSpecifiedTypeElements().isEmpty()) { Map map = new HashMap<>(); PackageElement pkg; @@ -279,6 +289,13 @@ public class HtmlConfiguration extends BaseConfiguration { return true; } + /** + * {@return the date to be recorded in generated files} + */ + public ZonedDateTime getBuildDate() { + return buildDate; + } + /** * Decide the page which will appear first in the right-hand frame. It will * be "overview-summary.html" if "-overview" option is used or no diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index 76709124ff2659d456136dbb14b46e71a3d30c30..8934d547213dcbca49476572c929ab29a31cf817 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ package jdk.javadoc.internal.doclets.formats.html; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; @@ -36,6 +37,7 @@ import java.util.ListIterator; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -262,7 +264,7 @@ public class HtmlDocletWriter { do { int match = docrootMatcher.start(); // append htmlstr up to start of next {@docroot} - buf.append(htmlstr.substring(prevEnd, match)); + buf.append(htmlstr, prevEnd, match); prevEnd = docrootMatcher.end(); if (options.docrootParent().length() > 0 && htmlstr.startsWith("/..", prevEnd)) { // Insert the absolute link if {@docRoot} is followed by "/..". @@ -451,7 +453,7 @@ public class HtmlDocletWriter { throws DocFileIOException { List additionalStylesheets = configuration.getAdditionalStylesheets(); additionalStylesheets.addAll(localStylesheets); - Head head = new Head(path, configuration.getDocletVersion(), configuration.startTime) + Head head = new Head(path, configuration.getDocletVersion(), configuration.getBuildDate()) .setTimestamp(!options.noTimestamp()) .setDescription(description) .setGenerator(getGenerator(getClass())) @@ -548,8 +550,7 @@ public class HtmlDocletWriter { protected Content getNavLinkMainTree(String label) { Content mainTreeContent = links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), Text.of(label)); - Content li = HtmlTree.LI(mainTreeContent); - return li; + return HtmlTree.LI(mainTreeContent); } /** @@ -622,7 +623,7 @@ public class HtmlDocletWriter { } else { flags = EnumSet.noneOf(ElementFlag.class); } - DocLink targetLink = null; + DocLink targetLink; if (included || packageElement == null) { targetLink = new DocLink(pathString(packageElement, DocPaths.PACKAGE_SUMMARY)); } else { @@ -896,7 +897,7 @@ public class HtmlDocletWriter { * Return the link for the given member. * * @param context the id of the context where the link will be printed. - * @param typeElement the typeElement that we should link to. This is not + * @param typeElement the typeElement that we should link to. This is * not necessarily the type containing element since we may be * inheriting comments. * @param element the member being linked to. @@ -912,7 +913,7 @@ public class HtmlDocletWriter { * Return the link for the given member. * * @param context the id of the context where the link will be printed. - * @param typeElement the typeElement that we should link to. This is not + * @param typeElement the typeElement that we should link to. This is * not necessarily the type containing element since we may be * inheriting comments. * @param element the member being linked to. @@ -929,7 +930,7 @@ public class HtmlDocletWriter { * Return the link for the given member. * * @param context the id of the context where the link will be printed. - * @param typeElement the typeElement that we should link to. This is not + * @param typeElement the typeElement that we should link to. This is * not necessarily the type containing element since we may be * inheriting comments. * @param element the member being linked to. @@ -945,7 +946,7 @@ public class HtmlDocletWriter { * Return the link for the given member. * * @param context the id of the context where the link will be printed. - * @param typeElement the typeElement that we should link to. This is not + * @param typeElement the typeElement that we should link to. This is * not necessarily the type containing element since we may be * inheriting comments. * @param element the member being linked to. @@ -1063,7 +1064,8 @@ public class HtmlDocletWriter { "doclet.see.class_or_package_not_found", "@" + tagName, seeText); - return (labelContent.isEmpty() ? text: labelContent); + return invalidTagOutput(resources.getText("doclet.tag.invalid", tagName), + Optional.of(labelContent.isEmpty() ? text: labelContent)); } } } else if (refMemName == null) { @@ -1407,14 +1409,6 @@ public class HtmlDocletWriter { return false; } - boolean isAllWhiteSpace(String body) { - for (int i = 0 ; i < body.length(); i++) { - if (!Character.isWhitespace(body.charAt(i))) - return false; - } - return true; - } - // Notify the next DocTree handler to take necessary action private boolean commentRemoved = false; @@ -1505,7 +1499,7 @@ public class HtmlDocletWriter { // Ignore any trailing whitespace OR whitespace after removed html comment if ((isLastNode || commentRemoved) && tag.getKind() == TEXT - && isAllWhiteSpace(ch.getText(tag))) + && ch.getText(tag).isBlank()) continue; // Ignore any leading html comments @@ -1537,18 +1531,11 @@ public class HtmlDocletWriter { return false; } sb.append("="); - String quote; - switch (node.getValueKind()) { - case DOUBLE: - quote = "\""; - break; - case SINGLE: - quote = "'"; - break; - default: - quote = ""; - break; - } + String quote = switch (node.getValueKind()) { + case DOUBLE -> "\""; + case SINGLE -> "'"; + default -> ""; + }; sb.append(quote); result.add(sb); Content docRootContent = new ContentBuilder(); @@ -1622,13 +1609,18 @@ public class HtmlDocletWriter { DocTreePath dtp = ch.getDocTreePath(node); if (dtp != null) { String body = node.getBody(); - if (body.matches("(?i)\\{@[a-z]+.*")) { - messages.warning(dtp,"doclet.tag.invalid_usage", body); - } else { + Matcher m = Pattern.compile("(?i)\\{@([a-z]+).*").matcher(body); + String tagName = m.matches() ? m.group(1) : null; + if (tagName == null) { messages.warning(dtp, "doclet.tag.invalid_input", body); + result.add(invalidTagOutput(resources.getText("doclet.tag.invalid_input", body), + Optional.empty())); + } else { + messages.warning(dtp, "doclet.tag.invalid_usage", body); + result.add(invalidTagOutput(resources.getText("doclet.tag.invalid", tagName), + Optional.of(Text.of(body)))); } } - result.add(Text.of(node.toString())); return false; } @@ -1782,6 +1774,24 @@ public class HtmlDocletWriter { && currentPageElement != utils.getEnclosingTypeElement(element)); } + /** + * Returns the output for an invalid tag. The returned content uses special styling to + * highlight the problem. Depending on the presence of the {@code detail} string the method + * returns a plain text span or an expandable component. + * + * @param summary the single-line summary message + * @param detail the optional detail message which may contain preformatted text + * @return the output + */ + protected Content invalidTagOutput(String summary, Optional detail) { + if (detail.isEmpty() || detail.get().isEmpty()) { + return HtmlTree.SPAN(HtmlStyle.invalidTag, Text.of(summary)); + } + return HtmlTree.DETAILS(HtmlStyle.invalidTag) + .add(HtmlTree.SUMMARY(Text.of(summary))) + .add(HtmlTree.PRE(detail.get())); + } + /** * Returns true if element lives in the same package as the type or package * element of this writer. @@ -2209,17 +2219,13 @@ public class HtmlDocletWriter { for (Element e: chain) { String name; switch (e.getKind()) { - case MODULE: - case PACKAGE: + case MODULE, PACKAGE -> { name = ((QualifiedNameable) e).getQualifiedName().toString(); if (name.length() == 0) { name = ""; } - break; - - default: - name = e.getSimpleName().toString(); - break; + } + default -> name = e.getSimpleName().toString(); } if (sb.length() == 0) { @@ -2363,8 +2369,7 @@ public class HtmlDocletWriter { Content leadingNote = contents.getContent("doclet.PreviewLeadingNote", nameCode); previewDiv.add(HtmlTree.SPAN(HtmlStyle.previewLabel, leadingNote)); - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.previewComment); + HtmlTree ul = HtmlTree.UL(HtmlStyle.previewComment); for (Content note : previewNotes) { ul.add(HtmlTree.LI(note)); } @@ -2428,8 +2433,7 @@ public class HtmlDocletWriter { private Content withPreviewFeatures(String key, String className, String featureName, List features) { String[] sep = new String[] {""}; ContentBuilder featureCodes = new ContentBuilder(); - features.stream() - .forEach(c -> { + features.forEach(c -> { featureCodes.add(sep[0]); featureCodes.add(HtmlTree.CODE(new ContentBuilder().add(c))); sep[0] = ", "; @@ -2444,7 +2448,7 @@ public class HtmlDocletWriter { String[] sep = new String[] {""}; ContentBuilder links = new ContentBuilder(); elements.stream() - .sorted((te1, te2) -> te1.getSimpleName().toString().compareTo(te2.getSimpleName().toString())) + .sorted(Comparator.comparing(te -> te.getSimpleName().toString())) .distinct() .map(te -> getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.CLASS, te) .label(HtmlTree.CODE(Text.of(te.getSimpleName()))).skipPreview(true))) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java index d57d82d98479deab4d7c06ea8952d8ef016f42cd..7278ac8e3155a030914e5c3e29a23a79f92ea423 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java @@ -71,9 +71,7 @@ public class HtmlSerialFieldWriter extends FieldWriterImpl */ @Override public Content getSerializableFieldsHeader() { - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); - return ul; + return HtmlTree.UL(HtmlStyle.blockList); } /** @@ -84,9 +82,7 @@ public class HtmlSerialFieldWriter extends FieldWriterImpl */ @Override public Content getFieldsContentHeader(boolean isLastContent) { - HtmlTree li = new HtmlTree(TagName.LI); - li.setStyle(HtmlStyle.blockList); - return li; + return new HtmlTree(TagName.LI).setStyle(HtmlStyle.blockList); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialMethodWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialMethodWriter.java index aa6e31e7c12ff1105cfd2cdc7bcb810a8f90c170..8b2bed47a00593cba96ab8b275e7a7b9ae1b13e8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialMethodWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialMethodWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,9 +60,7 @@ public class HtmlSerialMethodWriter extends MethodWriterImpl implements */ @Override public Content getSerializableMethodsHeader() { - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); - return ul; + return HtmlTree.UL(HtmlStyle.blockList); } /** @@ -73,9 +71,7 @@ public class HtmlSerialMethodWriter extends MethodWriterImpl implements */ @Override public Content getMethodsContentHeader(boolean isLastContent) { - HtmlTree li = new HtmlTree(TagName.LI); - li.setStyle(HtmlStyle.blockList); - return li; + return new HtmlTree(TagName.LI); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java index 3e169dab6f0a9d2628a26ea5b41e42106b7f5c19..299e565a65782735981e105330e9a7a8ee329675 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ public class IndexRedirectWriter extends HtmlDocletWriter { * @throws DocFileIOException if there is a problem generating the file */ private void generateIndexFile() throws DocFileIOException { - Head head = new Head(path, configuration.getDocletVersion(), configuration.startTime) + Head head = new Head(path, configuration.getDocletVersion(), configuration.getBuildDate()) .setTimestamp(!options.noTimestamp()) .setDescription("index redirect") .setGenerator(getGenerator(getClass())) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java index 4fadb86baa7562bb85897cb71662cea841c93ade..9e486b74ab9af8a8021a9ee8a75eccb2ad31d728 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -292,8 +292,7 @@ public class IndexWriter extends HtmlDocletWriter { */ protected void addComment(Element element, Content contentTree) { Content span = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(element)); - HtmlTree div = new HtmlTree(TagName.DIV); - div.setStyle(HtmlStyle.deprecationBlock); + HtmlTree div = HtmlTree.DIV(HtmlStyle.deprecationBlock); if (utils.isDeprecated(element)) { div.add(span); List tags = utils.getDeprecatedTrees(element); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java index e4dd2efd10dfe5c961e43e10ddbe3b8fa460a7b8..30803551b2fc66bf6d3825f1b93a0c39515ae68f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,8 +180,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW @Override public Content getModuleHeader(String heading) { HtmlTree bodyTree = getBody(getWindowTitle(mdle.getQualifiedName().toString())); - HtmlTree div = new HtmlTree(TagName.DIV); - div.setStyle(HtmlStyle.header); + HtmlTree div = HtmlTree.DIV(HtmlStyle.header); Content moduleHead = new ContentBuilder(); moduleHead.add(mdle.isOpen() && (configuration.docEnv.getModuleMode() == ModuleMode.ALL) ? contents.openModuleLabel : contents.moduleLabel); @@ -222,7 +221,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW */ @Override public Content getSummariesList() { - return new HtmlTree(TagName.UL).setStyle(HtmlStyle.summaryList); + return HtmlTree.UL(HtmlStyle.summaryList); } /** @@ -799,8 +798,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW List deprs = utils.getDeprecatedTrees(mdle); if (utils.isDeprecated(mdle)) { CommentHelper ch = utils.getCommentHelper(mdle); - HtmlTree deprDiv = new HtmlTree(TagName.DIV); - deprDiv.setStyle(HtmlStyle.deprecationBlock); + HtmlTree deprDiv = HtmlTree.DIV(HtmlStyle.deprecationBlock); Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(mdle)); deprDiv.add(deprPhrase); if (!deprs.isEmpty()) { @@ -859,8 +857,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW public void addPackageDeprecationInfo(Content li, PackageElement pkg) { if (utils.isDeprecated(pkg)) { List deprs = utils.getDeprecatedTrees(pkg); - HtmlTree deprDiv = new HtmlTree(TagName.DIV); - deprDiv.setStyle(HtmlStyle.deprecationBlock); + HtmlTree deprDiv = HtmlTree.DIV(HtmlStyle.deprecationBlock); Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(pkg)); deprDiv.add(deprPhrase); if (!deprs.isEmpty()) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java index 4ebd0c3f5c0df01feffcd945ff6d4e73b18f67e8..3e8e556974a300210e1bc63c8db5101ac9eaf63a 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import java.util.List; import java.util.Set; import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; import javax.lang.model.element.ModuleElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; @@ -635,21 +634,21 @@ public class Navigation { .put(HtmlAttr.TITLE, rowListTitle); addMainNavLinks(navList); navDiv.add(navList); - HtmlTree ulNavSummaryRight = new HtmlTree(TagName.UL).setStyle(HtmlStyle.subNavListSmall); + HtmlTree ulNavSummaryRight = HtmlTree.UL(HtmlStyle.subNavListSmall); addSummaryLinks(ulNavSummaryRight, true); addDetailLinks(ulNavSummaryRight, true); navDiv.add(ulNavSummaryRight); tree.add(navDiv); - HtmlTree subDiv = new HtmlTree(TagName.DIV).setStyle(HtmlStyle.subNav); + HtmlTree subDiv = HtmlTree.DIV(HtmlStyle.subNav); HtmlTree div = new HtmlTree(TagName.DIV).setId(HtmlIds.NAVBAR_SUB_LIST); // Add the summary links if present. - HtmlTree ulNavSummary = new HtmlTree(TagName.UL).setStyle(HtmlStyle.subNavList); + HtmlTree ulNavSummary = HtmlTree.UL(HtmlStyle.subNavList); addSummaryLinks(ulNavSummary, false); div.add(ulNavSummary); // Add the detail links if present. - HtmlTree ulNavDetail = new HtmlTree(TagName.UL).setStyle(HtmlStyle.subNavList); + HtmlTree ulNavDetail = HtmlTree.UL(HtmlStyle.subNavList); addDetailLinks(ulNavDetail, false); div.add(ulNavDetail); subDiv.add(div); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java index ba54e2a26dcada166c5c793796f82479b0c7e30f..9618be166f994cb766ae7467d2a9099ad27f3c35 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -147,8 +147,7 @@ public class PackageTreeWriter extends AbstractTreeWriter { Content span = HtmlTree.SPAN(HtmlStyle.packageHierarchyLabel, contents.packageHierarchies); div.add(span); - HtmlTree ul = new HtmlTree (TagName.UL); - ul.setStyle(HtmlStyle.horizontal); + HtmlTree ul = HtmlTree.UL(HtmlStyle.horizontal); ul.add(getNavLinkMainTree(resources.getText("doclet.All_Packages"))); div.add(ul); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java index b6c40c39a577876cdffbf206bf09bafbb40b55fc..1c44a1308685a2870f036d1bcc8608b4d9af6ba3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -181,8 +181,7 @@ public class PackageUseWriter extends SubWriterHolderWriter { protected void addClassList(Content contentTree) { TableHeader classTableHeader = new TableHeader( contents.classLabel, contents.descriptionLabel); - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); + HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList); for (String packageName : usingPackageToUsedClasses.keySet()) { PackageElement usingPackage = utils.elementUtils.getPackageElement(packageName); HtmlTree section = HtmlTree.SECTION(HtmlStyle.detail) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java index 6bca82f17be7eb30e862a027eb4f4f5b272e584e..231ab6c50e2a3e357ee503005e7c74a1a1c9507e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,8 +111,7 @@ public class PackageWriterImpl extends HtmlDocletWriter public Content getPackageHeader() { String packageName = getLocalizedPackageName(packageElement).toString(); HtmlTree bodyTree = getBody(getWindowTitle(packageName)); - HtmlTree div = new HtmlTree(TagName.DIV); - div.setStyle(HtmlStyle.header); + HtmlTree div = HtmlTree.DIV(HtmlStyle.header); if (configuration.showModules) { ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement); Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInPackage, contents.moduleLabel); @@ -212,8 +211,7 @@ public class PackageWriterImpl extends HtmlDocletWriter List deprs = utils.getDeprecatedTrees(packageElement); if (utils.isDeprecated(packageElement)) { CommentHelper ch = utils.getCommentHelper(packageElement); - HtmlTree deprDiv = new HtmlTree(TagName.DIV); - deprDiv.setStyle(HtmlStyle.deprecationBlock); + HtmlTree deprDiv = HtmlTree.DIV(HtmlStyle.deprecationBlock); Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(packageElement)); deprDiv.add(deprPhrase); if (!deprs.isEmpty()) { @@ -228,7 +226,7 @@ public class PackageWriterImpl extends HtmlDocletWriter @Override public Content getSummariesList() { - return new HtmlTree(TagName.UL).setStyle(HtmlStyle.summaryList); + return HtmlTree.UL(HtmlStyle.summaryList); } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java index 8d97e0c5b4ff6c4681bac97242f1e4b9b26988b3..242ebf371999841833b6f5a2fe3aa6d5866c0a33 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import javax.lang.model.element.TypeElement; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.Entity; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; -import jdk.javadoc.internal.doclets.formats.html.markup.TagName; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; import jdk.javadoc.internal.doclets.formats.html.markup.Text; @@ -90,9 +89,7 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter */ @Override public Content getSerializedSummariesHeader() { - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); - return ul; + return HtmlTree.UL(HtmlStyle.blockList); } /** @@ -127,9 +124,8 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter */ @Override public Content getClassSerializedHeader() { - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); - return ul; + return HtmlTree.UL(HtmlStyle.blockList); + } /** @@ -220,9 +216,8 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter */ @Override public Content getClassContentHeader() { - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); - return ul; + return HtmlTree.UL(HtmlStyle.blockList); + } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java index 7bc1f96b6488420756cd530640d54d94acc2c28e..4efa6a70d229eb80bf471a8b56c6a6c391b8232f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -232,7 +232,7 @@ public class SourceToHTMLConverter { * @param path the path for the file. */ private void writeToFile(Content body, DocPath path, TypeElement te) throws DocFileIOException { - Head head = new Head(path, configuration.getDocletVersion(), configuration.startTime) + Head head = new Head(path, configuration.getDocletVersion(), configuration.getBuildDate()) // .setTimestamp(!options.notimestamp) // temporary: compatibility! .setTitle(resources.getText("doclet.Window_Source_title")) // .setCharset(options.charset) // temporary: compatibility! diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java index 5f09e20fd7404c2c7226b7a6db3ccdfefedd2504..0a22ce4ae4a1333b0166534658632991167aba35 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,6 @@ import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlId; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; -import jdk.javadoc.internal.doclets.formats.html.markup.TagName; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; @@ -207,9 +206,7 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter { * @return a content tree for the member header */ public Content getMemberTreeHeader() { - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.blockList); - return ul; + return HtmlTree.UL(HtmlStyle.blockList); } /** @@ -218,7 +215,7 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter { * @return a list to be used for the list of summaries for members of a given kind */ public Content getSummariesList() { - return new HtmlTree(TagName.UL).setStyle(HtmlStyle.summaryList); + return HtmlTree.UL(HtmlStyle.summaryList); } /** @@ -238,7 +235,7 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter { * @return a list to be used for the list of details for members of a given kind */ public Content getDetailsList() { - return new HtmlTree(TagName.UL).setStyle(HtmlStyle.detailsList); + return HtmlTree.UL(HtmlStyle.detailsList); } /** @@ -257,7 +254,7 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter { * @return a list to be used for the list of members of a given kind */ public Content getMemberList() { - return new HtmlTree(TagName.UL).setStyle(HtmlStyle.memberList); + return HtmlTree.UL(HtmlStyle.memberList); } /** @@ -271,9 +268,7 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter { } public Content getMemberInheritedTree() { - HtmlTree div = new HtmlTree(TagName.DIV); - div.setStyle(HtmlStyle.inheritedList); - return div; + return HtmlTree.DIV(HtmlStyle.inheritedList); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Table.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Table.java index 25f7e98f4f259017d0de7e3e9e13c632d94555f6..8cf2e3710f08c4460135dc8b8092415d80f4362b 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Table.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Table.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -386,7 +386,7 @@ public class Table extends Content { default -> throw new IllegalStateException(); }; - HtmlTree table = new HtmlTree(TagName.DIV).setStyle(tableStyle).addStyle(columnStyle); + HtmlTree table = HtmlTree.DIV(tableStyle).addStyle(columnStyle); if ((tabMap == null || tabs.size() == 1) && !alwaysShowDefaultTab) { if (tabMap == null) { main.add(caption); @@ -396,7 +396,7 @@ public class Table extends Content { table.add(getTableBody()); main.add(table); } else { - HtmlTree tablist = new HtmlTree(TagName.DIV).setStyle(tabListStyle) + HtmlTree tablist = HtmlTree.DIV(tabListStyle) .put(HtmlAttr.ROLE, "tablist") .put(HtmlAttr.ARIA_ORIENTATION, "horizontal"); @@ -481,8 +481,6 @@ public class Table extends Content { } private HtmlTree getCaption(Content title) { - return new HtmlTree(TagName.DIV) - .setStyle(HtmlStyle.caption) - .add(HtmlTree.SPAN(title)); + return HtmlTree.DIV(HtmlStyle.caption, HtmlTree.SPAN(title)); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java index 640786dd4eb1b330470b74d9258c92b7799dcd46..fdac4e55576804f710f58c0fb964b124ca69fb03 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import javax.lang.model.element.Element; @@ -351,8 +352,7 @@ public class TagletWriterImpl extends TagletWriter { // Use a different style if any link label is longer than 30 chars or contains commas. boolean hasLongLabels = links.stream() .anyMatch(c -> c.charCount() > SEE_TAG_MAX_INLINE_LENGTH || c.toString().contains(",")); - HtmlTree seeList = new HtmlTree(TagName.UL) - .setStyle(hasLongLabels ? HtmlStyle.seeListLong : HtmlStyle.seeList); + HtmlTree seeList = HtmlTree.UL(hasLongLabels ? HtmlStyle.seeListLong : HtmlStyle.seeList); links.stream().filter(Content::isValid).forEach(item -> { seeList.add(HtmlTree.LI(item)); }); @@ -536,6 +536,14 @@ public class TagletWriterImpl extends TagletWriter { : Text.of(constantVal); } + @Override + protected Content invalidTagOutput(String summary, Optional detail) { + return htmlWriter.invalidTagOutput(summary, + detail.isEmpty() || detail.get().isEmpty() + ? Optional.empty() + : Optional.of(Text.of(utils.normalizeNewlines(detail.get())))); + } + @Override public Content commentTagsToOutput(DocTree holder, List tags) { return commentTagsToOutput(null, holder, tags, false); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java index 12971fc19dcba2d78ec7bc9aad512fa8f0b521e4..57b2b470dee83178bf8c72435fb4233c253f3727 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * 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,10 +32,8 @@ import javax.lang.model.element.PackageElement; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; -import jdk.javadoc.internal.doclets.formats.html.markup.TagName; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; -import jdk.javadoc.internal.doclets.formats.html.markup.Text; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.util.ClassTree; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; @@ -135,8 +133,7 @@ public class TreeWriter extends AbstractTreeWriter { Content span = HtmlTree.SPAN(HtmlStyle.packageHierarchyLabel, contents.packageHierarchies); contentTree.add(span); - HtmlTree ul = new HtmlTree(TagName.UL); - ul.setStyle(HtmlStyle.horizontal); + HtmlTree ul = HtmlTree.UL(HtmlStyle.horizontal); int i = 0; for (PackageElement pkg : packages) { // If the package name length is 0 or if -nodeprecated option diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java index 975154b7d1d29c67947d1f89bd833bfa82e11089..adbd5ef09fd3b257b77087fbcb2032592e022a5d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java @@ -27,12 +27,14 @@ package jdk.javadoc.internal.doclets.formats.html.markup; import java.io.IOException; import java.io.Writer; -import java.text.SimpleDateFormat; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Locale; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; @@ -50,7 +52,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; */ public class Head extends Content { private final Runtime.Version docletVersion; - private final Date generatedDate; + private final ZonedDateTime generatedDate; private final DocPath pathToRoot; private String title; private String charset; @@ -78,7 +80,7 @@ public class Head extends Content { * @param path the path for the file that will include this HEAD element * @param docletVersion the doclet version */ - public Head(DocPath path, Runtime.Version docletVersion, Date generatedDate) { + public Head(DocPath path, Runtime.Version docletVersion, ZonedDateTime generatedDate) { this.docletVersion = docletVersion; this.generatedDate = generatedDate; pathToRoot = path.parent().invert(); @@ -279,8 +281,8 @@ public class Head extends Content { } if (showTimestamp) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - tree.add(HtmlTree.META("dc.created", dateFormat.format(generatedDate))); + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + tree.add(HtmlTree.META("dc.created", generatedDate.format(dateFormat))); } if (description != null) { @@ -309,11 +311,14 @@ public class Head extends Content { return tree; } - private Comment getGeneratedBy(boolean timestamp, Date now) { + + private Comment getGeneratedBy(boolean timestamp, ZonedDateTime buildDate) { String text = "Generated by javadoc"; // marker string, deliberately not localized text += " (" + docletVersion.feature() + ")"; if (timestamp) { - text += " on " + now; + DateTimeFormatter fmt = + DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy").withLocale(Locale.US); + text += " on " + buildDate.format(fmt); } return new Comment(text); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java index 1d22926b8162ef6009c34e4b70dc38a49386c768..8301e9b9255cc0a900505b8a95d2dd0535df7cc2 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java @@ -48,20 +48,14 @@ import java.util.regex.Pattern; * or {@link javax.lang.model.element.Element "language model elements"}. * The usage is made explicit when it is not clear from the surrounding context. * + * @apiNote + * The stylized use of {@code editor-fold} comments and line comments (beginning {@code //}) + * is to support extracting details of declarations with external tools. Edit with care! + * * @see WhatWG: {@code class} attribute */ public enum HtmlStyle { - /** - * The class of the {@code div} element containing a snippet element. - */ - snippetContainer, - - /** - * The class of the {@code a} element to copy snippet content to the clipboard. - */ - snippetCopy, - // // // The following constants are used for the main navigation bar that appears in the @@ -324,17 +318,6 @@ public enum HtmlStyle { */ propertyDetails, - /** - * The class for the list containing the {@code @see} tags of an element. - */ - seeList, - - /** - * The class for the list containing the {@code @see} tags of an element - * when some of the tags have longer labels. - */ - seeListLong, - /** * The class for a {@code section} element containing details of the * serialized form of an element, on the "Serialized Form" page. @@ -391,6 +374,17 @@ public enum HtmlStyle { */ previewLabel, + /** + * The class for the list containing the {@code @see} tags of an element. + */ + seeList, + + /** + * The class for the list containing the {@code @see} tags of an element + * when some of the tags have longer labels. + */ + seeListLong, + // // @@ -844,6 +838,44 @@ public enum HtmlStyle { // + // + // + // The following constants are used for the contents of snippets. + // In addition, the translation of a snippet may use the class + // {@code language-LANG} where LANG is either specified explicitly + // by the "lang" attribute in a snippet tag, or can be inferred + // from the kind of an external snippet. + + /** + * The class of the {@code pre} element presenting a snippet. + */ + snippet, + + /** + * The class of the {@code div} element containing a snippet element. + */ + snippetContainer, + + /** + * The class of the UI element to copy snippet content to the clipboard. + */ + snippetCopy, + + /** + * The class of text highlighted with the type {@code bold}. + */ + bold, + + /** + * The class of text highlighted with the type {@code italic}. + */ + italic, + + /** + * The class of text highlighted with the type {@code highlighted}. + */ + highlighted, + // // // The following constants are used in various places across a variety of pages. @@ -907,6 +939,12 @@ public enum HtmlStyle { */ inheritedList, + /** + * The class of an element that acts as a notification for an invalid tag + * or other invalid items. + */ + invalidTag, + /** * The class of a {@code p} element containing legal copy in the page footer. */ @@ -918,7 +956,7 @@ public enum HtmlStyle { memberNameLink, /** - * The class for a {@code dl} element containing serial UID information in + * The class of a {@code dl} element containing serial UID information in * the serialized form page. */ nameValue, @@ -959,11 +997,6 @@ public enum HtmlStyle { */ sourceLineNo, - /** - * The class of the {@code pre} element presenting a snippet. - */ - snippet, - /** * The class of an {@code a} element for a link to a class or interface. */ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java index 1d05cd8c4d4cd676531fb4c0aeb74cc1ff241d98..4b954ef1a31b7570caaf8cf1618a96f98cfff75c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,14 +27,17 @@ package jdk.javadoc.internal.doclets.formats.html.markup; import java.io.IOException; import java.io.Writer; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.BitSet; +import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.function.Function; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr.Role; import jdk.javadoc.internal.doclets.toolkit.Content; @@ -222,6 +225,20 @@ public class HtmlTree extends Content { return this; } + /** + * Adds each of a collection of items, using a map function to create the content for each item. + * + * @param items the items + * @param mapper the map function to generate the content for each item + * + * @return this object + */ + @Override + public HtmlTree addAll(Collection items, Function mapper) { + items.forEach(item -> add(mapper.apply(item))); + return this; + } + @Override public int charCount() { int n = 0; @@ -301,6 +318,7 @@ public class HtmlTree extends Content { /** * Creates an HTML {@code A} element. + * The {@code ref} argument will be URL-encoded for use as the attribute value. * * @param ref the value for the {@code href} attribute} * @param body the content for element @@ -312,6 +330,22 @@ public class HtmlTree extends Content { .add(body); } + /** + * Creates an HTML {@code A} element. + * The {@code ref} argument is assumed to be already suitably encoded, + * and will not be additionally URL-encoded, but will be + * {@link URI#toASCIIString() converted} to ASCII for use as the attribute value. + * + * @param ref the value for the {@code href} attribute} + * @param body the content for element + * @return the element + */ + public static HtmlTree A(URI ref, Content body) { + return new HtmlTree(TagName.A) + .put(HtmlAttr.HREF, ref.toASCIIString()) + .add(body); + } + /** * Creates an HTML {@code CAPTION} element with the given content. * @@ -345,6 +379,16 @@ public class HtmlTree extends Content { .add(body); } + /** + * Creates an HTML {@code DETAILS} element. + * + * @return the element + */ + public static HtmlTree DETAILS(HtmlStyle style) { + return new HtmlTree(TagName.DETAILS) + .setStyle(style); + } + /** * Creates an HTML {@code DL} element with the given style. * @@ -495,12 +539,10 @@ public class HtmlTree extends Content { } private static TagName checkHeading(TagName headingTag) { - switch (headingTag) { - case H1: case H2: case H3: case H4: case H5: case H6: - return headingTag; - default: - throw new IllegalArgumentException(headingTag.toString()); - } + return switch (headingTag) { + case H1, H2, H3, H4, H5, H6 -> headingTag; + default -> throw new IllegalArgumentException(headingTag.toString()); + }; } /** @@ -682,6 +724,16 @@ public class HtmlTree extends Content { .setStyle(style); } + /** + * Creates an HTML {@code PRE} element with some content. + * + * @param body the content + * @return the element + */ + public static HtmlTree PRE(Content body) { + return new HtmlTree(TagName.PRE).add(body); + } + /** * Creates an HTML {@code SCRIPT} element with some script content. * The type of the script is set to {@code text/javascript}. @@ -782,6 +834,17 @@ public class HtmlTree extends Content { .add(body); } + /** + * Creates an HTML {@code SUMMARY} element with the given content. + * + * @param body the content + * @return the element + */ + public static HtmlTree SUMMARY(Content body) { + return new HtmlTree(TagName.SUMMARY) + .add(body); + } + /** * Creates an HTML {@code SUP} element with the given content. * @@ -845,6 +908,17 @@ public class HtmlTree extends Content { .add(body); } + /** + * Creates an HTML {@code UL} element with the given style. + * + * @param style the style + * @return the element + */ + public static HtmlTree UL(HtmlStyle style) { + return new HtmlTree(TagName.UL) + .setStyle(style); + } + /** * Creates an HTML {@code UL} element with the given style and some content. * @@ -863,6 +937,21 @@ public class HtmlTree extends Content { return htmlTree; } + /** + * Creates an HTML {@code UL} element with the given style and content generated + * from a collection of items.. + * + * @param style the style + * @param items the items to be added to the list + * @param mapper a mapper to create the content for each item + * @return the element + */ + public static HtmlTree UL(HtmlStyle style, Collection items, Function mapper) { + return new HtmlTree(TagName.UL) + .setStyle(style) + .addAll(items, mapper); + } + @Override public boolean isEmpty() { return (!hasContent() && !hasAttrs()); @@ -905,30 +994,29 @@ public class HtmlTree extends Content { */ @Override public boolean isValid() { - switch (tagName) { - case A: - return (hasAttr(HtmlAttr.ID) || (hasAttr(HtmlAttr.HREF) && hasContent())); - case BR: - return (!hasContent() && (!hasAttrs() || hasAttr(HtmlAttr.CLEAR))); - case HR: - case INPUT: - return (!hasContent()); - case IMG: - return (hasAttr(HtmlAttr.SRC) && hasAttr(HtmlAttr.ALT) && !hasContent()); - case LINK: - return (hasAttr(HtmlAttr.HREF) && !hasContent()); - case META: - return (hasAttr(HtmlAttr.CONTENT) && !hasContent()); - case SCRIPT: - return ((hasAttr(HtmlAttr.TYPE) && hasAttr(HtmlAttr.SRC) && !hasContent()) || - (hasAttr(HtmlAttr.TYPE) && hasContent())); - case SPAN: - return (hasAttr(HtmlAttr.ID) || hasContent()); - case WBR: - return (!hasContent()); - default : - return hasContent(); - } + return switch (tagName) { + case A -> + hasAttr(HtmlAttr.ID) || (hasAttr(HtmlAttr.HREF) && hasContent()); + case BR -> + !hasContent() && (!hasAttrs() || hasAttr(HtmlAttr.CLEAR)); + case HR, INPUT -> + !hasContent(); + case IMG -> + hasAttr(HtmlAttr.SRC) && hasAttr(HtmlAttr.ALT) && !hasContent(); + case LINK -> + hasAttr(HtmlAttr.HREF) && !hasContent(); + case META -> + hasAttr(HtmlAttr.CONTENT) && !hasContent(); + case SCRIPT -> + (hasAttr(HtmlAttr.TYPE) && hasAttr(HtmlAttr.SRC) && !hasContent()) + || (hasAttr(HtmlAttr.TYPE) && hasContent()); + case SPAN -> + hasAttr(HtmlAttr.ID) || hasContent(); + case WBR -> + !hasContent(); + default -> + hasContent(); + }; } /** @@ -939,14 +1027,10 @@ public class HtmlTree extends Content { * @see Phrasing Content */ public boolean isInline() { - switch (tagName) { - case A: case BUTTON: case BR: case CODE: case EM: case I: case IMG: - case LABEL: case SMALL: case SPAN: case STRONG: case SUB: case SUP: - case WBR: - return true; - default: - return false; - } + return switch (tagName) { + case A, BUTTON, BR, CODE, EM, I, IMG, LABEL, SMALL, SPAN, STRONG, SUB, SUP, WBR -> true; + default -> false; + }; } /** @@ -957,12 +1041,10 @@ public class HtmlTree extends Content { * @see Void Elements */ public boolean isVoid() { - switch (tagName) { - case BR: case HR: case IMG: case INPUT: case LINK: case META: case WBR: - return true; - default: - return false; - } + return switch (tagName) { + case BR, HR, IMG, INPUT, LINK, META, WBR -> true; + default -> false; + }; } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/TagName.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/TagName.java index 34655300b30b6dfbe154ac5c8568b91511b085c8..59aad16bf2d88f28fa15d0836466238f2d2255bf 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/TagName.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/TagName.java @@ -47,6 +47,7 @@ public enum TagName { CAPTION, CODE, DD, + DETAILS, DIV, DL, DT, @@ -83,6 +84,7 @@ public enum TagName { SPAN, STRONG, SUB, + SUMMARY, SUP, TABLE, TBODY, diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index f491b97adfef8837a08157790e4c64d606bfc2cd..285acb051fd7a551a7c881e1f6f672a973e46d12 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -106,6 +106,7 @@ doclet.see.class_or_package_not_accessible=Tag {0}: reference not accessible: {1 doclet.see.nested_link=Tag {0}: nested link doclet.tag.invalid_usage=invalid usage of tag {0} doclet.tag.invalid_input=invalid input: ''{0}'' +doclet.tag.invalid=invalid @{0} doclet.Deprecated_API=Deprecated API doclet.Deprecated_Elements=Deprecated {0} doclet.Deprecated_In_Release=Deprecated in {0} @@ -168,6 +169,12 @@ doclet.systemPropertiesSummary=System Properties Summary doclet.Window_Source_title=Source code doclet.Window_Help_title=API Help +# 0: a date +doclet.Option_date_out_of_range=value for ''--date'' out of range: {0} + +# 0: a date +doclet.Option_date_not_valid=value for ''--date'' not valid: {0} + doclet.help.main_heading=\ JavaDoc Help doclet.help.navigation.head=\ @@ -419,6 +426,12 @@ doclet.usage.windowtitle.parameters=\ doclet.usage.windowtitle.description=\ Browser window title for the documentation +doclet.usage.date.parameters=\ + +doclet.usage.date.description=\ + Specifies the value to be used to timestamp the generated\n\ + pages, in ISO 8601 format + doclet.usage.doctitle.parameters=\ doclet.usage.doctitle.description=\ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java index 6445f4fc6a088f4eaf0d52de680218f771f1bba3..42110c4aa70a5476049401c120921bae5fc326a1 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,16 @@ import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalUnit; import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; @@ -82,6 +90,12 @@ public abstract class BaseOptions { */ private final LinkedHashSet> customTagStrs = new LinkedHashSet<>(); + /** + * Argument for command-line option {@code --date}. + * {@code null} if option not given. + */ + private ZonedDateTime date; + /** * Argument for command-line option {@code -d}. * Destination directory name, in which doclet will generate the entire @@ -338,6 +352,33 @@ public abstract class BaseOptions { } }, + new XOption(resources, "--date", 1) { + // Valid --date range: within ten years of now + private static final ZonedDateTime now = ZonedDateTime.now(); + static final ZonedDateTime DATE_MIN = now.minusYears(10); + static final ZonedDateTime DATE_MAX = now.plusYears(10); + + @Override + public boolean process(String opt, List args) { + if (noTimestamp) { + messages.error("doclet.Option_conflict", "--date", "-notimestamp"); + return false; + } + String arg = args.get(0); + try { + date = ZonedDateTime.parse(arg, DateTimeFormatter.ISO_ZONED_DATE_TIME); + if (date.isBefore(DATE_MIN) || date.isAfter(DATE_MAX)) { + messages.error("doclet.Option_date_out_of_range", arg); + return false; + } + return true; + } catch (DateTimeParseException x) { + messages.error("doclet.Option_date_not_valid", arg); + return false; + } + } + }, + new Option(resources, "-docencoding", 1) { @Override public boolean process(String opt, List args) { @@ -471,6 +512,10 @@ public abstract class BaseOptions { @Override public boolean process(String opt, List args) { noTimestamp = true; + if (date != null) { + messages.error("doclet.Option_conflict", "--date", "-notimestamp"); + return false; + } return true; } }, @@ -739,6 +784,13 @@ public abstract class BaseOptions { return customTagStrs; } + /** + * Argument for command-line option {@code --date}. + */ + public ZonedDateTime date() { + return date; + } + /** * Argument for command-line option {@code -d}. * Destination directory name, in which doclet will generate the entire diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ConstructorWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ConstructorWriter.java index dd12824670c962193eceec81dc52e282f097dbf8..380ac5ce530c8b36a798b367ebec61a77eb5cc65 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ConstructorWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ConstructorWriter.java @@ -74,7 +74,7 @@ public interface ConstructorWriter extends MemberWriter { * Add the preview output for the given member. * * @param member the member being documented - * @param annotationDocTree content tree to which the preview information will be added + * @param contentTree content tree to which the preview information will be added */ void addPreview(ExecutableElement member, Content contentTree); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java index 84cc66912b4a712bcb9b0794fccd0a69383852da..80dd9c48587167ec891a2d32982a8f52f51e4141 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java @@ -28,6 +28,8 @@ package jdk.javadoc.internal.doclets.toolkit; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; +import java.util.Collection; +import java.util.function.Function; /** * A class to create content for javadoc output pages. @@ -89,6 +91,25 @@ public abstract class Content { throw new UnsupportedOperationException(); } + /** + * Adds content to the existing content, generated from a collection of items + * This is an optional operation. + * + * @implSpec This implementation delegates to {@link #add(Content)}. + * + * @param items the items to be added + * @param mapper the function to create content for each item + * + * @return this object + * @throws UnsupportedOperationException if this operation is not supported by + * a particular implementation + * @throws IllegalArgumentException if the content is not suitable to be added + */ + public Content addAll(Collection items, Function mapper) { + items.forEach(item -> add(mapper.apply(item))); + return this; + } + /** * Writes content to a writer. * diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/EnumConstantWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/EnumConstantWriter.java index 835be5e4d3a0ed474654674646960ebd7562bfe4..aa483714d1b4c79e1976a7c4a0d374455376843c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/EnumConstantWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/EnumConstantWriter.java @@ -79,7 +79,7 @@ public interface EnumConstantWriter extends MemberWriter { * Add the preview output for the given member. * * @param member the member being documented - * @param annotationDocTree content tree to which the preview information will be added + * @param contentTree content tree to which the preview information will be added */ void addPreview(VariableElement member, Content contentTree); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/MethodWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/MethodWriter.java index b4efc8a777b510383eeb93b6a8de015742feb59b..d13ba652ae4b8fb3d41c95cac2a20c46ea4c8576 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/MethodWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/MethodWriter.java @@ -75,7 +75,7 @@ public interface MethodWriter extends MemberWriter { * Adds the preview output for the given member. * * @param member the member being documented - * @param annotationDocTree content tree to which the preview information will be added + * @param contentTree content tree to which the preview information will be added */ void addPreview(ExecutableElement member, Content contentTree); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties index 8825d98f96de77da45348443317d65950e321f79..c67865344eebf4c6dc60d1c06b4ffb657eab46a0 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties @@ -45,7 +45,7 @@ doclet.exception.write.file=Error writing file: {0}\n\ \t({1}) doclet.exception.read.resource=Error reading system resource: {0}\n\ \t({1}) -doclet.internal.exception=An internal exception has occurred. \n\ +doclet.internal.exception=An internal exception has occurred.\n\ \t({0}) doclet.internal.report.bug=\ Please file a bug against the javadoc tool via the Java bug reporting page\n\ @@ -373,6 +373,8 @@ doclet.snippet.contents.mismatch=\ doclet.snippet.markup=\ snippet markup: {0} +doclet.snippet.markup.spurious=\ + spurious markup doclet.snippet.markup.attribute.absent=\ missing attribute "{0}" doclet.snippet.markup.attribute.simultaneous.use=\ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css index d61caef2a0ebff9cd018180b9a968ad95efc9c19..69252eab283f2f5efd01df10943e84306e438613 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css @@ -555,6 +555,18 @@ div.block { div.block div.deprecation-comment { font-style:normal; } +details.invalid-tag, span.invalid-tag { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; + background: #ffe6e6; + border: thin solid #000000; + border-radius:2px; + padding: 2px 4px; + display:inline-block; +} +details.invalid-tag summary { + cursor: pointer; +} /* * Styles specific to HTML5 elements. */ @@ -991,11 +1003,9 @@ button.snippet-copy:active { pre.snippet .italic { font-style: italic; } - pre.snippet .bold { font-weight: bold; } - pre.snippet .highlighted { background-color: #f7c590; border-radius: 10%; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java index b41260743ee5be3ee222050fa5b6d1207eb4dd1f..2af114d322b2cd0f3b420702cac57f40a868e628 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -152,7 +152,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet { } /** - * Given an array of {@code @param DocTree}s,return its string representation. + * Given an array of {@code @param DocTree}s, return its string representation. * Try to inherit the param tags that are missing. * * @param holder the element that holds the param tags. @@ -165,54 +165,29 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet { private Content getTagletOutput(ParamKind kind, Element holder, TagletWriter writer, List formalParameters, List paramTags) { Content result = writer.getOutputInstance(); - Set alreadyDocumented = new HashSet<>(); - if (!paramTags.isEmpty()) { - result.add( - processParamTags(holder, kind, paramTags, - getRankMap(writer.configuration().utils, formalParameters), writer, alreadyDocumented) - ); - } - if (alreadyDocumented.size() != formalParameters.size()) { - //Some parameters are missing corresponding @param tags. - //Try to inherit them. - result.add(getInheritedTagletOutput(kind, holder, - writer, formalParameters, alreadyDocumented)); - } + result.add(processParamTags(holder, kind, paramTags, formalParameters, writer)); return result; } /** - * Loop through each individual parameter, despite not having a - * corresponding param tag, try to inherit it. + * Try to get the inherited taglet documentation for a specific parameter. */ private Content getInheritedTagletOutput(ParamKind kind, Element holder, - TagletWriter writer, List formalParameters, - Set alreadyDocumented) { + TagletWriter writer, Element param, int rank, + boolean isFirst) { Utils utils = writer.configuration().utils; Content result = writer.getOutputInstance(); - if ((!alreadyDocumented.contains(null)) && utils.isExecutableElement(holder)) { - for (int i = 0; i < formalParameters.size(); i++) { - if (alreadyDocumented.contains(String.valueOf(i))) { - continue; - } - // This parameter does not have any @param documentation. - // Try to inherit it. - Input input = new DocFinder.Input(writer.configuration().utils, holder, this, - Integer.toString(i), kind == ParamKind.TYPE_PARAMETER); - DocFinder.Output inheritedDoc = DocFinder.search(writer.configuration(), input); - if (inheritedDoc.inlineTags != null && !inheritedDoc.inlineTags.isEmpty()) { - Element e = formalParameters.get(i); - String lname = kind != ParamKind.TYPE_PARAMETER - ? utils.getSimpleName(e) - : utils.getTypeName(e.asType(), false); - Content content = processParamTag(inheritedDoc.holder, kind, writer, - (ParamTree) inheritedDoc.holderTag, - lname, - alreadyDocumented.isEmpty()); - result.add(content); - } - alreadyDocumented.add(String.valueOf(i)); - } + Input input = new DocFinder.Input(writer.configuration().utils, holder, this, + Integer.toString(rank), kind == ParamKind.TYPE_PARAMETER); + DocFinder.Output inheritedDoc = DocFinder.search(writer.configuration(), input); + if (inheritedDoc.inlineTags != null && !inheritedDoc.inlineTags.isEmpty()) { + String lname = kind != ParamKind.TYPE_PARAMETER + ? utils.getSimpleName(param) + : utils.getTypeName(param.asType(), false); + Content content = processParamTag(inheritedDoc.holder, kind, writer, + (ParamTree) inheritedDoc.holderTag, + lname, isFirst); + result.add(content); } return result; } @@ -225,23 +200,15 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet { * * @param paramTags the array of {@code @param DocTree} to convert. * @param writer the TagletWriter that will write this tag. - * @param alreadyDocumented the set of exceptions that have already - * been documented. - * @param rankMap a {@link java.util.Map} which holds ordering - * information about the parameters. - * @param rankMap a {@link java.util.Map} which holds a mapping - of a rank of a parameter to its name. This is - used to ensure that the right name is used - when parameter documentation is inherited. * @return the Content representation of this {@code @param DocTree}. */ - private Content processParamTags(Element e, ParamKind kind, - List paramTags, Map rankMap, TagletWriter writer, - Set alreadyDocumented) { + private Content processParamTags(Element e, ParamKind kind, List paramTags, + List formalParameters, TagletWriter writer) { + Map documented = new HashMap<>(); Messages messages = writer.configuration().getMessages(); - Content result = writer.getOutputInstance(); + CommentHelper ch = writer.configuration().utils.getCommentHelper(e); if (!paramTags.isEmpty()) { - CommentHelper ch = writer.configuration().utils.getCommentHelper(e); + Map rankMap = getRankMap(writer.configuration().utils, formalParameters); for (ParamTree dt : paramTags) { String name = ch.getParameterName(dt); String paramName = kind == ParamKind.TYPE_PARAMETER ? "<" + name + ">" : name; @@ -250,23 +217,45 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet { case PARAMETER -> "doclet.Parameters_warn"; case TYPE_PARAMETER -> "doclet.TypeParameters_warn"; case RECORD_COMPONENT -> "doclet.RecordComponents_warn"; - default -> throw new IllegalArgumentException(kind.toString()); }; messages.warning(ch.getDocTreePath(dt), key, paramName); } String rank = rankMap.get(name); - if (rank != null && alreadyDocumented.contains(rank)) { - String key = switch (kind) { - case PARAMETER -> "doclet.Parameters_dup_warn"; - case TYPE_PARAMETER -> "doclet.TypeParameters_dup_warn"; - case RECORD_COMPONENT -> "doclet.RecordComponents_dup_warn"; - default -> throw new IllegalArgumentException(kind.toString()); - }; - messages.warning(ch.getDocTreePath(dt), key, paramName); + if (rank != null) { + if (documented.containsKey(rank)) { + String key = switch (kind) { + case PARAMETER -> "doclet.Parameters_dup_warn"; + case TYPE_PARAMETER -> "doclet.TypeParameters_dup_warn"; + case RECORD_COMPONENT -> "doclet.RecordComponents_dup_warn"; + }; + messages.warning(ch.getDocTreePath(dt), key, paramName); + } else { + documented.put(rank, dt); + } } + } + } + // Document declared parameters for which taglet documentation is available + // (either directly or inherited) in order of their declaration. + Content result = writer.getOutputInstance(); + for (int i = 0; i < formalParameters.size(); i++) { + ParamTree dt = documented.get(String.valueOf(i)); + if (dt != null) { result.add(processParamTag(e, kind, writer, dt, - name, alreadyDocumented.isEmpty())); - alreadyDocumented.add(rank); + ch.getParameterName(dt), result.isEmpty())); + } else if (writer.configuration().utils.isExecutableElement(e)) { + result.add(getInheritedTagletOutput(kind, e, writer, + formalParameters.get(i), i, result.isEmpty())); + } + } + if (paramTags.size() > documented.size()) { + // Generate documentation for remaining taglets that do not match a declared parameter. + // These are erroneous but we generate them anyway. + for (ParamTree dt : paramTags) { + if (!documented.containsValue(dt)) { + result.add(processParamTag(e, kind, writer, dt, + ch.getParameterName(dt), result.isEmpty())); + } } } return result; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SnippetTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SnippetTaglet.java index 925359bf4ae81ff51d60ea12a9f189eb7d920666..3c13b194c226543e801e7110169379fa12aa9ee6 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SnippetTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SnippetTaglet.java @@ -120,7 +120,8 @@ public class SnippetTaglet extends BaseTaglet { return generateContent(holder, tag, writer); } catch (BadSnippetException e) { error(writer, holder, e.tag(), e.key(), e.args()); - return badSnippet(writer); + String details = writer.configuration().getDocResources().getText(e.key(), e.args()); + return badSnippet(writer, Optional.of(details)); } } @@ -269,8 +270,14 @@ public class SnippetTaglet extends BaseTaglet { StyledText externalSnippet = null; try { + Diags d = (text, pos) -> { + var path = writer.configuration().utils.getCommentHelper(holder) + .getDocTreePath(snippetTag.getBody()); + writer.configuration().getReporter().print(Diagnostic.Kind.WARNING, + path, pos, pos, pos, text); + }; if (inlineContent != null) { - inlineSnippet = parse(writer.configuration().getDocResources(), language, inlineContent); + inlineSnippet = parse(writer.configuration().getDocResources(), d, language, inlineContent); } } catch (ParseException e) { var path = writer.configuration().utils.getCommentHelper(holder) @@ -280,18 +287,20 @@ public class SnippetTaglet extends BaseTaglet { .getText("doclet.snippet.markup", e.getMessage()); writer.configuration().getReporter().print(Diagnostic.Kind.ERROR, path, e.getPosition(), e.getPosition(), e.getPosition(), msg); - return badSnippet(writer); + return badSnippet(writer, Optional.of(e.getMessage())); } try { + var finalFileObject = fileObject; + Diags d = (text, pos) -> writer.configuration().getMessages().warning(finalFileObject, pos, pos, pos, text); if (externalContent != null) { - externalSnippet = parse(writer.configuration().getDocResources(), language, externalContent); + externalSnippet = parse(writer.configuration().getDocResources(), d, language, externalContent); } } catch (ParseException e) { assert fileObject != null; writer.configuration().getMessages().error(fileObject, e.getPosition(), e.getPosition(), e.getPosition(), "doclet.snippet.markup", e.getMessage()); - return badSnippet(writer); + return badSnippet(writer, Optional.of(e.getMessage())); } // the region must be matched at least in one content: it can be matched @@ -363,12 +372,16 @@ public class SnippetTaglet extends BaseTaglet { """.formatted(inline, external); } - private StyledText parse(Resources resources, Optional language, String content) throws ParseException { - Parser.Result result = new Parser(resources).parse(language, content); + private StyledText parse(Resources resources, Diags diags, Optional language, String content) throws ParseException { + Parser.Result result = new Parser(resources).parse(diags, language, content); result.actions().forEach(Action::perform); return result.text(); } + public interface Diags { + void warn(String text, int pos); + } + private static String stringValueOf(AttributeTree at) throws BadSnippetException { if (at.getValueKind() == AttributeTree.ValueKind.EMPTY) { throw new BadSnippetException(at, "doclet.tag.attribute.value.missing", @@ -396,8 +409,9 @@ public class SnippetTaglet extends BaseTaglet { writer.configuration().utils.getCommentHelper(holder).getDocTreePath(tag), key, args); } - private Content badSnippet(TagletWriter writer) { - return writer.getOutputInstance().add("bad snippet"); + private Content badSnippet(TagletWriter writer, Optional details) { + Resources resources = writer.configuration().getDocResources(); + return writer.invalidTagOutput(resources.getText("doclet.tag.invalid", "snippet"), details); } private String packageName(PackageElement pkg, Utils utils) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java index 19928eee306456eb1bd32a323a46d5fdf5a2cafd..134d54276340ffed28277e853d3f67f063ea63b8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java @@ -250,23 +250,22 @@ public class TagletManager { * @param fileManager the file manager to load classes and resources */ public void addCustomTag(String classname, JavaFileManager fileManager) { + ClassLoader tagClassLoader = fileManager.getClassLoader(TAGLET_PATH); + if (configuration.workArounds.accessInternalAPI()) { + Module thisModule = getClass().getModule(); + Module tagletLoaderUnnamedModule = tagClassLoader.getUnnamedModule(); + List pkgs = List.of( + "jdk.javadoc.doclet", + "jdk.javadoc.internal.doclets.toolkit", + "jdk.javadoc.internal.doclets.formats.html"); + pkgs.forEach(p -> thisModule.addOpens(p, tagletLoaderUnnamedModule)); + } try { - ClassLoader tagClassLoader; - tagClassLoader = fileManager.getClassLoader(TAGLET_PATH); - if (configuration.workArounds.accessInternalAPI()) { - Module thisModule = getClass().getModule(); - Module tagletLoaderUnnamedModule = tagClassLoader.getUnnamedModule(); - List pkgs = List.of( - "jdk.javadoc.doclet", - "jdk.javadoc.internal.doclets.toolkit", - "jdk.javadoc.internal.doclets.formats.html"); - pkgs.forEach(p -> thisModule.addOpens(p, tagletLoaderUnnamedModule)); - } Class customTagClass = tagClassLoader.loadClass(classname).asSubclass(jdk.javadoc.doclet.Taglet.class); jdk.javadoc.doclet.Taglet instance = customTagClass.getConstructor().newInstance(); registerTaglet(instance); - } catch (ReflectiveOperationException exc) { + } catch (ReflectiveOperationException | ExceptionInInitializerError | ClassCastException exc) { messages.error("doclet.Error_taglet_not_registered", exc.getClass().getName(), classname); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java index a12c7b42ffd8045f17b6367db48c2df253708433..b9142d6721a3a2f7936c6a8b4db43bd7193f6f97 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java @@ -27,6 +27,7 @@ package jdk.javadoc.internal.doclets.toolkit.taglets; import java.util.List; import java.util.Map; +import java.util.Optional; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; @@ -239,6 +240,17 @@ public abstract class TagletWriter { protected abstract Content valueTagOutput(VariableElement field, String constantVal, boolean includeLink); + /** + * Returns the output for an invalid tag. The returned content uses special styling to + * highlight the problem. Depending on the presence of the {@code detail} string the method + * returns a plain text span or an expandable component. + * + * @param summary the single-line summary message + * @param detail the optional detail message which may contain preformatted text + * @return the output + */ + protected abstract Content invalidTagOutput(String summary, Optional detail); + /** * Returns the main type element of the current page or null for pages that don't have one. * diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/MarkupParser.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/MarkupParser.java index 879ba7bf2e40e5843ef09dd297b4ce1bb3c46991..59d6b3f9fdb3381e5dab55d3c5255b80d06c50cd 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/MarkupParser.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/MarkupParser.java @@ -31,11 +31,8 @@ import java.util.List; import jdk.javadoc.internal.doclets.toolkit.Resources; // -// markup-comment = { markup-tag } ; -// markup-tag = "@" , tag-name , {attribute} [":"] ; -// -// If optional trailing ":" is present, the tag refers to the next line -// rather than to this line. +// markup-comment = { markup-tag } [":"] ; +// markup-tag = "@" , tag-name , {attribute} ; // /** @@ -76,15 +73,28 @@ public final class MarkupParser { } protected List parse() throws ParseException { + List tags = readTags(); + if (ch == ':') { + tags.forEach(t -> t.appliesToNextLine = true); + nextChar(); + } + skipWhitespace(); + if (ch != EOI) { + return List.of(); + } + return tags; + } + + protected List readTags() throws ParseException { List tags = new ArrayList<>(); - // TODO: what to do with leading and trailing unrecognized markup? + skipWhitespace(); while (bp < buflen) { - switch (ch) { - case '@' -> tags.add(readTag()); - default -> nextChar(); + if (ch == '@') { + tags.add(readTag()); + } else { + break; } } - return tags; } @@ -94,26 +104,13 @@ public final class MarkupParser { String name = readIdentifier(); skipWhitespace(); - boolean appliesToNextLine = false; - List attributes = List.of(); - - if (ch == ':') { - appliesToNextLine = true; - nextChar(); - } else { - attributes = attrs(); - skipWhitespace(); - if (ch == ':') { - appliesToNextLine = true; - nextChar(); - } - } + List attributes = attrs(); + skipWhitespace(); Parser.Tag i = new Parser.Tag(); i.nameLineOffset = nameBp; i.name = name; i.attributes = attributes; - i.appliesToNextLine = appliesToNextLine; return i; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/Parser.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/Parser.java index ccc6ce87799b06faf73426d42a1fdadf9f6ab709..3ed4ac03166d23b38922de2eb173e1cb18d3f7ce 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/Parser.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/snippet/Parser.java @@ -94,19 +94,19 @@ public final class Parser { this.markupParser = new MarkupParser(resources); } - public Result parse(Optional language, String source) throws ParseException { + public Result parse(SnippetTaglet.Diags diags, Optional language, String source) throws ParseException { SnippetTaglet.Language lang = language.orElse(SnippetTaglet.Language.JAVA); var p = switch (lang) { case JAVA -> JAVA_COMMENT; case PROPERTIES -> PROPERTIES_COMMENT; }; - return parse(p, source); + return parse(diags, p, source); } /* * Newline characters in the returned text are of the \n form. */ - private Result parse(Pattern commentPattern, String source) throws ParseException { + private Result parse(SnippetTaglet.Diags diags, Pattern commentPattern, String source) throws ParseException { Objects.requireNonNull(commentPattern); Objects.requireNonNull(source); @@ -150,7 +150,7 @@ public final class Parser { parsedTags = markupParser.parse(maybeMarkup); } catch (ParseException e) { // translate error position from markup to file line - throw new ParseException(e::getMessage, markedUpLine.start("markup") + e.getPosition()); + throw new ParseException(e::getMessage, next.offset() + markedUpLine.start("markup") + e.getPosition()); } for (Tag t : parsedTags) { t.lineSourceOffset = next.offset(); @@ -166,7 +166,7 @@ public final class Parser { } } if (parsedTags.isEmpty()) { // (2) - // TODO: log this with NOTICE; + diags.warn(resources.getText("doclet.snippet.markup.spurious"), next.offset() + markedUpLine.start("markup")); line = rawLine + (addLineTerminator ? "\n" : ""); } else { // (3) hasMarkup = true; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java index 0d73d233cc166af98273ec654db57c070abda3d8..446757513a17e6756089b1e5f04d5772a2fb7abd 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java @@ -41,6 +41,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; @@ -952,11 +953,31 @@ public class Checker extends DocTreePathScanner { @Override @DefinedBy(Api.COMPILER_TREE) public Void visitReference(ReferenceTree tree, Void ignore) { Element e = env.trees.getElement(getCurrentPath()); - if (e == null) - env.messages.error(REFERENCE, tree, "dc.ref.not.found"); + if (e == null) { + reportBadReference(tree); + } return super.visitReference(tree, ignore); } + private void reportBadReference(ReferenceTree tree) { + if (!env.strictReferenceChecks) { + String refSig = tree.getSignature(); + int sep = refSig.indexOf("/"); + if (sep > 0) { + String moduleName = refSig.substring(0, sep); + if (SourceVersion.isName(moduleName)) { + Element m = env.elements.getModuleElement(moduleName); + if (m == null) { + env.messages.warning(REFERENCE, tree, "dc.ref.in.missing.module", moduleName); + return; + } + } + } + } + + env.messages.error(REFERENCE, tree, "dc.ref.not.found"); + } + @Override @DefinedBy(Api.COMPILER_TREE) public Void visitReturn(ReturnTree tree, Void ignore) { if (foundReturn) { @@ -1236,13 +1257,7 @@ public class Checker extends DocTreePathScanner { } boolean hasNonWhitespace(TextTree tree) { - String s = tree.getBody(); - for (int i = 0; i < s.length(); i++) { - Character c = s.charAt(i); - if (!Character.isWhitespace(s.charAt(i))) - return true; - } - return false; + return !tree.getBody().isBlank(); } // diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/DocLint.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/DocLint.java index 1c4f3a3d6509b1bfc987877636f9454927cd3d4b..9a1d0f2e4ccb3240af39c95cca3dfdaf030dc9bc 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/DocLint.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/DocLint.java @@ -274,6 +274,14 @@ public class DocLint extends com.sun.tools.doclint.DocLint { // + /** + * Initialize DocLint for use with a {@code JavacTask}. + * {@link Env#strictReferenceChecks Strict reference checks} are not enabled by default. + * + * @param task the task + * @param args arguments to configure DocLint + * @param addTaskListener whether or not to register a {@code TaskListener} to invoke DocLint + */ public void init(JavacTask task, String[] args, boolean addTaskListener) { env = new Env(); env.init(task); @@ -319,9 +327,19 @@ public class DocLint extends com.sun.tools.doclint.DocLint { } } + /** + * Initialize DocLint with the given utility objects and arguments. + * {@link Env#strictReferenceChecks Strict reference checks} are enabled by default. + * + * @param trees the {@code DocTrees} utility class + * @param elements the {@code Elements} utility class + * @param types the {@code Types} utility class + * @param args arguments to configure DocLint + */ public void init(DocTrees trees, Elements elements, Types types, String... args) { env = new Env(); env.init(trees, elements, types); + env.strictReferenceChecks = true; processArgs(env, args); checker = new Checker(env); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Env.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Env.java index 01a0a8676732f1403256569254722eac3e30e2a1..be13ca43fd1c0d9fe0cf7ab473fd5eb7a475e612 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Env.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Env.java @@ -108,6 +108,20 @@ public class Env { Set includePackages; Set excludePackages; + /** + * How to handle bad references. + * + * If {@code false}, a reference into a module that is not + * in the module graph will just be reported as a warning. + * All other bad references will be reported as errors. + * This is the desired behavior for javac. + * + * If {@code true}, all bad references will be reported as + * errors. This is the desired behavior for javadoc. + * + */ + boolean strictReferenceChecks = false; + // Utility classes DocTrees trees; Elements elements; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/resources/doclint.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/resources/doclint.properties index 091316f0e29d075bbdb1c36dd83261105ade4bfe..fbcb2c0088149a0b9395daa55c67d8f4e8c697a6 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/resources/doclint.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/resources/doclint.properties @@ -61,6 +61,7 @@ dc.no.alt.attr.for.image = no "alt" attribute for image dc.no.summary.or.caption.for.table=no caption for table dc.param.name.not.found = @param name not found dc.ref.not.found = reference not found +dc.ref.in.missing.module = module for reference not found: {0} dc.return.not.first = '{@return} not at beginning of description dc.service.not.found = service-type not found dc.tag.code.within.code = '{@code} within diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/package-info.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/package-info.java index 473e44ff4214a07f59007c58270638c68dedf5eb..4d7da0ba7cded3b005c9abce0ca1f993d34447bf 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/package-info.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,21 +24,146 @@ */ /** - * The implementation of the javadoc tool, and associated doclets. + * The implementation of the javadoc tool and associated doclets. * - *

        Internally, javadoc is composed of two primary parts: + *

        Internally, javadoc is composed of two primary parts: * the {@link jdk.javadoc.internal.tool tool}, and a series of * {@link jdk.javadoc.internal.doclets doclets}. * - * The tool provides a common infrastructure for command-line processing, - * and for reading the documentation comments in Java source files, + *

        The tool provides a common infrastructure for command-line processing, + * and for reading the declarations and documentation comments in Java source files, * while doclets provide a user-selectable backend for determining - * how to process the documentation comments. + * how to process the declarations and their documentation comments. + * + *

        The following provides a top-down description of the overall javadoc + * software stack. + * + *

        + *
        Doclets + *
        + *
        + *
        The Standard Doclet + *

        + * The {@link jdk.javadoc.doclet.StandardDoclet} is a thin public wrapper + * around the internal HTML doclet. + * + *

        The HTML Doclet + *

        + * The {@link jdk.javadoc.internal.doclets.formats.html.HtmlDoclet} class + * and other classes in the + * {@link jdk.javadoc.internal.doclets.formats.html formats.html} package + * customize the abstract pages generated by the toolkit layer to generate + * HTML pages. Some pages are specific to the HTML output format, + * and do not have an abstract builder in the toolkit layer. + * + *

        Individual pages of output are generated by page-specific subtypes of + * {@link jdk.javadoc.internal.doclets.formats.html.HtmlDocletWriter}. + * + *

        The {@link jdk.javadoc.internal.doclets.formats.html.HtmlConfiguration} class + * provides configuration information that is relevant to all the generated pages. + * The class extends the {@link jdk.javadoc.internal.doclets.toolkit.BaseConfiguration} + * class provided by the toolkit layer. + * + *

        The classes in the {@code formats.html} package use an internal + * library in the + * {@link jdk.javadoc.internal.doclets.formats.html.markup formats.html.markup} package, + * to create trees (or acyclic graphs) of + * {@linkplain jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree HTML tree nodes}. + * Apart from using a common format-neutral supertype, + * {@link jdk.javadoc.internal.doclets.toolkit.Content}, the {@code markup} library + * is mostly independent of the rest of the javadoc software stack. + * + *

        Toolkit + *

        + * The {@link jdk.javadoc.internal.doclets.toolkit toolkit} package provides + * support for a format-neutral + * {@linkplain jdk.javadoc.internal.doclets.toolkit.AbstractDoclet abstract doclet}, + * which uses + * {@linkplain jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder builders} + * to generate pages of abstract + * {@linkplain jdk.javadoc.internal.doclets.toolkit.Content content}. + * + *

        The format-specific content for each page is provided by implementations + * of various writer interfaces, created by a format-specific + * {@linkplain jdk.javadoc.internal.doclets.toolkit.WriterFactory writer factory}. + * + *

        The {@link jdk.javadoc.internal.doclets.toolkit.BaseConfiguration} provides + * configuration information that is relevant to all the generated pages. + * Some of the information is provided by abstract methods which are implemented + * in format-specific subtypes of the class. + * + *

        The toolkit layer also provides + * {@linkplain jdk.javadoc.internal.doclets.toolkit.util utility classes} + * used by this layer and by format-specific layers. + * + *

        Generally, it is intended that doclets should use the + * {@link javax.lang.model Language Model API} to navigate the structure of a Java program, + * without needing to access any internal details of the underlying javac implementation. + * However, there are still some shortcomings of the Language Model API, + * and so it is still necessary to provide limited access to some of those internal details. + * Although not enforceable by the module system, by design the access to javac + * internal details by doclets based on {@code AbstractDoclet} is restricted to the aptly-named + * {@link jdk.javadoc.internal.doclets.toolkit.WorkArounds} class. + * + *

        Other Doclets + *

        + * Doclets are obviously not required to use + * {@link jdk.javadoc.internal.doclets.toolkit.AbstractDoclet} and other classes in + * the toolkit layer. In times past, it was common to write doclets to analyze + * code using the then-current API as an early version of a Java language model. + * That old API has been replaced by the {@link javax.lang.model Language Model API}, + * and tools that wish to use that API to analyze Java programs have a choice of + * how to invoke it, using the javac support for + * {@linkplain javax.annotation.processing annotation processing}, + * or {@linkplain com.sun.source.util.Plugin plugins}, as well as doclets. + * Which is best for any application will depend of the circumstances, but + * if a tool does not need access to the documentation comments in a program, + * it is possible that one of the other invocation mechanisms will be more convenient. + * + *

        + * + *
        The Doclet Interface + *

        + * The {@linkplain jdk.javadoc.doclet Doclet API} is the interface layer between + * the javadoc tool and the code to process the elements specified to the tool. + * + *

        Above this layer, in any doclet, the code is expected to use the + * {@linkplain javax.lang.model Language Model API} to navigate around the specified + * elements, and/or the {@linkplain com.sun.source.doctree DocTree API} to examine + * the corresponding documentation comments. + * + *

        The javadoc Tool + *

        + * After reading the command-line options, the tool uses a modified javac + * front end to read the necessary files and thus instantiate the + * {@linkplain javax.lang.model.element.Element elements} to be made available to + * the doclet that will be used to process them. + * + * The tool uses an internal feature of the javac architecture, which + * allows various components to be replaced by subtypes with modified behavior. + * This is done by pre-registering the desired components in the javac + * {@code Context}. + * The tool uses this mechanism to do the following: + *

          + *
        • although source files are parsed in their entirety, the + * content of method bodies is quickly discarded as unnecessary; + *
        • the class reader is updated to handle {@code package.html} + * files in any package directories that are read; and + *
        • the compilation pipeline for each source file is terminated + * after the parse and enter phases, meaning that + * the files are processed enough to instantiate the elements to + * be made available to the doclet, but no more. + *
        + *
        * * *

        This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice. + * + * @see JavaDoc Architecture + * @see Using the new Doclet API + * @see Processing Code */ -package jdk.javadoc.internal; +package jdk.javadoc.internal; \ No newline at end of file diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java index 20362f6a09d099b39f3708ff551e170e0e4541ce..e92176cbd8573abce616ecbd49936741c739173a 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -793,7 +793,7 @@ public class ElementsTable { Collection collection, boolean recurse) throws ToolException { for (ModulePackage modpkg : collection) { - toolEnv.notice("main.Loading_source_files_for_package", modpkg.toString()); + toolEnv.printInfo("main.Loading_source_files_for_package", modpkg.toString()); List files = getFiles(modpkg, recurse); if (files.isEmpty()) { String text = log.getText("main.no_source_files_for_package", diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocLog.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocLog.java index 8409169968b0f6dc5636a43f9741509c88bc816d..04f24fcde9cb35c9a861a4144c8648c5804588ee 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocLog.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocLog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -292,12 +292,6 @@ public class JavadocLog extends Log implements Reporter { report(dt, flags, ds, dp, message); } - private int getSourcePos(DocTreePath path, int offset) { - DCTree.DCDocComment docComment = (DCTree.DCDocComment) path.getDocComment(); - DCTree tree = (DCTree) path.getLeaf(); - return docComment.getSourcePosition(tree.getStartPosition() + offset); - } - @Override // Reporter public void print(Kind kind, Element element, String message) { DiagnosticType dt = getDiagnosticType(kind); @@ -450,22 +444,27 @@ public class JavadocLog extends Log implements Reporter { } /** - * Prints a "notice" message to the standard writer. + * Prints a "notice" message. * - * @param key the resource key for the message - * @param args the arguments for the message + * @param message the message */ - public void noticeUsingKey(String key, Object... args) { - printRawLines(getStandardWriter(), getText(key, args)); + public void printNote(String message) { + // Ideally, for consistency with errors and warnings, we would use the following: + // report(Kind.NOTE, null, null, message); + // but the default formatting in Log for Kind.NOTE is to prefix the line with "Note:" + // which is undesirable and inconsistent with existing javadoc output. + // For now, to avoid the prefix, we write directly to the underlying stream. + printRawLines(WriterKind.NOTICE, message); } /** - * Prints a "notice" message to the standard writer. + * Prints a "notice" message. * - * @param message the message + * @param key the resource key for the message + * @param args the arguments for the message */ - public void notice(String message) { - printRawLines(getStandardWriter(), message); + public void printNoteUsingKey(String key, Object... args) { + printNote(getText(key, args)); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java index 16f9ce2ca68c81261ec44c5a1828efdc9e3d68ca..94d3d21413172b138f9d7079b9f964a5b796be49 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -207,7 +207,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { } // Enter symbols for all files - toolEnv.notice("main.Building_tree"); + toolEnv.printInfo("main.Building_tree"); javadocEnter.main(allTrees.toList()); if (log.hasErrors()) { @@ -284,7 +284,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { for (JavaFileObject fo: files) { if (uniquefiles.add(fo)) { // ignore duplicates if (trace) - toolEnv.notice("main.Loading_source_file", fo.getName()); + toolEnv.printInfo("main.Loading_source_file", fo.getName()); trees.append(parse(fo)); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java index 467c28adba1e466ca988e6adc3575224b98690cf..cb12e6e25e6c9dd22d6669a1b80c1ee6698c64f7 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,12 @@ */ package jdk.javadoc.internal.tool; +import javax.tools.JavaFileManager; +import javax.tools.StandardJavaFileManager; import java.io.PrintWriter; +import java.util.Objects; + +import com.sun.tools.javac.util.Context; /** * Provides external entry points (tool and programmatic) for the javadoc program. @@ -37,11 +42,6 @@ import java.io.PrintWriter; public class Main { - /** - * This constructor should never be called. - */ - private Main() { throw new AssertionError(); } - /** * The main entry point called by the launcher. This will call * System.exit with an appropriate return value. @@ -88,6 +88,65 @@ public class Main { return jdoc.begin(args).exitCode; } + + // builder-style API to run javadoc + + private PrintWriter outWriter; + private PrintWriter errWriter; + private StandardJavaFileManager fileManager; + + /** + * Creates a default builder to run javadoc. + */ + public Main() { } + + /** + * Sets the output and error streams to be used when running javadoc. + * The streams may be the same; they must not be {@code null}. + * + * @param outWriter the output stream + * @param errWriter the error stream + * + * @return this object + */ + public Main setStreams(PrintWriter outWriter, PrintWriter errWriter) { + this.outWriter = Objects.requireNonNull(outWriter); + this.errWriter = Objects.requireNonNull(errWriter); + return this; + } + + /** + * Sets the file manager to be used when running javadoc. + * A value of {@code null} means to use the default file manager. + * + * @param fileManager the file manager to use + * + * @return this object + */ + public Main setFileManager(StandardJavaFileManager fileManager) { + this.fileManager = fileManager; + return this; + } + + /** + * Runs javadoc with preconfigured values and a given set of arguments. + * Any errors will be reported to the error stream, or to {@link System#err} + * if no error stream has been specified with {@code setStreams}. + * + * @param args the arguments + * + * @return a value indicating the success or otherwise of the run + */ + public Result run(String... args) { + Context context = null; + if (fileManager != null) { + context = new Context(); + context.put(JavaFileManager.class, fileManager); + } + Start jdoc = new Start(context, null, outWriter, errWriter, null, null); + return jdoc.begin(args); + } + public enum Result { /** completed with no errors */ OK(0), diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java index 307c5d6517ef40a14cba5115263a0f72ea558a1a..4d25ac5f22adc892c7eeb06b8b01662593e71337 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import java.util.Comparator; import java.util.IllformedLocaleException; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Supplier; @@ -195,7 +196,7 @@ public class Start { } private void showUsage(String headerKey, ToolOption.Kind kind, String footerKey) { - log.noticeUsingKey(headerKey); + showLinesUsingKey(headerKey); showToolOptions(kind); // let doclet print usage information @@ -204,12 +205,13 @@ public class Start { ? Option.Kind.EXTENDED : Option.Kind.STANDARD); } - if (footerKey != null) - log.noticeUsingKey(footerKey); + if (footerKey != null) { + showLinesUsingKey(footerKey); + } } private void showVersion(String labelKey, String value) { - log.noticeUsingKey(labelKey, log.programName, value); + showLinesUsingKey(labelKey, log.programName, value); } private void showToolOptions(ToolOption.Kind kind) { @@ -252,7 +254,7 @@ public class Start { if (options.isEmpty()) { return; } - log.noticeUsingKey("main.doclet.usage.header", name); + showLinesUsingKey("main.doclet.usage.header", name); Comparator comp = new Comparator() { final Collator collator = Collator.getInstance(Locale.US); @@ -307,22 +309,30 @@ public class Start { if (synopses.length() < DEFAULT_SYNOPSIS_WIDTH && !description.contains("\n") && (SMALL_INDENT.length() + DEFAULT_SYNOPSIS_WIDTH + 1 + description.length() <= DEFAULT_MAX_LINE_LENGTH)) { - log.notice(String.format(COMPACT_FORMAT, synopses, description)); + showLines(String.format(COMPACT_FORMAT, synopses, description)); return; } // If option synopses fit on a single line of reasonable length, show that; // otherwise, show 1 per line if (synopses.length() <= DEFAULT_MAX_LINE_LENGTH) { - log.notice(SMALL_INDENT + synopses); + showLines(SMALL_INDENT + synopses); } else { for (String name: names) { - log.notice(SMALL_INDENT + name + parameters); + showLines(SMALL_INDENT + name + parameters); } } // Finally, show the description - log.notice(LARGE_INDENT + description.replace("\n", "\n" + LARGE_INDENT)); + showLines(LARGE_INDENT + description.replace("\n", "\n" + LARGE_INDENT)); + } + + private void showLinesUsingKey(String key, Object... args) { + showLines(log.getText(key, args)); + } + + private void showLines(String message) { + log.printRawLines(Log.WriterKind.STDOUT, message); } @@ -520,7 +530,21 @@ public class Start { } if (fileManager instanceof BaseFileManager bfm) { + // standard file manager: use direct support for handling options bfm.handleOptions(options.fileManagerOptions()); + } else { + // unrecognized file manager: + for (Map.Entry e: options.fileManagerOptions().entrySet()) { + String optName = e.getKey().getPrimaryName(); + String optValue = e.getValue(); + try { + if (!fileManager.handleOption(optName, List.of(optValue).iterator())) { + log.error("main.unknown.option.for.filemanager", optName); + } + } catch (IllegalArgumentException ex) { + log.error("main.bad.arg.for.filemanager.option", optName, ex.getMessage()); + } + } } String mr = com.sun.tools.javac.main.Option.MULTIRELEASE.primaryName; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java index ef6f1b74940ff4ef79d24f4c85d9aa366872c3fb..b42245da5a973be96b679f20b2c19d807a2718cc 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -191,28 +191,14 @@ public class ToolEnvironment { } /** - * Print a notice, iff quiet is not specified. + * Prints a notice unless {@code -quiet} was specified. * * @param key selects message from resource */ - public void notice(String key) { - if (quiet) { - return; + public void printInfo(String key, Object... args) { + if (!quiet) { + log.printNoteUsingKey(key, args); } - JavadocLog.printRawLines(log.getDiagnosticWriter(), log.getText(key)); - } - - /** - * Print a notice, iff quiet is not specified. - * - * @param key selects message from resource - * @param a1 first argument - */ - public void notice(String key, String a1) { - if (quiet) { - return; - } - JavadocLog.printRawLines(log.getDiagnosticWriter(), log.getText(key, a1)); } TreePath getTreePath(JCCompilationUnit tree) { @@ -247,8 +233,4 @@ public class ToolEnvironment { public Env getEnv(ClassSymbol tsym) { return enter.getEnv(tsym); } - - public boolean isQuiet() { - return quiet; - } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties index 8b46fcf88925cbc4927d231309da8fb64935d452..77e73e19955a875509866880838fb790c9843d16 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties @@ -302,6 +302,8 @@ main.warnings.Werror=warnings found and -Werror specified main.unknown.error=an unknown error has occurred main.internal.error=an internal error has occurred main.unexpected.exception=an unexpected exception was caught: {0} +main.unknown.option.for.filemanager=option not supported by file manager: {0} +main.bad.arg.for.filemanager.option=bad value for file manager option {0}: "{1}" doclet.internal.report.bug=\ Please file a bug against the javadoc tool via the Java bug reporting page\n\ (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com)\n\ diff --git a/src/jdk.javadoc/share/man/javadoc.1 b/src/jdk.javadoc/share/man/javadoc.1 index c052a4ca136f62e53b839b89cf8fd66def28a942..4f64deb532fa18c518da06803821b68436edf798 100644 --- a/src/jdk.javadoc/share/man/javadoc.1 +++ b/src/jdk.javadoc/share/man/javadoc.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVADOC" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JAVADOC" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP @@ -34,9 +34,9 @@ files .TP .B \f[I]options\f[R] Specifies command\-line options, separated by spaces. -See \f[B]Options for javadoc\f[R], \f[B]Extended Options\f[R], -\f[B]Standard doclet Options\f[R], and \f[B]Additional Options Provided -by the Standard doclet\f[R]. +See \f[B]Standard \f[BC]javadoc\f[B] Options\f[R], \f[B]Extra +\f[BC]javadoc\f[B] Options\f[R], \f[B]Standard Options for the Standard +Doclet\f[R], and \f[B]Extra Options for the Standard Doclet\f[R]. .RS .RE .TP @@ -88,19 +88,15 @@ option either to recursively traverse a directory and its subdirectories, or to pass in an explicit list of package names. When you document individual source files, pass in a list of Java source file names. -See \f[B]javadoc Overview\f[R] -[https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase/13/tools&id=JSJAV\-GUID\-7A344353\-3BBF\-45C4\-8B28\-15025DDCC643] -in Java Platform, Standard Edition Javadoc Guide for information about -using the \f[CB]javadoc\f[R] tool. -.SH CONFORMANCE +.SS Conformance .PP -The standard doclet does not validate the content of documentation +The Standard Doclet does not validate the content of documentation comments for conformance, nor does it attempt to correct any errors in documentation comments. Anyone running javadoc is advised to be aware of the problems that may arise when generating non\-conformant output or output containing executable content, such as JavaScript. -The standard doclet does provide the \f[CB]doclint\f[R] feature to help +The Standard Doclet does provide the \f[B]DocLint\f[R] feature to help developers detect common problems in documentation comments; but it is also recommended to check the generated output with any appropriate conformance and other checking tools. @@ -112,7 +108,16 @@ in the HTML5 Specification. For more details on security issues related to web pages, see the \f[B]Open Web Application Security Project (OWASP)\f[R] [https://www.owasp.org] page. -.SH OPTIONS FOR JAVADOC +.SH OPTIONS +.PP +\f[CB]javadoc\f[R] supports command\-line options for both the main +\f[CB]javadoc\f[R] tool and the currently selected doclet. +The Standard Doclet is used if no other doclet is specified. +.PP +GNU\-style options (that is, those beginning with \f[CB]\-\-\f[R]) can use +an equal sign (\f[CB]=\f[R]) instead of whitespace characters to separate +the name of an option from its value. +.SS Standard \f[CB]javadoc\f[R] Options .PP The following core \f[CB]javadoc\f[R] options are equivalent to corresponding \f[CB]javac\f[R] options. @@ -151,12 +156,6 @@ descriptions of using these options: .PP The following options are the core \f[CB]javadoc\f[R] options that are not equivalent to a corresponding \f[CB]javac\f[R] option: -.PP -\f[B]Note:\f[R] -.PP -In tools that support \f[CB]\-\-\f[R] style options, the GNU\-style -options can use the equal sign (=) instead of a white space to separate -the name of an option from its value. .TP .B \f[CB]\-breakiterator\f[R] Computes the first sentence with \f[CB]BreakIterator\f[R]. @@ -222,20 +221,24 @@ exclude packages rooted at \f[CB]java.net\f[R] and \f[CB]java.lang\f[R]. Notice that these examples exclude \f[CB]java.lang.ref\f[R], which is a subpackage of \f[CB]java.lang\f[R]. .IP \[bu] 2 -\f[B]Linux and OS X:\f[R] +\f[B]Linux and macOS:\f[R] .RS 2 -.RS -.PP -\f[CB]javadoc\ \-sourcepath\ /home/user/src\ \-subpackages\ java\ \-exclude\ java.net:java.lang\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-sourcepath\ /home/user/src\ \-subpackages\ java\ \-exclude\ java.net:java.lang +\f[R] +.fi .RE .IP \[bu] 2 \f[B]Windows:\f[R] .RS 2 -.RS -.PP -\f[CB]javadoc\ \-sourcepath\ \\user\\src\ \-subpackages\ java\ \-exclude\ java.net:java.lang\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-sourcepath\ \\user\\src\ \-subpackages\ java\ \-exclude\ java.net:java.lang +\f[R] +.fi .RE .RE .TP @@ -283,9 +286,9 @@ used to run the \f[CB]javadoc\f[R] tool. .nf \f[CB] javadoc\ \-J\-version -java\ version\ "10\-ea"\ 2018\-03\-20 -Java(TM)\ SE\ Runtime\ Environment\ 18.3\ (build\ 10\-ea+36) -Java\ HotSpot(TM)\ 64\-Bit\ Server\ VM\ 18.3\ (build\ 10\-ea+36,\ mixed\ mode) +java\ version\ "17"\ 2021\-09\-14\ LTS +Java(TM)\ SE\ Runtime\ Environment\ (build\ 17+35\-LTS\-2724) +Java\ HotSpot(TM)\ 64\-Bit\ Server\ VM\ (build\ 17+35\-LTS\-2724,\ mixed\ mode,\ sharing) \f[R] .fi .RE @@ -298,13 +301,6 @@ The argument is the name of the locale, as described in (English, United States) or \f[CB]en_US_WIN\f[R] (Windows variant). .RS .PP -\f[B]Note:\f[R] -.PP -The \f[CB]\-locale\f[R] option must be placed ahead (to the left) of any -options provided by the standard doclet or any other doclet. -Otherwise, the navigation bars appear in English. -This is the only command\-line option that depends on order. -.PP Specifying a locale causes the \f[CB]javadoc\f[R] tool to choose the resource files of that locale for messages such as strings in the navigation bar, headings for lists and tables, help file contents, @@ -349,13 +345,14 @@ Specifies which members (fields or methods) are documented, where \f[I]value\f[R] can be any of the following: .RS .IP \[bu] 2 -\f[CB]protected\f[R]: The default value is protected. +\f[CB]public\f[R] \-\-\- shows only public members .IP \[bu] 2 -\f[CB]public\f[R]: Shows only public values. +\f[CB]protected\f[R] \-\-\- shows public and protected members; this is +the default .IP \[bu] 2 -\f[CB]package\f[R]: Shows public, protected, and package members. +\f[CB]package\f[R] \-\-\- shows public, protected, and package members .IP \[bu] 2 -\f[CB]private\f[R]: Shows all members. +\f[CB]private\f[R] \-\-\- shows all members .RE .TP .B \f[CB]\-\-show\-module\-contents\f[R] \f[I]value\f[R] @@ -375,14 +372,14 @@ Specifies which types (classes, interfaces, etc.) are documented, where \f[I]value\f[R] can be any of the following: .RS .IP \[bu] 2 -\f[CB]protected\f[R]: The default value. -Shows public and protected types. +\f[CB]public\f[R] \-\-\- shows only public types .IP \[bu] 2 -\f[CB]public\f[R]: Shows only public values. +\f[CB]protected\f[R] \-\-\- shows public and protected types; this is the +default .IP \[bu] 2 -\f[CB]package\f[R]: Shows public, protected, and package types. +\f[CB]package\f[R] \-\-\- shows public, protected, and package types .IP \[bu] 2 -\f[CB]private\f[R]: Shows all types. +\f[CB]private\f[R] \-\-\- shows all types .RE .TP .B \f[CB]\-subpackages\f[R] \f[I]subpkglist\f[R] @@ -404,20 +401,24 @@ For example, the following commands generates documentation for packages named \f[CB]java\f[R] and \f[CB]javax.swing\f[R] and all of their subpackages. .IP \[bu] 2 -\f[B]Linux and OS X:\f[R] +\f[B]Linux and macOS:\f[R] .RS 2 -.RS -.PP -\f[CB]javadoc\ \-d\ docs\ \-sourcepath\ /home/user/src\ \-subpackages\ java:javax.swing\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-d\ docs\ \-sourcepath\ /home/user/src\ \-subpackages\ java:javax.swing +\f[R] +.fi .RE .IP \[bu] 2 \f[B]Windows:\f[R] .RS 2 -.RS -.PP -\f[CB]javadoc\ \-d\ docs\ \-sourcepath\ \\user\\src\ \-subpackages\ java:javax.swing\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-d\ docs\ \-sourcepath\ \\user\\src\ \-subpackages\ java:javax.swing +\f[R] +.fi .RE .RE .TP @@ -440,14 +441,12 @@ Prints version information. Reports an error if any warnings occur. .RS .RE -.SH EXTENDED OPTIONS -.PP -\f[B]Note:\f[R] +.SS Extra \f[CB]javadoc\f[R] Options .PP -The extended options for \f[CB]javadoc\f[R] are subject to change without -notice. +\f[I]Note:\f[R] The additional options for \f[CB]javadoc\f[R] are subject +to change without notice. .PP -The following extended \f[CB]javadoc\f[R] options are equivalent to +The following additional \f[CB]javadoc\f[R] options are equivalent to corresponding \f[CB]javac\f[R] options. See \f[I]Extra Options\f[R] in \f[B]javac\f[R] for the detailed descriptions of using these options: @@ -461,25 +460,42 @@ descriptions of using these options: \f[CB]\-Xmaxerrs\f[R] .IP \[bu] 2 \f[CB]\-Xmaxwarns\f[R] -.SH STANDARD DOCLET OPTIONS +.SS Standard Options for the Standard Doclet .PP The following options are provided by the standard doclet. .TP -.B \f[CB]\-\-add\-stylesheet\f[R] \f[I]file\f[R] -Adds additional stylesheet file for the generated documentation. -This option can be used one or more times to specify additional -stylesheets included in the documentation. +.B \f[CB]\-\-add\-script\f[R] \f[I]file\f[R] +Adds \f[I]file\f[R] as an additional JavaScript file to the generated +documentation. +This option can be used one or more times to specify additional script +files. .RS .PP Command\-line example: .RS .PP -\f[CB]javadoc\ \-\-add\-stylesheet\ new_stylesheet_1.css\ \-\-add\-stylesheet\ new_stylesheet_2.css\ pkg_foo\f[R] +\f[CB]javadoc\ \-\-add\-script\ first_script.js\ \-\-add\-script\ second_script.js\ pkg_foo\f[R] .RE .RE .TP +.B \f[CB]\-\-add\-stylesheet\f[R] \f[I]file\f[R] +Adds \f[I]file\f[R] as an additional stylesheet file to the generated +documentation. +This option can be used one or more times to specify additional +stylesheets included in the documentation. +.RS +.PP +Command\-line example: +.IP +.nf +\f[CB] +javadoc\ \-\-add\-stylesheet\ new_stylesheet_1.css\ \-\-add\-stylesheet\ new_stylesheet_2.css\ pkg_foo +\f[R] +.fi +.RE +.TP .B \f[CB]\-\-allow\-script\-in\-comments\f[R] -Allow JavaScript in options and comments +Allow JavaScript in options and comments. .RS .RE .TP @@ -506,19 +522,23 @@ Registry, Character Sets\f[R] .RS .PP For example: -.RS -.PP -\f[CB]javadoc\ \-charset\ "iso\-8859\-1"\ mypackage\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-charset\ "iso\-8859\-1"\ mypackage +\f[R] +.fi .PP This command inserts the following line in the head of every generated page: -.RS -.PP -\f[CB]\f[R] -.RE +.IP +.nf +\f[CB] + +\f[R] +.fi .PP -The \f[CB]META\f[R] tag is described in the \f[B]HTML standard (4197265 +The \f[CB]meta\f[R] tag is described in the \f[B]HTML standard (4197265 and 4137321), HTML Document Representation\f[R] [http://www.w3.org/TR/REC\-html40/charset.html#h\-5.2.2]. .RE @@ -534,24 +554,28 @@ The destination directory is automatically created when the \f[CB]javadoc\f[R] tool runs. .RS .IP \[bu] 2 -\f[B]Linux and OS X:\f[R] For example, the following command generates +\f[B]Linux and macOS:\f[R] For example, the following command generates the documentation for the package \f[CB]com.mypackage\f[R] and saves the results in the \f[CB]/user/doc/\f[R] directory: .RS 2 -.RS -.PP -\f[CB]javadoc\ \-d\ /user/doc/\ com.mypackage\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-d\ /user/doc/\ com.mypackage +\f[R] +.fi .RE .IP \[bu] 2 \f[B]Windows:\f[R] For example, the following command generates the documentation for the package \f[CB]com.mypackage\f[R] and saves the results in the \f[CB]\\user\\doc\\\f[R] directory: .RS 2 -.RS -.PP -\f[CB]javadoc\ \-d\ \\user\\doc\\\ com.mypackage\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-d\ \\user\\doc\\\ com.mypackage +\f[R] +.fi .RE .RE .TP @@ -572,14 +596,15 @@ Of the three available options, at most, only the input and an output encoding option are used in a single encoding command. If you specify both input and output encoding options in a command, they must be the same value. -If you specify neither output option, it the tool defaults to the input -encoding. +If you specify neither output option, it defaults to the input encoding. .PP For example: -.RS -.PP -\f[CB]javadoc\ \-docencoding\ "iso\-8859\-1"\ mypackage\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-docencoding\ "iso\-8859\-1"\ mypackage +\f[R] +.fi .RE .TP .B \f[CB]\-docfilessubdirs\f[R] @@ -596,12 +621,12 @@ it does, you must enclose the title in quotation marks. Additional quotation marks within the \f[CB]title\f[R] tag must be escaped. For example, -\f[CB]javadoc\ \-doctitle\ "My\ Library
        v1.0"\ com.mypackage.\f[R] +\f[CB]javadoc\ \-doctitle\ "My\ Library
        v1.0"\ com.mypackage\f[R]. .RS .RE .TP .B \f[CB]\-excludedocfilessubdir\f[R] \f[I]name\f[R] -Excludes any doc files sub directories with the given name. +Excludes any doc files subdirectories with the given name. Enables deep copying of doc\-files directories. Subdirectories and all contents are recursively copied to the destination. @@ -635,7 +660,7 @@ The \f[CB]header\f[R] can contain HTML tags and white space, but when it does, the \f[CB]header\f[R] must be enclosed in quotation marks. Use escape characters for internal quotation marks within a header. For example, -\f[CB]javadoc\ \-header\ "My\ Library
        v1.0"\ com.mypackage.\f[R] +\f[CB]javadoc\ \-header\ "My\ Library
        v1.0"\ com.mypackage\f[R]. .RS .RE .TP @@ -653,20 +678,24 @@ accordingly. For example: .RS .IP \[bu] 2 -\f[B]Linux and OS X:\f[R] +\f[B]Linux and macOS:\f[R] .RS 2 -.RS -.PP -\f[CB]javadoc\ \-helpfile\ /home/user/myhelp.html\ java.awt.\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-helpfile\ /home/user/myhelp.html\ java.awt +\f[R] +.fi .RE .IP \[bu] 2 \f[B]Windows:\f[R] .RS 2 -.RS -.PP -\f[CB]javadoc\ \-helpfile\ C:\\user\\myhelp.html\ java.awt.\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-helpfile\ C:\\user\\myhelp.html\ java.awt +\f[R] +.fi .RE .RE .TP @@ -678,19 +707,21 @@ compatibility. .TP .B \f[CB]\-\-javafx\f[R] or \f[CB]\-javafx\f[R] Enables JavaFX functionality. +This option is enabled by default if the JavaFX library classes are +detected on the module path. .RS .RE .TP .B \f[CB]\-keywords\f[R] -Adds HTML keyword \f[CB]\f[R] tags to the generated file for each +Adds HTML keyword \f[CB]\f[R] tags to the generated file for each class. -These tags can help search engines that look for \f[CB]\f[R] tags +These tags can help search engines that look for \f[CB]\f[R] tags find the pages. Most search engines that search the entire Internet don\[aq]t look at -\f[CB]\f[R] tags, because pages can misuse them. +\f[CB]\f[R] tags, because pages can misuse them. Search engines offered by companies that confine their searches to their -own website can benefit by looking at \f[CB]\f[R] tags. -The \f[CB]\f[R] tags include the fully qualified name of the class +own website can benefit by looking at \f[CB]\f[R] tags. +The \f[CB]\f[R] tags include the fully qualified name of the class and the unqualified names of the fields and methods. Constructors aren\[aq]t included because they are identical to the class name. @@ -699,10 +730,10 @@ For example, the class \f[CB]String\f[R] starts with these keywords: .IP .nf \f[CB] - - - - + + + + \f[R] .fi .RE @@ -721,10 +752,8 @@ Either a \f[CB]package\-list\f[R] or an \f[CB]element\-list\f[R] file must be in this \f[I]url\f[R] directory (otherwise, use the \f[CB]\-linkoffline\f[R] option). .PP -\f[B]Note:\f[R] -.PP -The \f[CB]package\-list\f[R] and \f[CB]element\-list\f[R] files are -generated by the \f[CB]javadoc\f[R] tool when generating the API +\f[I]Note:\f[R] The \f[CB]package\-list\f[R] and \f[CB]element\-list\f[R] +files are generated by the \f[CB]javadoc\f[R] tool when generating the API documentation and should not be modified by the user. .PP When you use the \f[CB]javadoc\f[R] tool to document packages, it uses the @@ -769,6 +798,15 @@ Uniform Resource Locators\f[R] [http://www.ietf.org/rfc/rfc1738.txt]. .fi .RE .TP +.B \f[CB]\-\-link\-modularity\-mismatch\f[R] (\f[CB]warn\f[R]|\f[CB]info\f[R]) +Specifies whether external documentation with wrong modularity (e.g. +non\-modular documentation for a modular library, or the reverse case) +should be reported as a warning (\f[CB]warn\f[R]) or just a message +(\f[CB]info\f[R]). +The default behavior is to report a warning. +.RS +.RE +.TP .B \f[CB]\-linkoffline\f[R] \f[I]url1\f[R] \f[I]url2\f[R] This option is a variation of the \f[CB]\-link\f[R] option. They both create links to \f[CB]javadoc\f[R] generated documentation for @@ -788,10 +826,8 @@ the URL location, but does exist at a different location and can be specified by either the \f[CB]package\-list\f[R] or \f[CB]element\-list\f[R] file (typically local). .PP -\f[B]Note:\f[R] -.PP -The \f[CB]package\-list\f[R] and \f[CB]element\-list\f[R] files are -generated by the \f[CB]javadoc\f[R] tool when generating the API +\f[I]Note:\f[R] The \f[CB]package\-list\f[R] and \f[CB]element\-list\f[R] +files are generated by the \f[CB]javadoc\f[R] tool when generating the API documentation and should not be modified by the user. .PP If \f[I]url1\f[R] is accessible only on the World Wide Web, then the @@ -820,6 +856,38 @@ root of the packages being linked to. See \f[I]url\f[R] in the \f[CB]\-link\f[R] option. .RE .TP +.B \f[CB]\-\-link\-platform\-properties\f[R] \f[I]url\f[R] +Specifies a properties file used to configure links to platform +documentation. +.RS +.PP +The \f[I]url\f[R] argument is expected to point to a properties file +containing one or more entries with the following format, where +\f[CB]\f[R] is the platform version as passed to the +\f[CB]\-\-release\f[R] or \f[CB]\-\-source\f[R] option and \f[CB]\f[R] is +the base URL of the corresponding platform API documentation: +.IP +.nf +\f[CB] +doclet.platform.docs.= +\f[R] +.fi +.PP +For instance, a properties file containing URLs for releases 15 to 17 +might contain the following lines: +.IP +.nf +\f[CB] +doclet.platform.docs.15=https://example.com/api/15/ +doclet.platform.docs.16=https://example.com/api/16/ +doclet.platform.docs.17=https://example.com/api/17/ +\f[R] +.fi +.PP +If the properties file does not contain an entry for a particular +release no platform links are generated. +.RE +.TP .B \f[CB]\-linksource\f[R] Creates an HTML version of each source file (with line numbers) and adds links to them from the standard HTML documentation. @@ -840,17 +908,21 @@ classes or interfaces are accessible through links. Each link appears on the name of the identifier in its declaration. For example, the link to the source code of the \f[CB]Button\f[R] class would be on the word \f[CB]Button\f[R]: -.RS -.PP -\f[CB]public\ class\ Button\ extends\ Component\ implements\ Accessible\f[R] -.RE +.IP +.nf +\f[CB] +public\ class\ Button\ extends\ Component\ implements\ Accessible +\f[R] +.fi .PP The link to the source code of the \f[CB]getLabel\f[R] method in the \f[CB]Button\f[R] class is on the word \f[CB]getLabel\f[R]: -.RS -.PP -\f[CB]public\ String\ getLabel()\f[R] -.RE +.IP +.nf +\f[CB] +public\ String\ getLabel() +\f[R] +.fi .RE .TP .B \f[CB]\-\-main\-stylesheet\f[R] \f[I]file\f[R] or \f[CB]\-stylesheetfile\f[R] \f[I]file\f[R] @@ -865,10 +937,12 @@ The \f[CB]\-\-main\-stylesheet\f[R] option is the preferred form. .RS .PP Command\-line example: -.RS -.PP -\f[CB]javadoc\ \-\-main\-stylesheet\ main_stylesheet.css\ pkg_foo\f[R] -.RE +.IP +.nf +\f[CB] +javadoc\ \-\-main\-stylesheet\ main_stylesheet.css\ pkg_foo +\f[R] +.fi .RE .TP .B \f[CB]\-nocomment\f[R] @@ -901,15 +975,9 @@ you want to make the navigation bar cleaner. .RS .RE .TP -.B \f[CB]\-\-no\-frames\f[R] -This option is a no\-op and is just retained for backwards -compatibility. -.RS -.RE -.TP .B \f[CB]\-nohelp\f[R] -Omits the HELP link in the navigation bars at the top and bottom of each -page of output. +Omits the HELP link in the navigation bar at the top of each page of +output. .RS .RE .TP @@ -922,7 +990,7 @@ The index is produced by default. .B \f[CB]\-nonavbar\f[R] Prevents the generation of the navigation bar, header, and footer, that are usually found at the top and bottom of the generated pages. -The \f[CB]\-nonavbar\f[R] option has no affect on the \f[CB]\-bottom\f[R] +The \f[CB]\-nonavbar\f[R] option has no effect on the \f[CB]\-bottom\f[R] option. The \f[CB]\-nonavbar\f[R] option is useful when you are interested only in the content and have no need for navigation, such as when you are @@ -930,6 +998,12 @@ converting the files to PostScript or PDF for printing only. .RS .RE .TP +.B \f[CB]\-\-no\-platform\-links\f[R] +Prevents the generation of links to platform documentation. +These links are generated by default. +.RS +.RE +.TP .B \f[CB]\-noqualifier\f[R] \f[I]name1\f[R]\f[CB]:\f[R]\f[I]name2\f[R]... Excludes the list of qualifiers from the output. The package name is removed from places where class or interface names @@ -1000,14 +1074,14 @@ that contains the topmost package directories. In this location, no path is needed when documenting packages, because the \f[CB]\-sourcepath\f[R] option points to this file. .IP \[bu] 2 -\f[B]Linux and OS X:\f[R] For example, if the source tree for the -\f[CB]java.lang\f[R] package is \f[CB]/src/classes/java/lang/\f[R], then you -could place the overview file at /src/classes/overview.html. +\f[B]Linux and macOS:\f[R] For example, if the source tree for the +\f[CB]java.lang\f[R] package is \f[CB]src/classes/java/lang/\f[R], then you +could place the overview file at src/classes/overview.html. .IP \[bu] 2 \f[B]Windows:\f[R] For example, if the source tree for the -\f[CB]java.lang\f[R] package is \f[CB]\\src\\classes\\java\\lang\\\f[R], -then you could place the overview file at -\f[CB]\\src\\classes\\overview.html\f[R] +\f[CB]java.lang\f[R] package is \f[CB]src\\classes\\java\\lang\\\f[R], then +you could place the overview file at +\f[CB]src\\classes\\overview.html\f[R] .PP The overview page is created only when you pass two or more package names to the \f[CB]javadoc\f[R] tool. @@ -1022,6 +1096,43 @@ document default serializable fields and \f[CB]writeExternal\f[R] methods. .RS .RE .TP +.B \f[CB]\-\-since\f[R] \f[I]release\f[R](\f[CB],\f[R]\f[I]release\f[R])* +Generates documentation for APIs that were added or newly deprecated in +the specified \f[I]release\f[R]s. +.RS +.PP +If the \f[CB]\@since\f[R] tag in the \f[CB]javadoc\f[R] comment of an +element in the documented source code matches a \f[I]release\f[R] passed +as option argument, information about the element and the release it was +added in is included in a "New API" page. +.PP +If the "Deprecated API" page is generated and the \f[CB]since\f[R] element +of the \f[CB]java.lang.Deprecated\f[R] annotation of a documented element +matches a \f[I]release\f[R] in the option arguments, information about +the release the element was deprecated in is added to the "Deprecated +API" page. +.PP +Releases are compared using case\-sensitive string comparison. +.RE +.TP +.B \f[CB]\-\-since\-label\f[R] \f[I]text\f[R] +Specifies the \f[I]text\f[R] to use in the heading of the "New API" page. +This may contain information about the releases covered in the page, +e.g. +"New API in release 2.0", or "New API since release 1". +.RS +.RE +.TP +.B \f[CB]\-\-snippet\-path\f[R] \f[I]snippetpathlist\f[R] +Specifies the search paths for finding files for external snippets. +The \f[I]snippetpathlist\f[R] can contain multiple paths by separating +them with the platform path separator (\f[CB];\f[R] on Windows; \f[CB]:\f[R] +on other platforms.) The Standard Doclet first searches the +\f[CB]snippet\-files\f[R] subdirectory in the package containing the +snippet, and then searches all the directories in the given list. +.RS +.RE +.TP .B \f[CB]\-sourcetab\f[R] \f[I]tablength\f[R] Specifies the number of spaces each tab uses in the source. .RS @@ -1141,8 +1252,8 @@ Specifies the title to be placed in the HTML \f[CB]\f[R] tag. The text specified in the \f[CB]title\f[R] tag appears in the window title and in any browser bookmarks (favorite places) that someone creates for this page. -This title shouldn\[aq]t contain any HTML tags because the browser -doesn\[aq]t interpret them correctly. +This title should not contain any HTML tags because a browser will not +interpret them correctly. Use escape characters on any internal quotation marks within the \f[CB]title\f[R] tag. If the \f[CB]\-windowtitle\f[R] option is omitted, then the @@ -1152,131 +1263,276 @@ For example, \f[CB]javadoc\ \-windowtitle\ "My\ Library"\ com.mypackage\f[R]. .RS .RE -.SH ADDITIONAL OPTIONS PROVIDED BY THE STANDARD DOCLET +.SS Extra Options for the Standard Doclet .PP -The following are additional options provided by the standard doclet and +The following are additional options provided by the Standard Doclet and are subject to change without notice. Additional options are less commonly used or are otherwise regarded as advanced. .TP -.B \f[CB]\-Xdoclint\f[R] -Enables recommended checks for problems in documentation comments. +.B \f[CB]\-\-legal\-notices\f[R] (\f[CB]default\f[R]|\f[CB]none\f[R]|\f[I]directory\f[R]) +Specifies the location from which to copy legal files to the generated +documentation. +If the option is not specified or is used with the value +\f[CB]default\f[R], the files are copied from the default location. +If the argument is used with value \f[CB]none\f[R], no files are copied. +Every other argument is interpreted as directory from which to copy the +legal files. .RS .RE .TP -.B \f[CB]\-Xdoclint:\f[R](\f[CB]all\f[R]|\f[CB]none\f[R]|[\f[CB]\-\f[R]]\f[I]group\f[R]) -Enable or disable specific checks for bad references, accessibility -issues, missing documentation comments, errors in documentation comment -syntax and missing HTML tags. +.B \f[CB]\-\-no\-frames\f[R] +This option is a no\-op and is just retained for backwards +compatibility. +.RS +.RE +.TP +.B \f[CB]\-Xdoclint\f[R] +Enables recommended checks for problems in documentation comments. .RS -.PP -This option enables the \f[CB]javadoc\f[R] tool to check for all -documentation comments included in the generated output. -You can select which items to include in the generated output with the -standard options \f[CB]\-public\f[R], \f[CB]\-protected\f[R], -\f[CB]\-package\f[R] and \f[CB]\-private\f[R]. -.PP -When the \f[CB]\-Xdoclint\f[R] option is enabled, it reports issues with -messages similar to the \f[CB]javac\f[R] command. -The \f[CB]javadoc\f[R] tool prints a message, a copy of the source line, -and a caret pointing at the exact position where the error was detected. -Messages may be either warnings or errors, depending on their severity -and the likelihood to cause an error if the generated documentation were -to be run through a validator. -For example: missing documentation comments, duplicate information, and -extraneous comments do not cause the \f[CB]javadoc\f[R] tool to generate -invalid HTML, so these issues are reported as warnings; syntax errors, -missing required HTML end tags, and references to missing or misspelled -elements cause the \f[CB]javadoc\f[R] tool to generate invalid output, so -these issues are reported as errors. -.PP -\f[CB]\-Xdoclint\f[R] option validates input comments based upon the -requested markup. .PP By default, the \f[CB]\-Xdoclint\f[R] option is enabled. Disable it with the option \f[CB]\-Xdoclint:none\f[R]. .PP -The following options change what the \f[CB]\-Xdoclint\f[R] option -reports: -.IP \[bu] 2 -\f[CB]\-Xdoclint\ none\f[R]: Disables the \f[CB]\-Xdoclint\f[R] option -.IP \[bu] 2 -\f[CB]\-Xdoclint\f[R] \f[I]group\f[R]: Enables \f[I]group\f[R] checks -.IP \[bu] 2 -\f[CB]\-Xdoclint\ all\f[R]: Enables all groups of checks -.IP \[bu] 2 -\f[CB]\-Xdoclint\ all,\-\f[R]\f[I]group\f[R]: Enables all checks except -\f[I]group\f[R] checks -.PP -The \f[I]group\f[R] variable has one of the following values: -.IP \[bu] 2 -\f[CB]accessibility\f[R]: Checks for the issues to be detected by an -accessibility checker (for example, no caption or summary attributes -specified in a \f[CB]<table>\f[R] tag). -.IP \[bu] 2 -\f[CB]html\f[R]: Detects high\-level HTML issues, such as putting block -elements inside inline elements, or not closing elements that require an -end tag. -The rules are derived from the \f[B]HTML 4 Specification\f[R] -[https://www.w3.org/TR/html4/] or the \f[B]HTML 5 Specification\f[R] -[http://www.w3.org/TR/2014/REC\-html5\-20141028/] based on the standard -doclet \f[CB]html\f[R] output generation selected. -This type of check enables the \f[CB]javadoc\f[R] tool to detect HTML -issues that some browsers might not interpret as intended. -.IP \[bu] 2 -\f[CB]missing\f[R]: Checks for missing documentation comments or tags (for -example, a missing comment or class, or a missing \f[CB]\@return\f[R] tag -or similar tag on a method). -.IP \[bu] 2 -\f[CB]reference\f[R]: Checks for issues relating to the references to Java -API elements from documentation comment tags (for example, item not -found in \f[CB]\@see\f[R], or a bad name after \f[CB]\@param)\f[R]. -.IP \[bu] 2 -\f[CB]syntax\f[R]: Checks for low level issues like unescaped angle -brackets (\f[CB]<\f[R] and \f[CB]>\f[R]) and ampersands (\f[CB]&\f[R]) and -invalid documentation comment tags. -.PP -You can specify the \f[CB]\-Xdoclint\f[R] option multiple times to enable -the option to check errors and warnings in multiple categories. -Alternatively, you can specify multiple error and warning categories by -using the preceding options. -For example, use either of the following commands to check for the HTML, -syntax, and accessibility issues in the file \f[I]filename\f[R]. -.RS -.PP -\f[CB]javadoc\ \-Xdoclint:html\ \-Xdoclint:syntax\ \-Xdoclint:accessibility\f[R] -\f[I]filename\f[R] +For more details, see \f[B]DocLint\f[R]. .RE +.TP +.B \f[CB]\-Xdoclint:\f[R]\f[I]flag\f[R],\f[I]flag\f[R],... +Enable or disable specific checks for different kinds of issues in +documentation comments. .RS .PP -\f[CB]javadoc\ \-Xdoclint:html,syntax,accessibility\f[R] \f[I]filename\f[R] -.RE +Each \f[I]flag\f[R] can be one of \f[CB]all\f[R], \f[CB]none\f[R], or +\f[CB][\-]\f[R]\f[I]group\f[R] where \f[I]group\f[R] has one of the +following values: \f[CB]accessibility\f[R], \f[CB]html\f[R], +\f[CB]missing\f[R], \f[CB]reference\f[R], \f[CB]syntax\f[R]. +For more details on these values, see \f[B]DocLint Groups\f[R]. .PP -\f[B]Note:\f[R] +When specifying two or more flags, you can either use a single +\f[CB]\-Xdoclint:...\f[R] option, listing all the desired flags, or you +can use multiple options giving one or more flag in each option. +For example, use either of the following commands to check for the HTML, +syntax, and accessibility issues in the file \f[CB]MyFile.java\f[R]. +.IP +.nf +\f[CB] +javadoc\ \-Xdoclint:html\ \-Xdoclint:syntax\ \-Xdoclint:accessibility\ MyFile.java +javadoc\ \-Xdoclint:html,syntax,accessibility\ MyFile.java +\f[R] +.fi .PP -The \f[CB]javadoc\f[R] tool doesn\[aq]t guarantee the completeness of -these checks. -In particular, it isn\[aq]t a full HTML compliance checker. -The goal of the \-\f[CB]Xdoclint\f[R] option is to enable the -\f[CB]javadoc\f[R] tool to report majority of common errors. +The following examples illustrate how to change what DocLint reports: +.IP \[bu] 2 +\f[CB]\-Xdoclint:none\f[R] \-\-\- disables all checks +.IP \[bu] 2 +\f[CB]\-Xdoclint:\f[R]\f[I]group\f[R] \-\-\- enables \f[I]group\f[R] checks +.IP \[bu] 2 +\f[CB]\-Xdoclint:all\f[R] \-\-\- enables all groups of checks +.IP \[bu] 2 +\f[CB]\-Xdoclint:all,\-\f[R]\f[I]group\f[R] \-\-\- enables all checks +except \f[I]group\f[R] checks .PP -The \f[CB]javadoc\f[R] tool doesn\[aq]t attempt to fix invalid input, it -just reports it. +For more details, see \f[B]DocLint\f[R]. .RE .TP .B \f[CB]\-Xdoclint/package:\f[R][\f[CB]\-\f[R]]\f[I]packages\f[R] Enables or disables checks in specific packages. \f[I]packages\f[R] is a comma separated list of package specifiers. A package specifier is either a qualified name of a package or a package -name prefix followed by \f[CB]*\f[R], which expands to all sub packages of +name prefix followed by \f[CB]*\f[R], which expands to all subpackages of the given package. Prefix the package specifier with \f[CB]\-\f[R] to disable checks for the specified packages. .RS +.PP +For more details, see \f[B]DocLint\f[R]. .RE .TP .B \f[CB]\-Xdocrootparent\f[R] \f[I]url\f[R] -Replaces all \f[CB]\@docRoot\f[R] items followed by\f[CB]/..\f[R] in Javadoc -comments with the \f[I]url\f[R]. +Replaces all \f[CB]\@docRoot\f[R] items followed by \f[CB]/..\f[R] in +documentation comments with \f[I]url\f[R]. .RS .RE +.SH DOCLINT +.PP +DocLint provides the ability to check for possible problems in +documentation comments. +Problems may be reported as warnings or errors, depending on their +severity. +For example, a missing comment may be bad style that deserves a warning, +but a link to an unknown Java declaration is more serious and deserves +an error. +Problems are organized into \f[B]groups\f[R], and options can be used to +enable or disable messages in one or more groups. +Within the source code, messages in one or more groups can be +\f[B]suppressed\f[R] by using \f[CB]\@SuppressWarnings\f[R] annotations. +.PP +When invoked from \f[CB]javadoc\f[R], by default DocLint checks all +comments that are used in the generated documentation. +It thus relies on other command\-line options to determine which +declarations, and which corresponding documentation comments will be +included. +\f[I]Note:\f[R] this may mean that even comments on some private members +of serializable classes will also be checked, if the members need to be +documented in the generated \f[CB]Serialized\ Forms\f[R] page. +.PP +In contrast, when DocLint is invoked from \f[CB]javac\f[R], DocLint solely +relies on the various \f[CB]\-Xdoclint...\f[R] options to determine which +documentation comments to check. +.PP +DocLint doesn\[aq]t attempt to fix invalid input, it just reports it. +.PP +\f[I]Note:\f[R] DocLint doesn\[aq]t guarantee the completeness of these +checks. +In particular, it isn\[aq]t a full HTML compliance checker. +The goal is to just report common errors in a convenient manner. +.SS Groups +.PP +The checks performed by DocLint are organized into groups. +The warnings and errors in each group can be enabled or disabled with +command\-line options, or suppressed with \f[CB]\@SuppressWarnings\f[R] +annotations. +.PP +The groups are as follows: +.IP \[bu] 2 +\f[CB]accessibility\f[R] \-\-\- Checks for issues related to +accessibility. For example, no \f[CB]alt\f[R] attribute specified in an +\f[CB]<img>\f[R] element, or no caption or summary attributes specified in +a \f[CB]<table>\f[R] element. +.RS 2 +.PP +Issues are reported as errors if a downstream validation tool might be +expected to report an error in the files generated by \f[CB]javadoc\f[R]. +.PP +For reference, see the \f[B]Web Content Accessibility Guidelines\f[R] +[https://www.w3.org/WAI/standards\-guidelines/wcag/]. +.RE +.IP \[bu] 2 +\f[CB]html\f[R] \-\-\- Detects common high\-level HTML issues. For +example, putting block elements inside inline elements, or not closing +elements that require an end tag. +.RS 2 +.PP +Issues are reported as errors if a downstream validation tool might be +expected to report an error in the files generated by \f[CB]javadoc\f[R]. +.PP +For reference, see the \f[B]HTML Living Standard\f[R] +[https://html.spec.whatwg.org/multipage/]. +.RE +.IP \[bu] 2 +\f[CB]missing\f[R] \-\-\- Checks for missing documentation comments or +tags. For example, a missing comment on a class declaration, or a +missing \f[CB]\@param\f[R] or \f[CB]\@return\f[R] tag in the comment for a +method declaration. +.RS 2 +.PP +Issues related to missing items are typically reported as warnings +because they are unlikely to be reported as errors by downstream +validation tools that may be used to check the output generated by +\f[CB]javadoc\f[R]. +.RE +.IP \[bu] 2 +\f[CB]reference\f[R] \-\-\- Checks for issues relating to the references +to Java API elements from documentation comment tags. For example, the +reference in \f[CB]\@see\f[R] or \f[CB]{\@link\ ...}\f[R] cannot be found, +or a bad name is given for \f[CB]\@param\f[R] or \f[CB]\@throws\f[R]. +.RS 2 +.PP +Issues are typically reported as errors because while the issue may not +cause problems in the generated files, the author has likely made a +mistake that will lead to incorrect or unexpected documentation. +.RE +.IP \[bu] 2 +\f[CB]syntax\f[R] \-\-\- Checks for low\-level syntactic issues in +documentation comments. For example, unescaped angle brackets +(\f[CB]<\f[R] and \f[CB]>\f[R]) and ampersands (\f[CB]&\f[R]) and invalid +documentation comment tags. +.RS 2 +.PP +Issues are typically reported as errors because the issues may lead to +incorrect or unexpected documentation. +.RE +.SS Suppressing Messages +.PP +DocLint checks for and recognizes two strings that may be present in the +arguments for an \f[CB]\@SuppressWarnings\f[R] annotation. +.IP \[bu] 2 +\f[CB]doclint\f[R] +.IP \[bu] 2 +\f[CB]doclint:\f[R]\f[I]LIST\f[R] +.PP +where \f[I]LIST\f[R] is a comma\-separated list of one or more of +\f[CB]accessibility\f[R], \f[CB]html\f[R], \f[CB]missing\f[R], +\f[CB]syntax\f[R], \f[CB]reference\f[R]. +.PP +The names in \f[I]LIST\f[R] are the same \f[B]group\f[R] names supported +by the command\-line \f[CB]\-Xdoclint\f[R] option for \f[CB]javac\f[R] and +\f[CB]javadoc\f[R]. +(This is the same convention honored by the \f[CB]javac\f[R] +\f[CB]\-Xlint\f[R] option and the corresponding names supported by +\f[CB]\@SuppressWarnings\f[R].) +.PP +The names in \f[I]LIST\f[R] can equivalently be specified in separate +arguments of the annotation. +For example, the following are equivalent: +.IP \[bu] 2 +\f[CB]\@SuppressWarnings("doclint:accessibility,missing")\f[R] +.IP \[bu] 2 +\f[CB]\@SuppressWarnings("doclint:accessibility",\ "doclint:missing")\f[R] +.PP +When DocLint detects an issue in a documentation comment, it checks for +the presence of \f[CB]\@SuppressWarnings\f[R] on the associated +declaration and on all lexically enclosing declarations. +The issue will be ignored if any such annotation is found containing the +simple string \f[CB]doclint\f[R] or the longer form \f[CB]doclint:LIST\f[R] +where \f[I]LIST\f[R] contains the name of the group for the issue. +.PP +\f[I]Note:\f[R] as with other uses of \f[CB]\@SuppressWarnings\f[R], using +the annotation on a module or package declaration only affects that +declaration; it does not affect the contents of the module or package in +other source files. +.PP +All messages related to an issue are suppressed by the presence of an +appropriate \f[CB]\@SuppressWarnings\f[R] annotation: this includes errors +as well as warnings. +.PP +\f[I]Note:\f[R] It is only possible to \f[I]suppress\f[R] messages. +If an annotation of \f[CB]\@SuppressWarnings("doclint")\f[R] is given on a +top\-level declaration, all DocLint messages for that declaration and +any enclosed declarations will be suppressed; it is not possible to +selectively re\-enable messages for issues in enclosed declarations. +.SS Comparison with downstream validation tools +.PP +DocLint is a utility built into \f[CB]javac\f[R] and \f[CB]javadoc\f[R] that +checks the content of documentation comments, as found in source files. +In contrast, downstream validation tools can be used to validate the +output generated from those documentation comments by \f[CB]javadoc\f[R] +and the Standard Doclet. +.PP +Although there is some overlap in functionality, the two mechanisms are +different and each has its own strengths and weaknesses. +.IP \[bu] 2 +Downstream validation tools can check the end result of any generated +documentation, as it will be seen by the end user. +This includes content from all sources, including documentation +comments, the Standard Doclet itself, user\-provided taglets, and +content supplied via command\-line options. +Because such tools are analyzing complete HTML pages, they can do more +complete checks than can DocLint. +However, when a problem is found in the generated pages, it can be +harder to track down exactly where in the build pipeline the problem +needs to be fixed. +.IP \[bu] 2 +DocLint checks the content of documentation comments, in source files. +This makes it very easy to identify the exact position of any issues +that may be found. +DocLint can also detect some semantic errors in documentation comments +that downstream tools cannot detect, such as missing comments, using an +\f[CB]\@return\f[R] tag in a method returning \f[CB]void\f[R], or an +\f[CB]\@param\f[R] tag describing a non\-existent parameter. +But by its nature, DocLint cannot report on problems such as missing +links, or errors in user\-provided custom taglets, or problems in the +Standard Doclet itself. +It also cannot reliably detect errors in documentation comments at the +boundaries between content in a documentation comment and content +generated by a custom taglet. diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1 index a5f16e6a82d25b7939e56ab608d17a1a40ef3a7b..9342943ac2a99b40ac22e85c8823564747d217f8 100644 --- a/src/jdk.jcmd/share/man/jcmd.1 +++ b/src/jdk.jcmd/share/man/jcmd.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JCMD" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JCMD" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP @@ -596,8 +596,8 @@ To list available options, use the \f[CB]JAVA_HOME\f[R]/bin/jfr tool. .IP \[bu] 2 \f[CB]event\-setting\f[R]: (Optional) Specifies the event setting value to modify. -Use the form: #= To add a new event setting, prefix the event name with -\[aq]+\[aq]. +Use the form: \f[CB]<event\-name>#<setting\-name>=<value>\f[R] To add a +new event setting, prefix the event name with \[aq]+\[aq]. .PP You can specify values for multiple event settings and .jfc options by separating them with a whitespace. @@ -802,7 +802,8 @@ false) .RE .TP .B \f[CB]VM.cds\f[R] [\f[I]arguments\f[R]] -Dump a static or dynamic shared archive including all shareable classes. +Dumps a static or dynamic shared archive that includes all currently +loaded classes. .RS .PP Impact: Medium \-\-\- pause time depends on number of loaded classes @@ -811,11 +812,22 @@ Permission: \f[CB]java.lang.management.ManagementPermission(monitor)\f[R] .PP \f[I]arguments\f[R]: .IP \[bu] 2 -\f[CB]subcmd\f[R]: \f[CB]static_dump\f[R] | \f[CB]dynamic_dump\f[R] (STRING, -no default value) +\f[CB]subcmd\f[R]: must be either \f[CB]static_dump\f[R] or +\f[CB]dynamic_dump\f[R] (STRING, no default value) .IP \[bu] 2 \f[CB]filename\f[R]: (Optional) Name of the shared archive to be dumped (STRING, no default value) +.PP +If \f[CB]filename\f[R] is not specified, a default file name is chosen +using the pid of the target JVM process. +For example, java_pid1234_static.jsa, java_pid5678_dynamic.jsa, etc. +.PP +If \f[CB]filename\f[R] is not specified as an absolute path, the archive +file is created in a directory relative to the current directory of the +target JVM process. +.PP +If \f[CB]dynamic_dump\f[R] is specified, the target JVM must be started +with the JVM option \f[CB]\-XX:+RecordDynamicDumpInfo\f[R]. .RE .TP .B \f[CB]VM.classloaders\f[R] [\f[I]options\f[R]] @@ -873,9 +885,9 @@ The following \f[I]options\f[R] must be specified using either \f[CB]\-i\f[R]: (Optional) Inherited interfaces should be printed. (BOOLEAN, false) .IP \[bu] 2 -\f[CB]\-s\f[R]: (Optional) If a class name is specified, it prints the -subclasses. -If the class name is not specified, only the superclasses are printed. +\f[CB]\-s\f[R]: (Optional) If a classname is specified, print its +subclasses in addition to its superclasses. +Without this option only the superclasses will be printed. (BOOLEAN, false) .PP \f[I]arguments\f[R]: @@ -1077,10 +1089,6 @@ detail comparison against previous baseline, which shows the memory allocation activities at different callsites. (BOOLEAN, false) .IP \[bu] 2 -\f[CB]shutdown\f[R]: (Optional) Requests runtime to shutdown itself and -free the memory used by runtime. -(BOOLEAN, false) -.IP \[bu] 2 \f[CB]statistics\f[R]: (Optional) Prints tracker statistics for tuning purpose. (BOOLEAN, false) diff --git a/src/jdk.jcmd/share/man/jinfo.1 b/src/jdk.jcmd/share/man/jinfo.1 index 30de6c169247c81e4017bd129ad35ed3b713fca3..40cf79d2b6ecd26de8b6ae740d83615232e872c2 100644 --- a/src/jdk.jcmd/share/man/jinfo.1 +++ b/src/jdk.jcmd/share/man/jinfo.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JINFO" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JINFO" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jmap.1 b/src/jdk.jcmd/share/man/jmap.1 index 82e16d0ae2091bc1ec1fb5c3a5768fa0ac63a249..d29f8e84cfede203c73ef516b3039a26695ff1ba 100644 --- a/src/jdk.jcmd/share/man/jmap.1 +++ b/src/jdk.jcmd/share/man/jmap.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JMAP" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JMAP" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jps.1 b/src/jdk.jcmd/share/man/jps.1 index a6d10fe911afe0b289b8cd83a1cdd2ee11fb7be5..a442c4665fbcc4d2862ab936a4b96ab21bdf855d 100644 --- a/src/jdk.jcmd/share/man/jps.1 +++ b/src/jdk.jcmd/share/man/jps.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JPS" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JPS" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jstack.1 b/src/jdk.jcmd/share/man/jstack.1 index 302b9e5c24ab799cf56be7a33197231c2e159dc8..80674a67552c021ce8708acffe057695a61cf32b 100644 --- a/src/jdk.jcmd/share/man/jstack.1 +++ b/src/jdk.jcmd/share/man/jstack.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JSTACK" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JSTACK" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jstat.1 b/src/jdk.jcmd/share/man/jstat.1 index 9996833ece9c06c6c54683e19f33bd7a79a023b4..f235acf0c116a8a90751d74037a285d4fb0215a8 100644 --- a/src/jdk.jcmd/share/man/jstat.1 +++ b/src/jdk.jcmd/share/man/jstat.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JSTAT" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JSTAT" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jconsole/share/classes/sun/tools/jconsole/SummaryTab.java b/src/jdk.jconsole/share/classes/sun/tools/jconsole/SummaryTab.java index f70f1b1f35895391c2eb76424df5350ab21464cd..3168665cfc0f99185ea98516f69746ac40f47e9c 100644 --- a/src/jdk.jconsole/share/classes/sun/tools/jconsole/SummaryTab.java +++ b/src/jdk.jconsole/share/classes/sun/tools/jconsole/SummaryTab.java @@ -113,6 +113,7 @@ class SummaryTab extends Tab { StringBuilder buf; + @SuppressWarnings("deprecation") synchronized Result formatSummary() { Result result = new Result(); ProxyClient proxyClient = vmPanel.getProxyClient(); diff --git a/src/jdk.jconsole/share/man/jconsole.1 b/src/jdk.jconsole/share/man/jconsole.1 index f9e29abb1acd76d171aea8ed68d7a1249a3e5203..a32e6d0d447de86c12479365b274869b0866f68b 100644 --- a/src/jdk.jconsole/share/man/jconsole.1 +++ b/src/jdk.jconsole/share/man/jconsole.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JCONSOLE" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JCONSOLE" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleDotGraph.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleDotGraph.java index 21c4d67829c412fa83923b84d3587c58bac2248e..a23f25be9d2aeda5bfe8d92d8261cab937e298ed 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleDotGraph.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleDotGraph.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,6 @@ public class ModuleDotGraph { this(config, config.rootModules().stream() .map(Module::name) - .sorted() .collect(toMap(Function.identity(), mn -> config.resolve(Set.of(mn)))), apiOnly); } diff --git a/src/jdk.jdeps/share/man/javap.1 b/src/jdk.jdeps/share/man/javap.1 index 02fc77a0e158b23979597fa133341159ef1f8c1e..c63d7a3a82dfd27f6113a58bf6250d12cd65b2b4 100644 --- a/src/jdk.jdeps/share/man/javap.1 +++ b/src/jdk.jdeps/share/man/javap.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVAP" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JAVAP" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/man/jdeprscan.1 b/src/jdk.jdeps/share/man/jdeprscan.1 index 109e97890ef8db3aa2763d620b2fb31b666b42be..d168901b5bcddb4546f1699136689698961232ae 100644 --- a/src/jdk.jdeps/share/man/jdeprscan.1 +++ b/src/jdk.jdeps/share/man/jdeprscan.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JDEPRSCAN" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JDEPRSCAN" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/man/jdeps.1 b/src/jdk.jdeps/share/man/jdeps.1 index 110a314af733229080239c34e5908860ebbe0fdd..e8cb14c460afc4290d0681938bb1e1633d1668e9 100644 --- a/src/jdk.jdeps/share/man/jdeps.1 +++ b/src/jdk.jdeps/share/man/jdeps.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JDEPS" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JDEPS" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdi/share/classes/com/sun/jdi/ReferenceType.java b/src/jdk.jdi/share/classes/com/sun/jdi/ReferenceType.java index 2e84651fbd093107d8231489014b70a840ded252..043acc839f7d4b1a0b97897e26444f19cbbfcd8c 100644 --- a/src/jdk.jdi/share/classes/com/sun/jdi/ReferenceType.java +++ b/src/jdk.jdi/share/classes/com/sun/jdi/ReferenceType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -413,13 +413,13 @@ public interface ReferenceType /** * Returns a list containing each {@link Method} * declared or inherited by this type. Methods from superclasses - * or superinterfaces that that have been hidden or overridden + * or superinterfaces that have been hidden or overridden * are not included. * <p> * Note that despite this exclusion, multiple inherited methods * with the same signature can be present in the returned list, but * at most one can be a member of a {@link ClassType}. - * See JLS section 8.4.6 for details. + * See JLS section 8.4.8 for details. * <p> * For arrays ({@link ArrayType}) and primitive classes, the returned * list is always empty. @@ -454,7 +454,7 @@ public interface ReferenceType * find overloaded methods. * <p> * Overridden and hidden methods are not included. - * See JLS (8.4.6) for details. + * See JLS (8.4.8) for details. * <p> * For arrays ({@link ArrayType}) and primitive classes, the returned * list is always empty. @@ -478,7 +478,7 @@ public interface ReferenceType * <li><code>(IIII)Z</code> * </ul> * This method follows the inheritance rules specified - * in the JLS (8.4.6) to determine visibility. + * in the JLS (8.4.8) to determine visibility. * <p> * At most one method in the list is a concrete method and a * component of {@link ClassType}; any other methods in the list diff --git a/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java b/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java index 8b5957dc0d90a07e3911c515971a85730675cb4e..eee09ded39b0b27601711e78b9051b1ee42b6461 100644 --- a/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java +++ b/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,7 +97,7 @@ import com.sun.jdi.event.VMStartEvent; * {@code -agentlib:jdwp=transport=xxx,server=y} * </LI> * <LI> - * Target VM generates and outputs the tranport-specific address at which it will + * Target VM generates and outputs the transport-specific address at which it will * listen for a connection.</LI> * <LI> * Debugger is launched. Debugger selects a connector in the list @@ -158,7 +158,7 @@ import com.sun.jdi.event.VMStartEvent; * </LI> * <LI> * Later, an uncaught exception is thrown in the target VM. The target - * VM generates the tranport-specific address at which it will + * VM generates the transport-specific address at which it will * listen for a connection. * <LI>Target VM launches the debugger with the following items concatenated * together (separated by spaces) to form the command line: diff --git a/src/jdk.jdi/share/man/jdb.1 b/src/jdk.jdi/share/man/jdb.1 index dfac04e3e275051c942a886236d5d05b0e2fd21d..fb6f04f5c12065f14d92967fff5cc1f6240836e3 100644 --- a/src/jdk.jdi/share/man/jdb.1 +++ b/src/jdk.jdi/share/man/jdb.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JDB" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JDB" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/ArrayTypeImpl.c b/src/jdk.jdwp.agent/share/native/libjdwp/ArrayTypeImpl.c index c1631c2993827561caa50839896fdfbd53879afe..4176f0171d24228c7ee684a68ed099f6d49f18c9 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/ArrayTypeImpl.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/ArrayTypeImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -227,7 +227,7 @@ newInstance(PacketInputStream *in, PacketOutputStream *out) error = classSignature(arrayClass, &signature, NULL); if ( error != JVMTI_ERROR_NONE ) { outStream_setError(out, map2jdwpError(error)); - return JNI_FALSE; + return JNI_TRUE; } componentSignature = componentTypeSignature(signature); diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c b/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c index bc7ddb660bf048714b5aea061bb2e99e5c866c46..d55c517332bd93f0e8df04b6178c628260f014ea 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,6 +82,14 @@ newSeqNum(void) return gdata->nextSeqNum++; } +/* Returns true if this is a strong reference, meaning that either or both of + isPinAll and isCommonPin are true. */ +static jboolean +isStrong(RefNode* node) +{ + return node->isPinAll || node->isCommonPin; +} + /* Create a fresh RefNode structure, create a weak ref and tag the object */ static RefNode * createNode(JNIEnv *env, jobject ref) @@ -89,7 +97,7 @@ createNode(JNIEnv *env, jobject ref) RefNode *node; jobject strongOrWeakRef; jvmtiError error; - jboolean pin = gdata->pinAllCount != 0; + jboolean pinAll = gdata->pinAllCount != 0; /* Could allocate RefNode's in blocks, not sure it would help much */ node = (RefNode*)jvmtiAllocate((int)sizeof(RefNode)); @@ -97,7 +105,7 @@ createNode(JNIEnv *env, jobject ref) return NULL; } - if (pin) { + if (pinAll) { /* Create strong reference to make sure we have a reference */ strongOrWeakRef = JNI_FUNC_PTR(env,NewGlobalRef)(env, ref); } else { @@ -116,7 +124,7 @@ createNode(JNIEnv *env, jobject ref) error = JVMTI_FUNC_PTR(gdata->jvmti, SetTag) (gdata->jvmti, strongOrWeakRef, ptr_to_jlong(node)); if ( error != JVMTI_ERROR_NONE ) { - if (pin) { + if (pinAll) { JNI_FUNC_PTR(env,DeleteGlobalRef)(env, strongOrWeakRef); } else { JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, strongOrWeakRef); @@ -128,7 +136,8 @@ createNode(JNIEnv *env, jobject ref) /* Fill in RefNode */ node->ref = strongOrWeakRef; node->count = 1; - node->strongCount = pin ? 1 : 0; + node->isPinAll = pinAll; + node->isCommonPin = JNI_FALSE; node->seqNum = newSeqNum(); /* Count RefNode's created */ @@ -146,7 +155,7 @@ deleteNode(JNIEnv *env, RefNode *node) /* Clear tag */ (void)JVMTI_FUNC_PTR(gdata->jvmti,SetTag) (gdata->jvmti, node->ref, NULL_OBJECT_ID); - if (node->strongCount != 0) { + if (isStrong(node)) { JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref); } else { JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, node->ref); @@ -158,9 +167,9 @@ deleteNode(JNIEnv *env, RefNode *node) /* Change a RefNode to have a strong reference */ static jobject -strengthenNode(JNIEnv *env, RefNode *node) +strengthenNode(JNIEnv *env, RefNode *node, jboolean isPinAll) { - if (node->strongCount == 0) { + if (!isStrong(node)) { jobject strongRef; strongRef = JNI_FUNC_PTR(env,NewGlobalRef)(env, node->ref); @@ -176,20 +185,27 @@ strengthenNode(JNIEnv *env, RefNode *node) if (strongRef != NULL) { JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, node->ref); node->ref = strongRef; - node->strongCount = 1; + } else { + return NULL; } - return strongRef; + } + if (isPinAll) { + node->isPinAll = JNI_TRUE; } else { - node->strongCount++; - return node->ref; + node->isCommonPin = JNI_TRUE; } + return node->ref; } /* Change a RefNode to have a weak reference */ static jweak -weakenNode(JNIEnv *env, RefNode *node) +weakenNode(JNIEnv *env, RefNode *node, jboolean isUnpinAll) { - if (node->strongCount == 1) { + jboolean willStillBeStrong = (node->isPinAll && !isUnpinAll) || (node->isCommonPin && isUnpinAll); + + // If the node is strong, but the reason(s) for it being strong + // will no longer exist, then weaken it. + if (isStrong(node) && !willStillBeStrong) { jweak weakRef; weakRef = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, node->ref); @@ -200,16 +216,18 @@ weakenNode(JNIEnv *env, RefNode *node) if (weakRef != NULL) { JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref); - node->ref = weakRef; - node->strongCount = 0; + node->ref = weakRef; + } else { + return NULL; } - return weakRef; + } + + if (isUnpinAll) { + node->isPinAll = JNI_FALSE; } else { - if (node->strongCount > 0) { - node->strongCount--; - } - return node->ref; + node->isCommonPin = JNI_FALSE; } + return node->ref; } /* @@ -470,7 +488,7 @@ commonRef_idToRef(JNIEnv *env, jlong id) node = findNodeByID(env, id); if (node != NULL) { - if (node->strongCount != 0) { + if (isStrong(node)) { saveGlobalRef(env, node->ref, &ref); } else { jobject lref; @@ -522,7 +540,7 @@ commonRef_pin(jlong id) } else { jobject strongRef; - strongRef = strengthenNode(env, node); + strongRef = strengthenNode(env, node, JNI_FALSE /* isPinAll */); if (strongRef == NULL) { /* * Referent has been collected, clean up now. @@ -551,7 +569,7 @@ commonRef_unpin(jlong id) if (node != NULL) { jweak weakRef; - weakRef = weakenNode(env, node); + weakRef = weakenNode(env, node, JNI_FALSE /* isUnpinAll */); if (weakRef == NULL) { error = AGENT_ERROR_OUT_OF_MEMORY; } @@ -585,7 +603,7 @@ commonRef_pinAll() while (node != NULL) { jobject strongRef; - strongRef = strengthenNode(env, node); + strongRef = strengthenNode(env, node, JNI_TRUE /* isPinAll */); /* Has the object been collected? */ if (strongRef == NULL) { @@ -628,7 +646,7 @@ commonRef_unpinAll() for (node = gdata->objectsByID[i]; node != NULL; node = node->next) { jweak weakRef; - weakRef = weakenNode(env, node); + weakRef = weakenNode(env, node, JNI_TRUE /* isUnpinAll */); if (weakRef == NULL) { EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"NewWeakGlobalRef"); } @@ -676,8 +694,7 @@ commonRef_compact(void) prev = NULL; while (node != NULL) { /* Has the object been collected? */ - if ( (node->strongCount == 0) && - isSameObject(env, node->ref, NULL)) { + if (!isStrong(node) && isSameObject(env, node->ref, NULL)) { RefNode *freed; /* Detach from the ID list */ diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c b/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c index fdc7a0bc613aa07a05c1c9e9c842ebc85ccaa97b..2f6eb5f40a1ac20b2e8962f02b6e36e5dca0c954 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -232,6 +232,7 @@ fillInvokeRequest(JNIEnv *env, InvokeRequest *request, /* * Squirrel away the method signature */ + JDI_ASSERT_MSG(request->methodSignature == NULL, "Request methodSignature not null"); error = methodSignature(method, NULL, &request->methodSignature, NULL); if (error != JVMTI_ERROR_NONE) { return error; @@ -752,7 +753,9 @@ invoker_completeInvokeRequest(jthread thread) } id = request->id; exc = request->exception; + request->exception = NULL; returnValue = request->returnValue; + request->returnValue.l = NULL; /* Release return value and exception references, but delay the release * until after the return packet was sent. */ @@ -773,6 +776,10 @@ invoker_completeInvokeRequest(jthread thread) */ deleteGlobalArgumentRefs(env, request); + JDI_ASSERT_MSG(request->methodSignature != NULL, "methodSignature is NULL"); + jvmtiDeallocate(request->methodSignature); + request->methodSignature = NULL; + /* From now on, do not access the request structure anymore * for this request id, because once we give up the invokerLock it may * be immediately reused by a new invoke request. @@ -790,23 +797,20 @@ invoker_completeInvokeRequest(jthread thread) (void)outStream_writeValue(env, &out, tag, returnValue); (void)outStream_writeObjectTag(env, &out, exc); (void)outStream_writeObjectRef(env, &out, exc); + /* + * Delete potentially saved global references for return value + * and exception. This must be done before sending the reply or + * these objects will briefly be viewable by the debugger as live + * when they shouldn't be. + */ + if (mustReleaseReturnValue && returnValue.l != NULL) { + tossGlobalRef(env, &returnValue.l); + } + if (exc != NULL) { + tossGlobalRef(env, &exc); + } outStream_sendReply(&out); } - - /* - * Delete potentially saved global references of return value - * and exception - */ - eventHandler_lock(); // for proper lock order - debugMonitorEnter(invokerLock); - if (mustReleaseReturnValue && returnValue.l != NULL) { - tossGlobalRef(env, &returnValue.l); - } - if (exc != NULL) { - tossGlobalRef(env, &exc); - } - debugMonitorExit(invokerLock); - eventHandler_unlock(); } jboolean diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.h b/src/jdk.jdwp.agent/share/native/libjdwp/util.h index 134bf03db7aae089a6f6ef196df31ce1b8e378d1..0619648d9579960ba430950ce8ce474dc038df7b 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/util.h +++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,8 @@ typedef struct RefNode { jobject ref; /* could be strong or weak */ struct RefNode *next; /* next RefNode* in bucket chain */ jint count; /* count of references */ - unsigned strongCount; /* count of strong reference */ + jboolean isPinAll; /* true if this is a strong reference due to a commonRef_pinAll() */ + jboolean isCommonPin; /* true if this is a strong reference due to a commonRef_pin() */ } RefNode; /* Value of a NULL ID */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/EventType.java b/src/jdk.jfr/share/classes/jdk/jfr/EventType.java index 27bb9825abd6dfb8070b64e61597472e1feed478..46145ef2e8b60d370cf942f332f6dbb541a0d264 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/EventType.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/EventType.java @@ -241,4 +241,9 @@ public final class EventType { PlatformEventType getPlatformEventType() { return platformEventType; } + + // package private + boolean isVisible() { + return platformEventType.isVisible(); + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java index b7f558a17cbe60cf31a6d41bb94165aee854cce6..5e2bac1ba74e22589c6f16dc33629bcc0a314108 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java @@ -192,7 +192,6 @@ public final class FlightRecorder { Logger.log(JFR, DEBUG, "globalbuffersize: " + Options.getGlobalBufferSize()+ " bytes"); Logger.log(JFR, DEBUG, "globalbuffercount: " + Options.getGlobalBufferCount()); Logger.log(JFR, DEBUG, "dumppath: " + Options.getDumpPath()); - Logger.log(JFR, DEBUG, "samplethreads: " + Options.getSampleThreads()); Logger.log(JFR, DEBUG, "stackdepth: " + Options.getStackDepth()); Logger.log(JFR, DEBUG, "threadbuffersize: " + Options.getThreadBufferSize()); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorderPermission.java b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorderPermission.java index 789fa18fdb3008e82fdc1082b569d711ff1a0700..7b89ddf02c8b547bea2c8f75fc1a1fe850bdb7fc 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorderPermission.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorderPermission.java @@ -203,6 +203,11 @@ public final class FlightRecorderPermission extends java.security.BasicPermissio public EventSettings newEventSettings(EventSettingsModifier esm) { return new EventSettings.DelegatedEventSettings(esm); } + + @Override + public boolean isVisible(EventType t) { + return t.isVisible(); + } } /** diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java index 71ef9cebc258b26f2b2088ae4f1bb9c2bc7c80ea..1dd4b3030133e94e152751b29ba6baf4235727b3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java @@ -424,25 +424,6 @@ public final class Recording implements Closeable { internal.setMaxSize(maxSize); } - /** - * Determines how often events are made available for streaming. - * - * @param interval the interval at which events are made available for streaming. - * - * @throws IllegalArgumentException if {@code interval} is negative - * - * @throws IllegalStateException if the recording is in the {@code CLOSED} state - * - * @since 14 - */ - /*package private*/ void setFlushInterval(Duration interval) { - Objects.requireNonNull(interval); - if (interval.isNegative()) { - throw new IllegalArgumentException("Stream interval can't be negative"); - } - internal.setFlushInterval(interval); - } - /** * Returns how often events are made available for streaming purposes. * diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java index 7a9cc510985b353bf7f54f734c55aa02745b0e8d..b0ffe88b9c71edcb65bf151f25f68a8db1b249a2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,6 +107,9 @@ public final class RecordedEvent extends RecordedObject { * @return the duration in nanoseconds, not {@code null} */ public Duration getDuration() { + if(startTimeTicks == endTimeTicks) { + return Duration.ZERO; + } return Duration.ofNanos(getEndTimeNanos() - getStartTimeNanos()); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java index c366934f23b8d30c19edd0cc3156d9b392de132f..d9def94ff8ab70259f83dcd7c21e39497773b37f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -150,16 +150,7 @@ public class RecordedObject { JdkJfrConsumer.setAccess(access); } - private static final class UnsignedValue { - private final Object o; - - UnsignedValue(Object o) { - this.o = o; - } - - Object value() { - return o; - } + private static final record UnsignedValue(Object value) { } final Object[] objects; @@ -827,8 +818,11 @@ public class RecordedObject { throw newIllegalArgumentException(name, "java.time.Duration"); } - private Duration getDuration(long timespan, String name) throws InternalError { + private Duration getDuration(long timespan, String name) { ValueDescriptor v = getValueDescriptor(objectContext.fields, name, null); + if (timespan == 0) { + return Duration.ZERO; + } if (timespan == Long.MIN_VALUE) { return Duration.ofSeconds(Long.MIN_VALUE, 0); } @@ -997,7 +991,7 @@ public class RecordedObject { if (instant.equals(Instant.MIN)) { return OffsetDateTime.MIN; } - return OffsetDateTime.ofInstant(getInstant(name), objectContext.getZoneOffset()); + return OffsetDateTime.ofInstant(instant, objectContext.getZoneOffset()); } private static IllegalArgumentException newIllegalArgumentException(String name, String typeName) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java index 5ebe57bcce4876f4c2a28dc4c67b81f189374669..3b8163e717b7d60824a7847e29d25bae897f88f0 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java @@ -41,6 +41,7 @@ import jdk.jfr.internal.Type; import jdk.jfr.internal.consumer.ChunkHeader; import jdk.jfr.internal.consumer.ChunkParser; import jdk.jfr.internal.consumer.FileAccess; +import jdk.jfr.internal.consumer.ParserState; import jdk.jfr.internal.consumer.RecordingInput; /** @@ -61,6 +62,7 @@ import jdk.jfr.internal.consumer.RecordingInput; */ public final class RecordingFile implements Closeable { + private final ParserState parserState = new ParserState(); private boolean isLastEventInChunk; private final File file; private RecordingInput input; @@ -247,7 +249,7 @@ public final class RecordingFile implements Closeable { private void findNext() throws IOException { while (nextEvent == null) { if (chunkParser == null) { - chunkParser = new ChunkParser(input); + chunkParser = new ChunkParser(input, parserState); } else if (!chunkParser.isLastChunk()) { chunkParser = chunkParser.nextChunkParser(); } else { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java index 703f0d1271c73c7e48df79c0821f2157d07d9990..a3a53c6a7e92318bd31c85b5fcb65811dbd9b750 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public final class FileReadEvent extends AbstractJDKEvent { // EventHandler::write(..., String, long, boolean) @Label("Path") - @Description("Full path of the file") + @Description("Full path of the file, or N/A if a file descriptor was used to create the stream, for example System.in") public String path; @Label("Bytes Read") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java index 7554fee09c29c487f190b3e43e9566e9819c1855..01ffc5dfa48045750743df781613a3bd3f4c113f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public final class FileWriteEvent extends AbstractJDKEvent { // EventHandler::write(..., String, long) @Label("Path") - @Description("Full path of the file") + @Description("Full path of the file, or N/A if a file descriptor was used to create the stream, for example System.out and System.err") public String path; @Label("Bytes Written") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunkInputStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunkInputStream.java index a5e1d01783f2ae988db772f0eee6b4965ea3a3ed..5b192443980606cf7a2c70e110fa9f11fe29e16b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunkInputStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunkInputStream.java @@ -112,7 +112,7 @@ final class ChunkInputStream extends InputStream { } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { super.finalize(); close(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunksChannel.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunksChannel.java index 1139536c93876f8fa49ed46a625e2b07d057b49a..b606105d29e5506006508b0a6ce05b9712874795 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunksChannel.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/ChunksChannel.java @@ -137,7 +137,7 @@ final class ChunksChannel implements ReadableByteChannel { } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { super.finalize(); close(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java index 0887d1ce0ed9c2c04c677e0dba49f07d51fe0115..27281cd5f58b8bfee4163f3ffd95380e988a6977 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,7 @@ public final class Control { public String getValue() { if (context == null) { // VM events requires no access control context - return getValue(); + return delegate.getValue(); } else { return AccessController.doPrivileged(new PrivilegedAction<String>() { @Override diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index 6a89ce02d1e00ba0d21ac72d19b05113306b8a95..b0fdce2d6c92114d149835e58cd17e14598046af 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -292,7 +292,7 @@ public final class EventControl { } ActiveSettingEvent event = ActiveSettingEvent.EVENT.get(); for (NamedControl nc : namedControls) { - if (Utils.isSettingVisible(nc.control, type.hasEventHook())) { + if (Utils.isSettingVisible(nc.control, type.hasEventHook()) && type.isVisible()) { String value = nc.control.getLastValue(); if (value == null) { value = nc.control.getDefaultValue(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java index b5aff49cbe070aa3afb8a5fe5815e3dc50c8e3de..0739a0bfacbf2093bd8130a72f503c14a1b98b1b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java @@ -301,15 +301,6 @@ public final class JVM { */ public native void setForceInstrumentation(boolean force); - /** - * Turn on/off thread sampling. - * - * @param sampleThreads true if threads should be sampled, false otherwise. - * - * @throws IllegalStateException if state can't be changed. - */ - public native void setSampleThreads(boolean sampleThreads) throws IllegalStateException; - /** * Turn on/off compressed integers. * @@ -473,13 +464,26 @@ public final class JVM { public native void flush(); /** - * Sets the location of the disk repository, to be used at an emergency - * dump. + * Sets the location of the disk repository. * * @param dirText */ public native void setRepositoryLocation(String dirText); + /** + * Sets the path to emergency dump. + * + * @param dumpPathText + */ + public native void setDumpPath(String dumpPathText); + + /** + * Gets the path to emergency dump. + * + * @return The path to emergency dump. + */ + public native String getDumpPath(); + /** * Access to VM termination support. * diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java index 2e4e4c95a3f30dff520c97cd8a1f4bfbc9bc3d53..be1dab301b785ad0f4b161fce1437942e328d06c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java @@ -125,14 +125,22 @@ final class JVMUpcalls { } } + /** + * Called by the JVM to ensure metadata for internal events/types become public. + * + * Must be called after metadata repository has been initialized (JFR created). + * + */ + static void unhideInternalTypes() { + MetadataRepository.unhideInternalTypes(); + } + /** * Called by the JVM to create the recorder thread. * - * @param systemThreadGroup - * the system thread group + * @param systemThreadGroup the system thread group * - * @param contextClassLoader - * the context class loader. + * @param contextClassLoader the context class loader. * * @return a new thread */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java index ef9c22556f2410536044376306956e7143d89dfc..552b070527e84334a8caffa8cfa6de8f11545c6e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java @@ -53,7 +53,8 @@ public final class MetadataLoader { // Caching to reduce allocation pressure and heap usage private final AnnotationElement RELATIONAL = new AnnotationElement(Relational.class); - private final AnnotationElement ENABLED = new AnnotationElement(Enabled.class, false); + private final AnnotationElement ENABLED = new AnnotationElement(Enabled.class, true); + private final AnnotationElement DISABLED = new AnnotationElement(Enabled.class, false); private final AnnotationElement THRESHOLD = new AnnotationElement(Threshold.class, "0 ns"); private final AnnotationElement STACK_TRACE = new AnnotationElement(StackTrace.class, true); private final AnnotationElement TRANSITION_TO = new AnnotationElement(TransitionTo.class); @@ -82,6 +83,7 @@ public final class MetadataLoader { private final boolean isEvent; private final boolean isRelation; private final boolean experimental; + private final boolean internal; private final long id; public TypeElement(DataInputStream dis) throws IOException { @@ -101,6 +103,7 @@ public final class MetadataLoader { cutoff = dis.readBoolean(); throttle = dis.readBoolean(); experimental = dis.readBoolean(); + internal = dis.readBoolean(); id = dis.readLong(); isEvent = dis.readBoolean(); isRelation = dis.readBoolean(); @@ -315,7 +318,11 @@ public final class MetadataLoader { } Type type; if (t.isEvent) { - aes.add(ENABLED); + if (t.internal) { + aes.add(ENABLED); + } else { + aes.add(DISABLED); + } type = new PlatformEventType(t.name, t.id, false, true); } else { type = knownTypeMap.get(t.name); @@ -328,6 +335,15 @@ public final class MetadataLoader { } } } + if (t.internal) { + type.setInternal(true); + // Internal types are hidden by default + type.setVisible(false); + // Internal events are enabled by default + if (type instanceof PlatformEventType pe) { + pe.setEnabled(true); + } + } type.setAnnotations(aes); typeMap.put(t.name, type); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java index 0c798b8b28eca3f1439661ede8f5be5e4d035de1..f76fdc62a74c5f671479ee30e8b4feca375e897d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import java.io.IOException; import java.time.Instant; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -71,7 +72,7 @@ public final class MetadataRepository { private void initializeJVMEventTypes() { List<RequestHook> requestHooks = new ArrayList<>(); - for (Type type : typeLibrary.getTypes()) { + for (Type type : new ArrayList<>(typeLibrary.getTypes())) { if (type instanceof PlatformEventType pEventType) { EventType eventType = PrivateAccess.getInstance().newEventType(pEventType); pEventType.setHasDuration(eventType.getAnnotation(Threshold.class) != null); @@ -106,7 +107,11 @@ public final class MetadataRepository { eventTypes.add(h.getEventType()); } } - eventTypes.addAll(nativeEventTypes); + for (EventType t : nativeEventTypes) { + if (PrivateAccess.getInstance().isVisible(t)) { + eventTypes.add(t); + } + } return eventTypes; } @@ -243,7 +248,13 @@ public final class MetadataRepository { ByteArrayOutputStream baos = new ByteArrayOutputStream(40000); DataOutputStream daos = new DataOutputStream(baos); try { - List<Type> types = typeLibrary.getTypes(); + List<Type> types = typeLibrary.getVisibleTypes(); + if (Logger.shouldLog(LogTag.JFR_METADATA, LogLevel.DEBUG)) { + Collections.sort(types,Comparator.comparing(Type::getName)); + for (Type t: types) { + Logger.log(LogTag.JFR_METADATA, LogLevel.INFO, "Serialized type: " + t.getName() + " id=" + t.getId()); + } + } Collections.sort(types); MetadataDescriptor.write(types, daos); daos.flush(); @@ -269,9 +280,12 @@ public final class MetadataRepository { if (staleMetadata) { storeDescriptorInJVM(); } - awaitUniqueTimestamp(); jvm.setOutput(filename); - long nanos = jvm.getChunkStartNanos(); + // Each chunk needs a unique start timestamp and + // if the clock resolution is low, two chunks may + // get the same timestamp. Utils.getChunkStartNanos() + // ensures the timestamp is unique for the next chunk + long chunkStart = Utils.getChunkStartNanos(); if (filename != null) { RepositoryFiles.notifyNewFile(); } @@ -282,29 +296,7 @@ public final class MetadataRepository { } unregistered = false; } - return Utils.epochNanosToInstant(nanos); - } - - // Each chunk needs a unique start timestamp and - // if the clock resolution is low, two chunks may - // get the same timestamp. - private void awaitUniqueTimestamp() { - if (outputChange == null) { - outputChange = Instant.now(); - return; - } - while (true) { - Instant time = Instant.now(); - if (!time.equals(outputChange)) { - outputChange = time; - return; - } - try { - Thread.sleep(0, 100); - } catch (InterruptedException iex) { - // ignore - } - } + return Utils.epochNanosToInstant(chunkStart); } private void unregisterUnloaded() { @@ -349,4 +341,20 @@ public final class MetadataRepository { jvm.flush(); } + static void unhideInternalTypes() { + for (Type t : TypeLibrary.getInstance().getTypes()) { + if (t.isInternal()) { + t.setVisible(true); + Logger.log(LogTag.JFR_METADATA, LogLevel.DEBUG, "Unhiding internal type " + t.getName()); + } + } + // Singleton should have been initialized here. + // It's not possible to call MetadataRepository().getInstance(), + // because it will deadlock with Java thread calling flush() or setOutput(); + instance.storeDescriptorInJVM(); + } + + public synchronized List<Type> getVisibleTypes() { + return typeLibrary.getVisibleTypes(); + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Options.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Options.java index 4d430bebba2c4e3c92b265eaf03182a01e6d1bf6..efd3ce6480799d84486b6ec38dce7efcfcee1a3f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Options.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Options.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,16 @@ package jdk.jfr.internal; +import java.io.IOException; + +import jdk.jfr.internal.LogLevel; +import jdk.jfr.internal.LogTag; +import jdk.jfr.internal.Logger; import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.internal.misc.Unsafe; +import static java.nio.file.LinkOption.*; + /** * Options that control Flight Recorder. * @@ -46,18 +53,15 @@ public final class Options { private static final long DEFAULT_MEMORY_SIZE = DEFAULT_GLOBAL_BUFFER_COUNT * DEFAULT_GLOBAL_BUFFER_SIZE; private static long DEFAULT_THREAD_BUFFER_SIZE; private static final int DEFAULT_STACK_DEPTH = 64; - private static final boolean DEFAULT_SAMPLE_THREADS = true; private static final long DEFAULT_MAX_CHUNK_SIZE = 12 * 1024 * 1024; - private static final SafePath DEFAULT_DUMP_PATH = SecuritySupport.USER_HOME; + private static final SafePath DEFAULT_DUMP_PATH = null; private static long memorySize; private static long globalBufferSize; private static long globalBufferCount; private static long threadBufferSize; private static int stackDepth; - private static boolean sampleThreads; private static long maxChunkSize; - private static SafePath dumpPath; static { final long pageSize = Unsafe.getUnsafe().pageSize(); @@ -113,12 +117,19 @@ public final class Options { globalBufferSize = globalBufsize; } - public static synchronized void setDumpPath(SafePath path) { - dumpPath = path; + public static synchronized void setDumpPath(SafePath path) throws IOException { + if (path != null) { + if (SecuritySupport.isWritable(path)) { + path = SecuritySupport.toRealPath(path, NOFOLLOW_LINKS); + } else { + throw new IOException("Cannot write JFR emergency dump to " + path.toString()); + } + } + jvm.setDumpPath(path == null ? null : path.toString()); } public static synchronized SafePath getDumpPath() { - return dumpPath; + return new SafePath(jvm.getDumpPath()); } public static synchronized void setStackDepth(Integer stackTraceDepth) { @@ -130,22 +141,16 @@ public final class Options { return stackDepth; } - public static synchronized void setSampleThreads(Boolean sample) { - jvm.setSampleThreads(sample); - sampleThreads = sample; - } - - public static synchronized boolean getSampleThreads() { - return sampleThreads; - } - private static synchronized void reset() { setMaxChunkSize(DEFAULT_MAX_CHUNK_SIZE); setMemorySize(DEFAULT_MEMORY_SIZE); setGlobalBufferSize(DEFAULT_GLOBAL_BUFFER_SIZE); setGlobalBufferCount(DEFAULT_GLOBAL_BUFFER_COUNT); - setDumpPath(DEFAULT_DUMP_PATH); - setSampleThreads(DEFAULT_SAMPLE_THREADS); + try { + setDumpPath(DEFAULT_DUMP_PATH); + } catch (IOException e) { + // Ignore (depends on default value in JVM: it would be NULL) + } setStackDepth(DEFAULT_STACK_DEPTH); setThreadBufferSize(DEFAULT_THREAD_BUFFER_SIZE); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java index 63a4840618faaa629b130d7baed90f77c5979be9..c0c62c64bb0c4dd2e48baa8ac8bfffd4590beaee 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java @@ -248,7 +248,7 @@ public final class PlatformRecorder { } currentChunk = newChunk; jvm.beginRecording(); - startNanos = jvm.getChunkStartNanos(); + startNanos = Utils.getChunkStartNanos(); startTime = Utils.epochNanosToInstant(startNanos); if (currentChunk != null) { currentChunk.setStartTime(startTime); @@ -269,7 +269,7 @@ public final class PlatformRecorder { startTime = MetadataRepository.getInstance().setOutput(p); newChunk.setStartTime(startTime); } - startNanos = jvm.getChunkStartNanos(); + startNanos = Utils.getChunkStartNanos(); startTime = Utils.epochNanosToInstant(startNanos); recording.setStartTime(startTime); recording.setState(RecordingState.RUNNING); @@ -316,7 +316,7 @@ public final class PlatformRecorder { } } OldObjectSample.emit(recording); - recording.setFinalStartnanos(jvm.getChunkStartNanos()); + recording.setFinalStartnanos(Utils.getChunkStartNanos()); if (endPhysical) { RequestEngine.doChunkEnd(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PrivateAccess.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PrivateAccess.java index def05bba4c985843d3ff9e1dcc545e99605e2e08..09d53b4b5620b374376fed7c658956ac3deb30c6 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PrivateAccess.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PrivateAccess.java @@ -103,4 +103,6 @@ public abstract class PrivateAccess { public abstract AccessControlContext getContext(SettingControl sc); public abstract EventSettings newEventSettings(EventSettingsModifier esm); + + public abstract boolean isVisible(EventType t); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java index af5ff3e08e4e1a3bce09c5bfe43c4b8709da4e49..8cb8bd85c3791ebd9e7686b6c6151047607d4db2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java @@ -134,7 +134,7 @@ final class RepositoryChunk { } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { boolean destroy = false; synchronized (this) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java index d761eb98c58c548021ade6d1dfdd05613304b459..ee30821dcf83b4f660af48f777a03e7d3e976b83 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import java.io.RandomAccessFile; import java.io.Reader; import java.lang.invoke.MethodHandles; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ReflectPermission; import java.nio.channels.FileChannel; @@ -41,6 +40,7 @@ import java.nio.channels.ReadableByteChannel; import java.nio.file.DirectoryStream; import java.nio.file.FileVisitResult; import java.nio.file.Files; +import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; @@ -77,7 +77,6 @@ public final class SecuritySupport { private static final Module JFR_MODULE = Event.class.getModule(); public static final SafePath JFC_DIRECTORY = getPathInProperty("java.home", "lib/jfr"); public static final FileAccess PRIVILEGED = new Privileged(); - static final SafePath USER_HOME = getPathInProperty("user.home", null); static final SafePath JAVA_IO_TMPDIR = getPathInProperty("java.io.tmpdir", null); static { @@ -150,7 +149,7 @@ public final class SecuritySupport { } /** - * Path created by the default file provider,and not + * Path created by the default file provider, and not * a malicious provider. * */ @@ -267,14 +266,11 @@ public final class SecuritySupport { public static List<SafePath> getPredefinedJFCFiles() { List<SafePath> list = new ArrayList<>(); - try { - Iterator<Path> pathIterator = doPrivilegedIOWithReturn(() -> { - return Files.newDirectoryStream(JFC_DIRECTORY.toPath(), "*").iterator(); - }); - while (pathIterator.hasNext()) { - Path path = pathIterator.next(); - if (path.toString().endsWith(".jfc")) { - list.add(new SafePath(path)); + try (var ds = doPrivilegedIOWithReturn(() -> Files.newDirectoryStream(JFC_DIRECTORY.toPath(), "*.jfc"))) { + for (Path path : ds) { + SafePath s = new SafePath(path); + if (!SecuritySupport.isDirectory(s)) { + list.add(s); } } } catch (IOException ioe) { @@ -357,16 +353,12 @@ public final class SecuritySupport { doPrivileged(() -> thread.setUncaughtExceptionHandler(eh), new RuntimePermission("modifyThread")); } - static void moveReplace(SafePath from, SafePath to) throws IOException { - doPrivilegedIOWithReturn(() -> Files.move(from.toPath(), to.toPath())); - } - static void clearDirectory(SafePath safePath) throws IOException { doPriviligedIO(() -> Files.walkFileTree(safePath.toPath(), new DirectoryCleaner())); } - static SafePath toRealPath(SafePath safePath) throws IOException { - return new SafePath(doPrivilegedIOWithReturn(() -> safePath.toPath().toRealPath())); + static SafePath toRealPath(SafePath safePath, LinkOption... options) throws IOException { + return new SafePath(doPrivilegedIOWithReturn(() -> safePath.toPath().toRealPath(options))); } static boolean existDirectory(SafePath directory) throws IOException { @@ -407,10 +399,6 @@ public final class SecuritySupport { return doPrivilegedIOWithReturn(() -> Files.isWritable(safePath.toPath())); } - static void deleteOnExit(SafePath safePath) { - doPrivileged(() -> safePath.toPath().toFile().deleteOnExit()); - } - static ReadableByteChannel newFileChannelToRead(SafePath safePath) throws IOException { return doPrivilegedIOWithReturn(() -> FileChannel.open(safePath.toPath(), StandardOpenOption.READ)); } @@ -423,10 +411,6 @@ public final class SecuritySupport { return doPrivilegedIOWithReturn(() -> Files.newBufferedReader(safePath.toPath())); } - static void touch(SafePath path) throws IOException { - doPriviligedIO(() -> new RandomAccessFile(path.toPath().toFile(), "rw").close()); - } - static void setAccessible(Method method) { doPrivileged(() -> method.setAccessible(true), new ReflectPermission("suppressAccessChecks")); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java index 9b6891bcdec515acb376d0bb14a6e0c08b61af4e..27938ed023c30678d5dd9a19449827481082e08e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java @@ -89,6 +89,8 @@ public class Type implements Comparable<Type> { private Boolean simpleType; // calculated lazy private boolean remove = true; private long id; + private boolean visible = true; + private boolean internal; /** * Creates a type @@ -337,4 +339,20 @@ public class Type implements Comparable<Type> { public void setId(long id) { this.id = id; } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public boolean isVisible() { + return visible; + } + + public void setInternal(boolean internal) { + this.internal = internal; + } + + public boolean isInternal() { + return internal; + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java index e57172b867a38335b268a275ca76e3f8c8a80029..1555bcc2aac660500288ecea18429f32defad535 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java @@ -119,8 +119,19 @@ public final class TypeLibrary { } } - public List<Type> getTypes() { - return new ArrayList<>(types.values()); + public Collection<Type> getTypes() { + return types.values(); + } + + // Returned list should be mutable (for in-place sorting) + public List<Type> getVisibleTypes() { + List<Type> visible = new ArrayList<>(types.size()); + types.values().forEach(t -> { + if (t.isVisible()) { + visible.add(t); + } + }); + return visible; } public static Type createAnnotationType(Class<? extends Annotation> a) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java index 38179ba891b75553fad3987d42d9fd23c68bff93..c0324d2d7f6d38fb8b29e55900ab55b04bcda3bf 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,6 +97,7 @@ public final class Utils { * The possible data race is benign and is worth of not introducing any contention here. */ private static Metrics[] metrics; + private static Instant lastTimestamp; public static void checkAccessFlightRecorder() throws SecurityException { @SuppressWarnings("removal") @@ -866,4 +867,30 @@ public final class Utils { throw new IllegalArgumentException("'" + name + "' is not a valid Java identifier"); } } + + public static long getChunkStartNanos() { + long nanos = JVM.getJVM().getChunkStartNanos(); + // JVM::getChunkStartNanos() may return a bumped timestamp, +1 ns or +2 ns. + // Spin here to give Instant.now() a chance to catch up. + awaitUniqueTimestamp(); + return nanos; + } + + private static void awaitUniqueTimestamp() { + if (lastTimestamp == null) { + lastTimestamp = Instant.now(); // lazy initialization + } + while (true) { + Instant time = Instant.now(); + if (!time.equals(lastTimestamp)) { + lastTimestamp = time; + return; + } + try { + Thread.sleep(0, 100); + } catch (InterruptedException iex) { + // ignore + } + } + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java index 4323e0cfeae3c2323a47859e9f41f207eb88255b..3feb350eb25a7102b8e5d9831fcb52bc28037685 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java @@ -65,7 +65,7 @@ public abstract class AbstractEventStream implements EventStream { private volatile Thread thread; private Dispatcher dispatcher; - private volatile boolean closed; + protected final ParserState parserState = new ParserState(); private boolean daemon = false; @@ -215,12 +215,12 @@ public abstract class AbstractEventStream implements EventStream { protected abstract void process() throws IOException; - protected final void setClosed(boolean closed) { - this.closed = closed; + protected final void closeParser() { + parserState.close(); } protected final boolean isClosed() { - return closed; + return parserState.isClosed(); } public final void startAsync(long startNanos) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java index 4027f447cf4caba8867b0d69c8f1a54cdc573bbc..95aa47a34bbcf7ad5157d0f5a1b5795c7adbbba3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java @@ -163,14 +163,6 @@ public final class ChunkHeader { } } - public boolean readHeader(byte[] bytes, int count) throws IOException { - input.position(absoluteChunkStart); - for (int i = 0; i< count; i++) { - bytes[i] = input.readPhysicalByte(); - } - return bytes[(int)FILE_STATE_POSITION] != UPDATING_CHUNK_HEADER; - } - public void awaitFinished() throws IOException { if (finished) { return; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkParser.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkParser.java index afa868f85b6821ef47bc57c09cd3431cc27f6d66..d698b3c52585fd381c897df63e9d8ea91d962074 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkParser.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkParser.java @@ -97,7 +97,7 @@ public final class ChunkParser { private final RecordingInput input; private final ChunkHeader chunkHeader; private final TimeConverter timeConverter; - + private final ParserState parserState; private final LongMap<ConstantLookup> constantLookups; private LongMap<Type> typeMap; @@ -105,24 +105,24 @@ public final class ChunkParser { private boolean chunkFinished; private ParserConfiguration configuration; - private volatile boolean closed; private MetadataDescriptor previousMetadata; private MetadataDescriptor metadata; private boolean staleMetadata = true; - public ChunkParser(RecordingInput input) throws IOException { - this(input, new ParserConfiguration()); + public ChunkParser(RecordingInput input, ParserState ps) throws IOException { + this(input, new ParserConfiguration(), ps); } - ChunkParser(RecordingInput input, ParserConfiguration pc) throws IOException { - this(new ChunkHeader(input), null, pc); + ChunkParser(RecordingInput input, ParserConfiguration pc, ParserState ps) throws IOException { + this(new ChunkHeader(input), null, pc, ps); } - private ChunkParser(ChunkParser previous) throws IOException { - this(new ChunkHeader(previous.input), previous, new ParserConfiguration()); + private ChunkParser(ChunkParser previous, ParserState ps) throws IOException { + this(new ChunkHeader(previous.input), previous, new ParserConfiguration(), ps); } - private ChunkParser(ChunkHeader header, ChunkParser previous, ParserConfiguration pc) throws IOException { + private ChunkParser(ChunkHeader header, ChunkParser previous, ParserConfiguration pc, ParserState ps) throws IOException { + this.parserState = ps; this.configuration = pc; this.input = header.getInput(); this.chunkHeader = header; @@ -155,7 +155,7 @@ public final class ChunkParser { } public ChunkParser nextChunkParser() throws IOException { - return new ChunkParser(chunkHeader.nextHeader(), this, configuration); + return new ChunkParser(chunkHeader.nextHeader(), this, configuration, parserState); } private void updateConfiguration() { @@ -280,7 +280,7 @@ public final class ChunkParser { Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Waiting for more data (streaming). Read so far: " + chunkHeader.getChunkSize() + " bytes"); } while (true) { - if (closed) { + if (parserState.isClosed()) { return true; } if (chunkHeader.getLastNanos() > filterEnd) { @@ -437,7 +437,7 @@ public final class ChunkParser { } ChunkParser newChunkParser() throws IOException { - return new ChunkParser(this); + return new ChunkParser(this, parserState); } public boolean isChunkFinished() { @@ -457,7 +457,7 @@ public final class ChunkParser { } public void close() { - this.closed = true; + parserState.close(); try { input.close(); } catch(IOException e) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/Dispatcher.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/Dispatcher.java index 721d5b190fc9cbbc4a6e4e5d8b1a2d7510111ed8..e8a565deb5d0ebdea99e993b7fff15bd79f28149 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/Dispatcher.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/Dispatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -160,6 +160,7 @@ final class Dispatcher { dispatcherLookup.put(type.getId(), dispatchers); } cacheDispatchers = dispatchers; + cacheEventType = type; } // Expected behavior if exception occurs in onEvent: // diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java index 28db3b68f3fec54ebc1910f4e9f4f6a60e505bd5..37fea4b9439980a74113e3af0de0a511cfcdcc90 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ package jdk.jfr.internal.consumer; import java.io.IOException; import java.nio.file.Path; import java.security.AccessControlContext; -import java.time.Duration; import java.time.Instant; import java.util.Arrays; import java.util.Comparator; @@ -49,7 +48,7 @@ import jdk.jfr.internal.consumer.ChunkParser.ParserConfiguration; * with chunk files. * */ -public class EventDirectoryStream extends AbstractEventStream { +public final class EventDirectoryStream extends AbstractEventStream { private static final Comparator<? super RecordedEvent> EVENT_COMPARATOR = JdkJfrConsumer.instance().eventComparator(); @@ -60,8 +59,6 @@ public class EventDirectoryStream extends AbstractEventStream { private long currentChunkStartNanos; private RecordedEvent[] sortedCache; private int threadExclusionLevel = 0; - protected volatile long maxSize; - protected volatile Duration maxAge; private volatile Consumer<Long> onCompleteHandler; @@ -83,7 +80,7 @@ public class EventDirectoryStream extends AbstractEventStream { @Override public void close() { - setClosed(true); + closeParser(); dispatcher().runCloseActions(); repositoryFiles.close(); if (currentParser != null) { @@ -148,7 +145,7 @@ public class EventDirectoryStream extends AbstractEventStream { } currentChunkStartNanos = repositoryFiles.getTimestamp(path); try (RecordingInput input = new RecordingInput(path.toFile(), fileAccess)) { - currentParser = new ChunkParser(input, disp.parserConfiguration); + currentParser = new ChunkParser(input, disp.parserConfiguration, parserState); long segmentStart = currentParser.getStartNanos() + currentParser.getChunkDuration(); long filterStart = validStartTime ? disp.startNanos : segmentStart; long filterEnd = disp.endTime != null ? disp.endNanos : Long.MAX_VALUE; @@ -259,12 +256,4 @@ public class EventDirectoryStream extends AbstractEventStream { c.dispatch(e); } } - - public void setMaxSize(long maxSize) { - this.maxSize = maxSize; - } - - public void setMaxAge(Duration maxAge) { - this.maxAge = maxAge; - } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java index c4595ab639d599d1bbc4a0c8137211966bde4dbf..89402f623086925a5a0473b10d3fcae1876efa62 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java @@ -64,7 +64,7 @@ public final class EventFileStream extends AbstractEventStream { @Override public void close() { - setClosed(true); + closeParser(); dispatcher().runCloseActions(); try { input.close(); @@ -85,7 +85,7 @@ public final class EventFileStream extends AbstractEventStream { end = disp.endNanos; } - currentParser = new ChunkParser(input, disp.parserConfiguration); + currentParser = new ChunkParser(input, disp.parserConfiguration, parserState); while (!isClosed()) { onMetadata(currentParser); if (currentParser.getStartNanos() > end) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ObjectContext.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ObjectContext.java index 3c946ba2097535aba8efa5acd4e9643b22e3f7ce..e855d0212a232923ec1cb5751b1066343d413258 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ObjectContext.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ObjectContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ package jdk.jfr.internal.consumer; import java.time.ZoneId; -import java.util.HashMap; +import java.util.ArrayDeque; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; @@ -34,33 +35,48 @@ import jdk.jfr.EventType; import jdk.jfr.ValueDescriptor; public final class ObjectContext { - private final Map<ValueDescriptor, ObjectContext> contextLookup; + private Map<ValueDescriptor, ObjectContext> contextLookup; private final TimeConverter timeConverter; - public final EventType eventType; public final List<ValueDescriptor> fields; ObjectContext(EventType eventType, List<ValueDescriptor> fields, TimeConverter timeConverter) { - this.contextLookup = new HashMap<>(); this.eventType = eventType; this.fields = fields; this.timeConverter = timeConverter; } - private ObjectContext(ObjectContext parent, ValueDescriptor descriptor) { - this.eventType = parent.eventType; - this.contextLookup = parent.contextLookup; - this.timeConverter = parent.timeConverter; - this.fields = descriptor.getFields(); + private ObjectContext(Map<ValueDescriptor, ObjectContext> contextLookup, EventType eventType, List<ValueDescriptor> fields, TimeConverter timeConverter) { + this.eventType = eventType; + this.contextLookup = contextLookup; + this.timeConverter = timeConverter; + this.fields = fields; } public ObjectContext getInstance(ValueDescriptor descriptor) { - ObjectContext context = contextLookup.get(descriptor); - if (context == null) { - context = new ObjectContext(this, descriptor); - contextLookup.put(descriptor, context); + if (contextLookup == null) { + // Lazy, only needed when accessing nested structures. + contextLookup = buildContextLookup(fields); + } + return contextLookup.get(descriptor); + } + + // Create mapping from ValueDescriptor to ObjectContext for all reachable + // ValueDescriptors. + public Map<ValueDescriptor, ObjectContext> buildContextLookup(List<ValueDescriptor> fields) { + Map<ValueDescriptor, ObjectContext> lookup = new IdentityHashMap<>(); + ArrayDeque<ValueDescriptor> q = new ArrayDeque<>(fields); + while (!q.isEmpty()) { + ValueDescriptor vd = q.pop(); + if (!lookup.containsKey(vd)) { + List<ValueDescriptor> children = vd.getFields(); + lookup.put(vd, new ObjectContext(lookup, eventType, children, timeConverter)); + for (ValueDescriptor v : children) { + q.add(v); + } + } } - return context; + return lookup; } public long convertTimestamp(long ticks) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ParserState.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ParserState.java new file mode 100644 index 0000000000000000000000000000000000000000..a03cddfff9ea453bf753e894f96484162109cedd --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ParserState.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.internal.consumer; + +public final class ParserState { + private volatile boolean closed; + + public boolean isClosed() { + return closed; + } + + public void close() { + closed = true; + } +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java index 4cfc9ae4800a81d1d7102323f1fa692526b421b8..69a0bd88378a697219fdef8347399a3f11fd3517 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ package jdk.jfr.internal.dcmd; - +import java.io.IOException; import jdk.jfr.FlightRecorder; import jdk.jfr.internal.LogLevel; @@ -69,8 +69,7 @@ final class DCmdConfigure extends AbstractDCmd { Long globalBufferSize, Long threadBufferSize, Long memorySize, - Long maxChunkSize, - Boolean sampleThreads + Long maxChunkSize ) throws DCmdException { if (Logger.shouldLog(LogTag.JFR_DCMD, LogLevel.DEBUG)) { @@ -81,8 +80,7 @@ final class DCmdConfigure extends AbstractDCmd { ", globalbuffersize=" + globalBufferSize + ", thread_buffer_size=" + threadBufferSize + ", memorysize=" + memorySize + - ", maxchunksize=" + maxChunkSize + - ", samplethreads=" + sampleThreads); + ", maxchunksize=" + maxChunkSize); } @@ -106,7 +104,11 @@ final class DCmdConfigure extends AbstractDCmd { } if (dumpPath != null) { - Options.setDumpPath(new SafePath(dumpPath)); + try { + Options.setDumpPath(new SafePath(dumpPath)); + } catch (IOException e) { + throw new DCmdException("Could not set " + dumpPath + " to emergency dump path. " + e.getMessage(), e); + } Logger.log(LogTag.JFR, LogLevel.INFO, "Emergency dump path set to " + dumpPath); if (verbose) { printDumpPath(); @@ -168,14 +170,6 @@ final class DCmdConfigure extends AbstractDCmd { updated = true; } - if (sampleThreads != null) { - Options.setSampleThreads(sampleThreads); - Logger.log(LogTag.JFR, LogLevel.INFO, "Sample threads set to " + sampleThreads); - if (verbose) { - printSampleThreads(); - } - updated = true; - } if (!verbose) { return new String[0]; } @@ -183,13 +177,13 @@ final class DCmdConfigure extends AbstractDCmd { println("Current configuration:"); println(); printRepositoryPath(); + printDumpPath(); printStackDepth(); printGlobalBufferCount(); printGlobalBufferSize(); printThreadBufferSize(); printMemorySize(); printMaxChunkSize(); - printSampleThreads(); } return getResult(); } @@ -206,10 +200,6 @@ final class DCmdConfigure extends AbstractDCmd { println(); } - private void printSampleThreads() { - println("Sample threads: " + Options.getSampleThreads()); - } - private void printStackDepth() { println("Stack depth: " + Options.getStackDepth()); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java index 77b8cccd77a17d615f7fa08325c9a1477bb51790..5d7f70c2a3409f135d1baaaa9ebba11dfe6a80f2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java @@ -42,10 +42,14 @@ import java.util.Set; import jdk.jfr.FlightRecorder; import jdk.jfr.Recording; import jdk.jfr.internal.JVM; +import jdk.jfr.internal.LogLevel; +import jdk.jfr.internal.LogTag; +import jdk.jfr.internal.Logger; import jdk.jfr.internal.OldObjectSample; import jdk.jfr.internal.PlatformRecording; import jdk.jfr.internal.PrivateAccess; import jdk.jfr.internal.SecuritySupport.SafePath; +import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.Type; import jdk.jfr.internal.jfc.JFC; import jdk.jfr.internal.jfc.model.JFCModel; @@ -240,7 +244,7 @@ final class DCmdStart extends AbstractDCmd { paths.add(JFC.createSafePath(setting)); } try { - JFCModel model = new JFCModel(paths); + JFCModel model = new JFCModel(paths, l -> logWarning(l)); Set<String> jfcOptions = new HashSet<>(); for (XmlInput input : model.getInputs()) { jfcOptions.add(input.getName()); @@ -364,7 +368,7 @@ final class DCmdStart extends AbstractDCmd { Turn on this flag only when you have an application that you suspect has a memory leak. If the settings parameter is set to 'profile', then the information collected includes the stack - trace from where the potential leaking object wasallocated. + trace from where the potential leaking object was allocated. (BOOLEAN, false) settings (Optional) Name of the settings file that identifies which events @@ -394,7 +398,7 @@ final class DCmdStart extends AbstractDCmd { take precedence. The whitespace character can be omitted for timespan values, i.e. 20s. For more information about the settings syntax, see Javadoc of the jdk.jfr package. - + %s Options must be specified using the <key> or <key>=<value> syntax. Example usage: @@ -414,7 +418,28 @@ final class DCmdStart extends AbstractDCmd { Note, if the default event settings are modified, overhead may exceed 1%%. - """.formatted(exampleDirectory()).lines().toArray(String[]::new); + """.formatted(jfcOptions(), exampleDirectory()).lines().toArray(String[]::new); + } + + private static String jfcOptions() { + try { + StringBuilder sb = new StringBuilder(); + for (SafePath s : SecuritySupport.getPredefinedJFCFiles()) { + String name = JFC.nameFromPath(s.toPath()); + JFCModel model = JFCModel.create(s, l -> {}); + sb.append('\n'); + sb.append("Options for ").append(name).append(":\n"); + sb.append('\n'); + for (XmlInput input : model.getInputs()) { + sb.append(" ").append(input.getOptionSyntax()).append('\n'); + sb.append('\n'); + } + } + return sb.toString(); + } catch (IOException | ParseException e) { + Logger.log(LogTag.JFR_DCMD, LogLevel.DEBUG, "Could not list .jfc options for JFR.start. " + e.getMessage()); + return ""; + } } @Override diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java index 6d798e294dddc2ed2ab2408c13b05e26cd983c3b..6a37bea34ad4e6caebf9f97834076d32c05a63fc 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java @@ -25,9 +25,11 @@ package jdk.jfr.internal.jfc; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.NoSuchFileException; @@ -62,9 +64,11 @@ public final class JFC { private final String content; private final String filename; private final String name; + private final SafePath path; private Configuration configuration; public KnownConfiguration(SafePath knownPath) throws IOException { + this.path = knownPath; this.content = readContent(knownPath); this.name = nameFromPath(knownPath.toPath()); this.filename = nullSafeFileName(knownPath.toPath()); @@ -270,4 +274,13 @@ public final class JFC { } throw new NoSuchFileException("Could not locate configuration with name " + name); } + + public static Reader newReader(SafePath sf) throws IOException { + for (KnownConfiguration c : getKnownConfigurations()) { + if (c.path.equals(sf)) { + return new StringReader(c.content); + } + } + return new FileReader(sf.toFile(), StandardCharsets.UTF_8); + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/JFCModel.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/JFCModel.java index bf9424265b8ea25c9059dd2af28bd573995c7833..746954a3e715a8718624a2d121f1d06b8ce98714 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/JFCModel.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/JFCModel.java @@ -26,14 +26,17 @@ package jdk.jfr.internal.jfc.model; import java.io.IOException; import java.io.PrintWriter; +import java.io.Reader; import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; import jdk.jfr.internal.SecuritySupport.SafePath; +import jdk.jfr.internal.jfc.JFC; import static java.nio.charset.StandardCharsets.UTF_8; @@ -42,19 +45,23 @@ public final class JFCModel { private final Map<String, List<ControlElement>> controls = new LinkedHashMap<>(); private final XmlConfiguration configuration; - public JFCModel(SafePath file) throws ParseException, IOException { - this.configuration = createConfiguration(file); - this.configuration.validate(); + private JFCModel(XmlConfiguration configuration) throws ParseException { + configuration.validate(); + this.configuration = configuration; + } + + public JFCModel(Reader reader, Consumer<String> logger) throws ParseException, IOException { + this(Parser.parse(reader)); addControls(); wireConditions(); - wireSettings(); + wireSettings(logger); } - public JFCModel(List<SafePath> files) throws IOException, ParseException { + public JFCModel(List<SafePath> files, Consumer<String> logger) throws IOException, ParseException { this.configuration = new XmlConfiguration(); this.configuration.setAttribute("version", "2.0"); for (SafePath file : files) { - JFCModel model = new JFCModel(file); + JFCModel model = JFCModel.create(file, logger); for (var entry : model.controls.entrySet()) { String name = entry.getKey(); // Fail-fast checks that prevents an ambiguous file to be written later @@ -69,6 +76,18 @@ public final class JFCModel { } } + public static JFCModel create(SafePath file, Consumer<String> logger) throws ParseException, IOException { + if (file.toString().equals("none")) { + XmlConfiguration configuration = new XmlConfiguration(); + configuration.setAttribute("version", "2.0"); + configuration.setAttribute("label", "None"); + return new JFCModel(configuration); + } + try (Reader r = JFC.newReader(file)) { + return new JFCModel(r, logger); + } + } + public void setLabel(String label) { configuration.setAttribute("label", label); } @@ -183,14 +202,14 @@ public final class JFCModel { } } - private void wireSettings() { + private void wireSettings(Consumer<String> logger) { for (XmlEvent event : configuration.getEvents()) { for (XmlSetting setting : event.getSettings()) { var controlName = setting.getControl(); if (controlName.isPresent()) { List<ControlElement> controls = getControlElements(controlName.get()); if (controls.isEmpty()) { - System.out.println("Warning! Setting '" + setting.getFullName() + "' refers to missing control '" + controlName.get() + "'"); + logger.accept("Setting '" + setting.getFullName() + "' refers to missing control '" + controlName.get() + "'"); } for (ControlElement ce : controls) { XmlElement control = (XmlElement) ce; @@ -204,14 +223,4 @@ public final class JFCModel { private void add(ControlElement control) { controls.computeIfAbsent(control.getName(), x -> new ArrayList<>()).add(control); } - - private XmlConfiguration createConfiguration(SafePath file) throws ParseException, IOException { - if (file.toString().equals("none")) { - XmlConfiguration configuration = new XmlConfiguration(); - configuration.setAttribute("version", "2.0"); - configuration.setAttribute("label", "None"); - return configuration; - } - return Parser.parse(file.toPath()); - } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/Parser.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/Parser.java index 78fd246ca7eb76a4fde8df0f3be2c30b8102d533..3b6aa05d9bd49d86fbf5e7fb170930ff7ed5520f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/Parser.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/Parser.java @@ -24,9 +24,8 @@ */ package jdk.jfr.internal.jfc.model; -import java.io.FileReader; import java.io.IOException; -import java.nio.file.Path; +import java.io.Reader; import java.text.ParseException; import java.util.ArrayDeque; import java.util.Deque; @@ -38,15 +37,13 @@ import jdk.internal.org.xml.sax.helpers.DefaultHandler; import jdk.internal.util.xml.SAXParser; import jdk.internal.util.xml.impl.SAXParserImpl; -import static java.nio.charset.StandardCharsets.UTF_8; - final class Parser { - static XmlConfiguration parse(Path path) throws ParseException, IOException { - try (FileReader r = new FileReader(path.toFile(), UTF_8)) { + static XmlConfiguration parse(Reader reader) throws ParseException, IOException { + try { SAXParser saxParser = new SAXParserImpl(); ConfigurationHandler handler = new ConfigurationHandler(); - saxParser.parse(new InputSource(r), handler); + saxParser.parse(new InputSource(reader), handler); return handler.configuration; } catch (SAXException sp) { ParseException pe = new ParseException(sp.getMessage(), -1); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlFlag.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlFlag.java index d494d3eb57ded2ba185ee1725f02c74eace40a3e..8e3431bc5a343761e302bc518237b514caac4418 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlFlag.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlFlag.java @@ -29,7 +29,7 @@ final class XmlFlag extends XmlInput { @Override public String getOptionSyntax() { - return getName() + "=<true|false>"; + return getName() + "=<true|false>" + " (" + getContent() + ")"; } @Override diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlSelection.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlSelection.java index d3bf22404797777b9caf69b09b7c6cb22a0d640c..c451119fb1af2881ca63cdd9ab030e4b3db2dc62 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlSelection.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlSelection.java @@ -36,7 +36,15 @@ final class XmlSelection extends XmlInput { for (XmlOption option : getOptions()) { sj.add(option.getName()); } - return getName() + "=" + sj.toString(); + StringBuilder sb = new StringBuilder(); + sb.append(getName()); + sb.append("="); + sb.append(sj.toString()); + XmlOption selected = getSelected(); + if (selected != null) { + sb.append(" (").append(selected.getName()).append(")"); + } + return sb.toString(); } @Override diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlText.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlText.java index 789243d2d5fb4fa651c4aa019f1984174178232b..4d90dd3c51cebb477b6c039f94471b97c656b535 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlText.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlText.java @@ -34,6 +34,14 @@ final class XmlText extends XmlInput { sb.append("=<"); sb.append(getContentType().orElse("text")); sb.append(">"); + sb.append(" ("); + String content = getContent(); + if (isTimespan()) { + // "20 ms" becomes "20ms" + content = content.replaceAll("\\s", ""); + } + sb.append(content); + sb.append(")"); return sb.toString(); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ChunkFilename.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ChunkFilename.java index 236c980acd0c741962497e73567add846dc9e0b4..8cc2cfeb180bdd2c763bb42a3fab77962e3d5a0f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ChunkFilename.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ChunkFilename.java @@ -74,7 +74,7 @@ public final class ChunkFilename { // If more than one file per second while (counter < MAX_CHUNK_NAMES) { - String extendedName = String.format("%s_%02d%s", filename, counter, FILE_EXTENSION); + String extendedName = makeExtendedName(filename, counter); p = directory.resolve(extendedName); counter++; if (!fileAcess.exists(p)) { @@ -83,4 +83,16 @@ public final class ChunkFilename { } throw new IOException("Unable to find unused filename after " + counter + " attempts"); } + + private String makeExtendedName(String filename, int counter) { + StringBuilder sb = new StringBuilder(); + sb.append(filename); + sb.append('_'); + if (counter < 10) { // chronological sorted + sb.append('0'); + } + sb.append(counter); + sb.append(FILE_EXTENSION); + return sb.toString(); + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java index 8a35a6b963915a90ee21fb232effc65dc33447fc..bdbeb4959b38feaddda9a28703bad8e38a8b730d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CutoffSetting.java @@ -78,10 +78,6 @@ public final class CutoffSetting extends JDKSettingControl { return value; } - public static boolean isType(long typeId) { - return CutoffSetting.typeId == typeId; - } - public static long parseValueSafe(String value) { if (value == null) { return 0L; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java index a05544c25c481e33dfdce3463da65b2643a7c4f3..49d676d636a80d2295f3dd8d7cbc8322b1fb0ee6 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java @@ -91,9 +91,5 @@ public final class ThrottleSetting extends JDKSettingControl { public String getValue() { return value; } - - public static boolean isType(long typeId) { - return ThrottleSetting.typeId == typeId; - } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Configure.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Configure.java index 037ad6dbf060c97a43851a5b1b53af5d92fcc7cc..551264c6889f77d79395ee6f396a760c167ac904 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Configure.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Configure.java @@ -127,7 +127,7 @@ final class Configure extends Command { } private void displayParameters(PrintStream stream, SafePath path, String name) throws ParseException, IOException { - JFCModel parameters = new JFCModel(path); + JFCModel parameters = JFCModel.create(path, l -> stream.println("Warning! " + l)); stream.println(); stream.println("Options for " + name + ":"); stream.println(); @@ -195,7 +195,7 @@ final class Configure extends Command { output = new SafePath(Path.of("custom.jfc")); } UserInterface ui = new UserInterface(); - JFCModel model = new JFCModel(inputFiles); + JFCModel model = new JFCModel(inputFiles, l -> ui.println("Warning! " + l)); model.setLabel("Custom"); if (log) { SettingsLog.enable(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Metadata.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Metadata.java index 3404c740439f9e1dd32c6a801eef05c70257fa96..c27bf935a2a487fe6fc05744ee8945e787a6ce23 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Metadata.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Metadata.java @@ -42,7 +42,7 @@ import jdk.jfr.consumer.RecordingFile; import jdk.jfr.internal.PlatformEventType; import jdk.jfr.internal.PrivateAccess; import jdk.jfr.internal.Type; -import jdk.jfr.internal.TypeLibrary; +import jdk.jfr.internal.MetadataRepository; import jdk.jfr.internal.consumer.JdkJfrConsumer; import static java.nio.charset.StandardCharsets.UTF_8; @@ -230,7 +230,7 @@ final class Metadata extends Command { if (file == null) { // Force initialization FlightRecorder.getFlightRecorder().getEventTypes(); - return TypeLibrary.getInstance().getTypes(); + return MetadataRepository.getInstance().getVisibleTypes(); } try (RecordingFile rf = new RecordingFile(file)) { return PRIVATE_ACCESS.readTypes(rf); diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 7ffacfc0248888dc7cc688bae48c8843d9f52f61..b168791f479a75dc2637c1c89400f53539aaa1d3 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -775,11 +775,6 @@ <setting name="threshold">0 ms</setting> </event> - <event name="jdk.ZThreadDebug"> - <setting name="enabled">true</setting> - <setting name="threshold">0 ms</setting> - </event> - <event name="jdk.ZUncommit"> <setting name="enabled">true</setting> <setting name="threshold">0 ms</setting> diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index 03eac2e8669e8ceb4f5cc03b2c76f6cd963d2618..8d1bada4638f057b0426cef4bbe840136474584d 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -775,11 +775,6 @@ <setting name="threshold">0 ms</setting> </event> - <event name="jdk.ZThreadDebug"> - <setting name="enabled">true</setting> - <setting name="threshold">0 ms</setting> - </event> - <event name="jdk.ZUncommit"> <setting name="enabled">true</setting> <setting name="threshold">0 ms</setting> diff --git a/src/jdk.jfr/share/man/jfr.1 b/src/jdk.jfr/share/man/jfr.1 index 27e4e630dc1374c8c66f1649dc4da859f65e1a0c..321562e90b81b6d0c5932161c68413509d156a2e 100644 --- a/src/jdk.jfr/share/man/jfr.1 +++ b/src/jdk.jfr/share/man/jfr.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JFR" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JFR" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AbstractPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AbstractPlugin.java index 758cb17e83e6803ff81f71b4fab1182bdffd8441..cf46ac684079381d1300e17f23d9635f236808b0 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AbstractPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AbstractPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.tools.jlink.plugin.ResourcePoolEntry; public abstract class AbstractPlugin implements Plugin { @@ -83,16 +84,31 @@ public abstract class AbstractPlugin implements Plugin { } } + ClassReader newClassReader(String path, ResourcePoolEntry resource) { + byte[] content = resource.contentBytes(); + try { + return new ClassReader(content); + } catch (Exception e) { + if (JlinkTask.DEBUG) { + System.err.printf("Failed to parse class file: %s from resource of type %s\n", path, + resource.getClass().getName()); + e.printStackTrace(); + dumpClassFile(path, content); + } + throw e; + } + } + protected ClassReader newClassReader(String path, byte[] buf) { try { return new ClassReader(buf); - } catch (IllegalArgumentException iae) { + } catch (Exception e) { if (JlinkTask.DEBUG) { System.err.printf("Failed to parse class file: %s\n", path); - iae.printStackTrace(); + e.printStackTrace(); dumpClassFile(path, buf); } - throw iae; + throw e; } } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripJavaDebugAttributesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripJavaDebugAttributesPlugin.java index 8e212f649c834000b05a011c46864df870261c36..d56ffc729ad95d2910a8160d694ad5bdbf112617 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripJavaDebugAttributesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripJavaDebugAttributesPlugin.java @@ -59,7 +59,7 @@ public final class StripJavaDebugAttributesPlugin extends AbstractPlugin { if (path.endsWith("module-info.class")) { // XXX. Do we have debug info? Is Asm ready for module-info? } else { - ClassReader reader = newClassReader(path, resource.contentBytes()); + ClassReader reader = newClassReader(path, resource); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); reader.accept(writer, ClassReader.SKIP_DEBUG); byte[] content = writer.toByteArray(); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties index 958c43c2ca4c7754f2c26094452f9020241cf0e2..017c46baab02df2c3318ad7447b10f5c31a355dc 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties @@ -142,7 +142,8 @@ generate-cds-archive.description=\ CDS plugin: generate cds archives if the runtime image supports CDS feature.\n\ generate-cds-archive.usage=\ -\ --generate-cds-archive Generate CDS archives if the runtime image supports CDS feature. +\ --generate-cds-archive Generate CDS archive if the runtime image supports\n\ +\ the CDS feature. generate-jli-classes.argument=@filename diff --git a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodOutputStream.java b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodOutputStream.java index 5fae838a59e050a31236d8da5b2acc5fb6690d8c..895500291f9e2fe71cd84b00295e1b2c94414811 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodOutputStream.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import jdk.internal.jmod.JmodFile; +import java.time.LocalDateTime; import static jdk.internal.jmod.JmodFile.*; @@ -54,15 +55,17 @@ class JmodOutputStream extends OutputStream implements AutoCloseable { * This method creates (or overrides, if exists) the JMOD file, * returning the the output stream to write to the JMOD file. */ - static JmodOutputStream newOutputStream(Path file) throws IOException { + static JmodOutputStream newOutputStream(Path file, LocalDateTime date) throws IOException { OutputStream out = Files.newOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(out); - return new JmodOutputStream(bos); + return new JmodOutputStream(bos, date); } private final ZipOutputStream zos; - private JmodOutputStream(OutputStream out) { + private final LocalDateTime date; + private JmodOutputStream(OutputStream out, LocalDateTime date) { this.zos = new ZipOutputStream(out); + this.date = date; try { JmodFile.writeMagicNumber(out); } catch (IOException e) { @@ -104,7 +107,11 @@ class JmodOutputStream extends OutputStream implements AutoCloseable { // sun.tools.jar.Main.update() ZipEntry e2 = new ZipEntry(e1.getName()); e2.setMethod(e1.getMethod()); - e2.setTime(e1.getTime()); + if (date != null) { + e2.setTimeLocal(date); + } else { + e2.setTime(e1.getTime()); + } e2.setComment(e1.getComment()); e2.setExtra(e1.getExtra()); if (e1.getMethod() == ZipEntry.STORED) { @@ -124,7 +131,11 @@ class JmodOutputStream extends OutputStream implements AutoCloseable { String name = Paths.get(prefix, path).toString() .replace(File.separatorChar, '/'); entries.get(section).add(path); - return new ZipEntry(name); + ZipEntry zipEntry = new ZipEntry(name); + if (date != null) { + zipEntry.setTimeLocal(date); + } + return zipEntry; } public boolean contains(Section section, String path) { diff --git a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java index f4248bd16cef3dda6ba04a30ce3966e89ca3db3f..52d6222d5a2288a9959821611334c5c831d59e8c 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java @@ -62,6 +62,11 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import jdk.internal.jmod.JmodFile; import jdk.internal.jmod.JmodFile.Section; @@ -160,8 +165,13 @@ public class JmodTask { boolean dryrun; List<PathMatcher> excludes; Path extractDir; + LocalDateTime date; } + // Valid --date range + static final ZonedDateTime DATE_MIN = ZonedDateTime.parse("1980-01-01T00:00:02Z"); + static final ZonedDateTime DATE_MAX = ZonedDateTime.parse("2099-12-31T23:59:59Z"); + public int run(String[] args) { try { @@ -427,7 +437,7 @@ public class JmodTask { Path target = options.jmodFile; Path tempTarget = jmodTempFilePath(target); try { - try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) { + try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget, options.date)) { jmod.write(jos); } Files.move(tempTarget, target); @@ -680,7 +690,6 @@ public class JmodTask { .filter(path -> isResource(path.toString())) .map(path -> toPackageName(path)) .filter(pkg -> pkg.length() > 0) - .distinct() .collect(Collectors.toSet()); } catch (IOException ioe) { throw new UncheckedIOException(ioe); @@ -695,7 +704,6 @@ public class JmodTask { .filter(e -> !e.isDirectory() && isResource(e.getName())) .map(e -> toPackageName(e)) .filter(pkg -> pkg.length() > 0) - .distinct() .collect(Collectors.toSet()); } @@ -984,7 +992,11 @@ public class JmodTask { if (e.getName().equals(MODULE_INFO)) { // what about module-info.class in versioned entries? ZipEntry ze = new ZipEntry(e.getName()); - ze.setTime(System.currentTimeMillis()); + if (options.date != null) { + ze.setTimeLocal(options.date); + } else { + ze.setTime(System.currentTimeMillis()); + } jos.putNextEntry(ze); recordHashes(in, jos, moduleHashes); jos.closeEntry(); @@ -1012,7 +1024,7 @@ public class JmodTask { { try (JmodFile jf = new JmodFile(target); - JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) + JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget, options.date)) { jf.stream().forEach(e -> { try (InputStream in = jf.getInputStream(e.section(), e.name())) { @@ -1147,6 +1159,26 @@ public class JmodTask { @Override public String valuePattern() { return "module-version"; } } + static class DateConverter implements ValueConverter<LocalDateTime> { + @Override + public LocalDateTime convert(String value) { + try { + ZonedDateTime date = ZonedDateTime.parse(value, DateTimeFormatter.ISO_ZONED_DATE_TIME) + .withZoneSameInstant(ZoneOffset.UTC); + if (date.isBefore(DATE_MIN) || date.isAfter(DATE_MAX)) { + throw new CommandException("err.date.out.of.range", value); + } + return date.toLocalDateTime(); + } catch (DateTimeParseException x) { + throw new CommandException("err.invalid.date", value, x.getMessage()); + } + } + + @Override public Class<LocalDateTime> valueType() { return LocalDateTime.class; } + + @Override public String valuePattern() { return "date"; } + } + static class WarnIfResolvedReasonConverter implements ValueConverter<ModuleResolution> { @@ -1382,6 +1414,11 @@ public class JmodTask { OptionSpec<Void> version = parser.accepts("version", getMessage("main.opt.version")); + OptionSpec<LocalDateTime> date + = parser.accepts("date", getMessage("main.opt.date")) + .withRequiredArg() + .withValuesConvertedBy(new DateConverter()); + NonOptionArgumentSpec<String> nonOptions = parser.nonOptions(); @@ -1425,6 +1462,8 @@ public class JmodTask { options.manPages = getLastElement(opts.valuesOf(manPages)); if (opts.has(legalNotices)) options.legalNotices = getLastElement(opts.valuesOf(legalNotices)); + if (opts.has(date)) + options.date = opts.valueOf(date); if (opts.has(modulePath)) { Path[] dirs = getLastElement(opts.valuesOf(modulePath)).toArray(new Path[0]); options.moduleFinder = ModulePath.of(Runtime.version(), true, dirs); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties b/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties index 09aa5ae44b3175b274a1727708f1f0c5d0a8a70f..c1022b0fb5e8e89b0e3ea1eb9385e908bf7a5db2 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -74,6 +74,9 @@ main.opt.hash-modules=Compute and record hashes to tie a packaged module\ main.opt.do-not-resolve-by-default=Exclude from the default root set of modules main.opt.warn-if-resolved=Hint for a tool to issue a warning if the module \ is resolved. One of deprecated, deprecated-for-removal, or incubating +main.opt.date=Date and time for the timestamps of entries, specified in ISO-8601\ +\ extended offset date-time with optional time-zone format, e.g.\ +\ "2022-02-12T12:30:00-05:00" main.opt.cmdfile=Read options from the specified file @@ -106,6 +109,8 @@ err.module.descriptor.not.found=Module descriptor not found err.missing.export.or.open.packages=Packages that are exported or open in {0} are not present: {1} err.module.resolution.fail=Resolution failed: {0} err.no.moduleToHash=No hashes recorded: no module matching {0} found to record hashes +err.invalid.date=--date {0} is not a valid ISO-8601 extended offset date-time with optional time-zone format: {1} +err.date.out.of.range=--date {0} is out of the valid range 1980-01-01T00:00:02Z to 2099-12-31T23:59:59Z warn.invalid.arg=Invalid classname or pathname not exist: {0} warn.no.module.hashes=No hashes recorded: no module specified for hashing depends on {0} warn.ignore.entry=ignoring entry {0}, in section {1} diff --git a/src/jdk.jlink/share/man/jlink.1 b/src/jdk.jlink/share/man/jlink.1 index f5324309efcfd1f7e867ebedc5f7c80f85174cf2..fbe660189431b54d4a6d39214303e6850497d896 100644 --- a/src/jdk.jlink/share/man/jlink.1 +++ b/src/jdk.jlink/share/man/jlink.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JLINK" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JLINK" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP @@ -294,6 +294,17 @@ Example: Strips debug information from the output image. .RS .RE +.SS Plugin \f[CB]generate\-cds\-archive\f[R] +.TP +.B Options +\f[CB]\-\-generate\-cds\-archive\f[R] +.RS +.RE +.TP +.B Description +Generate CDS archive if the runtime image supports the CDS feature. +.RS +.RE .SH JLINK EXAMPLES .PP The following command creates a runtime image in the directory diff --git a/src/jdk.jlink/share/man/jmod.1 b/src/jdk.jlink/share/man/jmod.1 index 16f595782a5077791a3b8fda38aa5fdd15c975f4..a9c68e1a8dcab0d28ca12dab826dd735ad363227 100644 --- a/src/jdk.jlink/share/man/jmod.1 +++ b/src/jdk.jlink/share/man/jmod.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JMOD" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JMOD" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java index b52285bc0ff030658e9ff223577d37d2bddb374a..c41d8ff3bbb68d34913e62c8948ee46acc9fc149 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java @@ -191,7 +191,7 @@ public class IOUtils { PrintStream consumer, boolean writeOutputToFile, long timeout) throws IOException { exec(pb, testForPresenceOnly, consumer, writeOutputToFile, - Executor.INFINITE_TIMEOUT, false); + timeout, false); } static void exec(ProcessBuilder pb, boolean testForPresenceOnly, diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Log.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Log.java index 22e43b4311f75f5db57be18331988adc56e90171..b14b4ab22caeb708e49e2a7cbe052eb6a68cf3ea 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Log.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Log.java @@ -108,7 +108,7 @@ public class Log { public void verbose(List<String> strings, List<String> output, int returnCode, long pid) { if (verbose) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append("Command [PID: "); sb.append(pid); sb.append("]:\n "); @@ -116,13 +116,13 @@ public class Log { for (String s : strings) { sb.append(" " + s); } - verbose(new String(sb)); + verbose(sb.toString()); if (output != null && !output.isEmpty()) { - sb = new StringBuffer("Output:"); + sb = new StringBuilder("Output:"); for (String s : output) { sb.append("\n " + s); } - verbose(new String(sb)); + verbose(sb.toString()); } verbose("Returned: " + returnCode + "\n"); } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/OverridableResource.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/OverridableResource.java index 9680691bc5db94d2322ba72e0be54c90f8848510..c455ef7150034918bab35f2dcb7a030c6fc672c5 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/OverridableResource.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/OverridableResource.java @@ -36,6 +36,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -279,11 +281,35 @@ final class OverridableResource { private static Stream<String> substitute(Stream<String> lines, Map<String, String> substitutionData) { + // Order substitution data by the length of keys. + // Longer keys go first. + // This is needed to properly handle cases when one key is + // a subtring of another and try the later first. + var orderedEntries = substitutionData.entrySet().stream() + .sorted(Map.Entry.<String, String>comparingByKey( + Comparator.comparingInt(String::length)).reversed()) + .toList(); return lines.map(line -> { String result = line; - for (var entry : substitutionData.entrySet()) { - result = result.replace(entry.getKey(), Optional.ofNullable( - entry.getValue()).orElse("")); + var workEntries = orderedEntries; + var it = workEntries.listIterator(); + while (it.hasNext()) { + var entry = it.next(); + String newResult = result.replace(entry.getKey(), + Optional.ofNullable(entry.getValue()).orElse("")); + if (!newResult.equals(result)) { + // Substitution occured. + // Remove the matching substitution key from the list and + // go over the list of substitution entries again. + if (workEntries == orderedEntries) { + workEntries = new ArrayList<>(orderedEntries); + it = workEntries.listIterator(it.nextIndex() - 1); + it.next(); + } + it.remove(); + it = workEntries.listIterator(); + result = newResult; + } } return result; }); diff --git a/src/jdk.jpackage/share/man/jpackage.1 b/src/jdk.jpackage/share/man/jpackage.1 index 2b85c96cb468fd7d9021599a097dbe796ab32a7e..51b45f7bdfcb73c27fa10187c7422d8a9b4317d9 100644 --- a/src/jdk.jpackage/share/man/jpackage.1 +++ b/src/jdk.jpackage/share/man/jpackage.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JPACKAGE" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JPACKAGE" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP @@ -56,7 +56,7 @@ Read options from a file. This option can be used multiple times. .RE .TP -.B \f[CB]\-\-type\f[R] or \f[CB]\-t\f[R] <type string> +.B \f[CB]\-\-type\f[R] or \f[CB]\-t\f[R] \f[I]type\f[R] The type of package to create .RS .PP @@ -67,17 +67,17 @@ If this option is not specified a platform dependent default type will be created. .RE .TP -.B \f[CB]\-\-app\-version\f[R] <version> +.B \f[CB]\-\-app\-version\f[R] \f[I]version\f[R] Version of the application and/or package .RS .RE .TP -.B \f[CB]\-\-copyright\f[R] <copyright string> +.B \f[CB]\-\-copyright\f[R] \f[I]copyright\f[R] Copyright for the application .RS .RE .TP -.B \f[CB]\-\-description\f[R] <description string> +.B \f[CB]\-\-description\f[R] \f[I]description\f[R] Description of the application .RS .RE @@ -88,30 +88,33 @@ for the current platform to the output stream, and exit. .RS .RE .TP -.B \f[CB]\-\-icon\f[R] <icon file path> -Path of the icon of the application package (absolute path or relative -to the current directory) +.B \f[CB]\-\-icon\f[R] \f[I]path\f[R] +Path of the icon of the application package .RS +.PP +(absolute path or relative to the current directory) .RE .TP -.B \f[CB]\-\-name\f[R] or \f[CB]\-n\f[R] <name> +.B \f[CB]\-\-name\f[R] or \f[CB]\-n\f[R] \f[I]name\f[R] Name of the application and/or package .RS .RE .TP -.B \f[CB]\-\-dest\f[R] or \f[CB]\-d\f[R] <output path> +.B \f[CB]\-\-dest\f[R] or \f[CB]\-d\f[R] \f[I]destination\f[R] Path where generated output file is placed .RS .PP -Defaults to the current working directory. (absolute path or relative to the current directory). +.PP +Defaults to the current working directory. .RE .TP -.B \f[CB]\-\-temp\f[R] <directory path> +.B \f[CB]\-\-temp\f[R] \f[I]directory\f[R] Path of a new or empty directory used to create temporary files -(absolute path or relative to the current directory) .RS .PP +(absolute path or relative to the current directory) +.PP If specified, the temp dir will not be removed upon the task completion and must be removed manually. .PP @@ -119,7 +122,7 @@ If not specified, a temporary directory will be created and removed upon the task completion. .RE .TP -.B \f[CB]\-\-vendor\f[R] <vendor string> +.B \f[CB]\-\-vendor\f[R] \f[I]vendor\f[R] Vendor of the application .RS .RE @@ -135,7 +138,7 @@ Print the product version to the output stream and exit. .RE .SS Options for creating the runtime image: .TP -.B \f[CB]\-\-add\-modules\f[R] <module name> [\f[CB],\f[R]<module name>...] +.B \f[CB]\-\-add\-modules\f[R] \f[I]module\-name\f[R] [\f[CB],\f[R]\f[I]module\-name\f[R]...] A comma (",") separated list of modules to add .RS .PP @@ -148,7 +151,7 @@ specified) are used. This option can be used multiple times. .RE .TP -.B \f[CB]\-\-module\-path\f[R] or \f[CB]\-p\f[R] <module path>... +.B \f[CB]\-\-module\-path\f[R] or \f[CB]\-p\f[R] \f[I]module\-path\f[R] [\f[CB],\f[R]\f[I]module\-path\f[R]...] A File.pathSeparator separated list of paths .RS .PP @@ -158,7 +161,7 @@ and is absolute or relative to the current directory. This option can be used multiple times. .RE .TP -.B \f[CB]\-\-jlink\-options\f[R] <jlink options> +.B \f[CB]\-\-jlink\-options\f[R] \f[I]options\f[R] A space separated list of options to pass to jlink .RS .PP @@ -168,34 +171,48 @@ If not specified, defaults to "\-\-strip\-native\-commands This option can be used multiple times. .RE .TP -.B \f[CB]\-\-runtime\-image\f[R] <directory path> +.B \f[CB]\-\-runtime\-image\f[R] \f[I]directory\f[R] Path of the predefined runtime image that will be copied into the -application image (absolute path or relative to the current directory) +application image .RS .PP +(absolute path or relative to the current directory) +.PP If \-\-runtime\-image is not specified, jpackage will run jlink to create the runtime image using options specified by \-\-jlink\-options. .RE .SS Options for creating the application image: .TP -.B \f[CB]\-\-input\f[R] or \f[CB]\-i\f[R] <input path> +.B \f[CB]\-\-input\f[R] or \f[CB]\-i\f[R] \f[I]directory\f[R] Path of the input directory that contains the files to be packaged -(absolute path or relative to the current directory) .RS .PP +(absolute path or relative to the current directory) +.PP All files in the input directory will be packaged into the application image. .RE +.TP +.B `\-\-app\-content \f[I]additional\-content\f[R][,\f[I]additional\-content\f[R]...] +A comma separated list of paths to files and/or directories to add to +the application payload. +.RS +.PP +This option can be used more than once. +.RE .SS Options for creating the application launcher(s): .TP -.B \f[CB]\-\-add\-launcher\f[R] <launcher name>=<file path> +.B \f[CB]\-\-add\-launcher\f[R] \f[I]name\f[R]=\f[I]path\f[R] Name of launcher, and a path to a Properties file that contains a list -of key, value pairs (absolute path or relative to the current directory) +of key, value pairs .RS .PP +(absolute path or relative to the current directory) +.PP The keys "module", "main\-jar", "main\-class", "arguments", -"java\-options", "app\-version", "icon", "linux\-app\-category", -"linux\-app\-release", and "win\-console" can be used. +"java\-options", "app\-version", "icon", "win\-console", +"win\-shortcut", "win\-menu", "linux\-app\-category", and +"linux\-shortcut", can be used. .PP These options are added to, or used to overwrite, the original command line options to build an additional alternative launcher. @@ -206,7 +223,7 @@ this option can be used multiple times to build multiple additional launchers. .RE .TP -.B \f[CB]\-\-arguments\f[R] <main class arguments> +.B \f[CB]\-\-arguments\f[R] \f[I]arguments\f[R] Command line arguments to pass to the main class if no command line arguments are given to the launcher .RS @@ -214,21 +231,21 @@ arguments are given to the launcher This option can be used multiple times. .RE .TP -.B \f[CB]\-\-java\-options\f[R] <java options> +.B \f[CB]\-\-java\-options\f[R] \f[I]options\f[R] Options to pass to the Java runtime .RS .PP This option can be used multiple times. .RE .TP -.B \f[CB]\-\-main\-class\f[R] <class name> +.B \f[CB]\-\-main\-class\f[R] \f[I]class\-name\f[R] Qualified name of the application main class to execute .RS .PP This option can only be used if \-\-main\-jar is specified. .RE .TP -.B \f[CB]\-\-main\-jar\f[R] <main jar file> +.B \f[CB]\-\-main\-jar\f[R] \f[I]main\-jar\f[R] The main JAR of the application; containing the main class (specified as a path relative to the input path) .RS @@ -236,7 +253,7 @@ a path relative to the input path) Either \-\-module or \-\-main\-jar option can be specified but not both. .RE .TP -.B \f[CB]\-\-module\f[R] or \f[CB]\-m\f[R] <module name>/<main class>] +.B \f[CB]\-\-module\f[R] or \f[CB]\-m\f[R] \f[I]module\-name\f[R][/\f[I]main\-class\f[R]] The main module (and optionally main class) of the application .RS .PP @@ -256,7 +273,7 @@ application which requires console interactions .RE .SS macOS platform options (available only when running on macOS): .TP -.B \f[CB]\-\-mac\-package\-identifier\f[R] <ID string> +.B \f[CB]\-\-mac\-package\-identifier\f[R] \f[I]identifier\f[R] An identifier that uniquely identifies the application for macOS .RS .PP @@ -266,7 +283,7 @@ May only use alphanumeric (A\-Z,a\-z,0\-9), hyphen (\-), and period (.) characters. .RE .TP -.B \f[CB]\-\-mac\-package\-name\f[R] <name string> +.B \f[CB]\-\-mac\-package\-name\f[R] \f[I]name\f[R] Name of the application as it appears in the Menu Bar .RS .PP @@ -277,7 +294,7 @@ displaying in the menu bar and the application Info window. Defaults to the application name. .RE .TP -.B \f[CB]\-\-mac\-package\-signing\-prefix\f[R] <prefix string> +.B \f[CB]\-\-mac\-package\-signing\-prefix\f[R] \f[I]prefix\f[R] When signing the application package, this value is prefixed to all components that need to be signed that don\[aq]t have an existing package identifier. @@ -289,14 +306,14 @@ Request that the bundle be signed. .RS .RE .TP -.B \f[CB]\-\-mac\-signing\-keychain\f[R] <keychain name> +.B \f[CB]\-\-mac\-signing\-keychain\f[R] \f[I]keychain\-name\f[R] Name of the keychain to search for the signing identity .RS .PP If not specified, the standard keychains are used. .RE .TP -.B \f[CB]\-\-mac\-signing\-key\-user\-name\f[R] <team name> +.B \f[CB]\-\-mac\-signing\-key\-user\-name\f[R] \f[I]name\f[R] Team or user name portion in Apple signing identities .RS .RE @@ -306,13 +323,13 @@ Indicates that the jpackage output is intended for the Mac App Store. .RS .RE .TP -.B \f[CB]\-\-mac\-entitlements\f[R] <file path> +.B \f[CB]\-\-mac\-entitlements\f[R] \f[I]path\f[R] Path to file containing entitlements to use when signing executables and libraries in the bundle .RS .RE .TP -.B \f[CB]\-\-mac\-app\-category\f[R] <category string> +.B \f[CB]\-\-mac\-app\-category\f[R] \f[I]category\f[R] String used to construct LSApplicationCategoryType in application plist .RS .PP @@ -320,59 +337,63 @@ The default value is "utilities". .RE .SS Options for creating the application package: .TP -.B \f[CB]\-\-about\-url\f[R] <url> +.B \f[CB]\-\-about\-url\f[R] \f[I]url\f[R] URL of the application\[aq]s home page .RS .RE .TP -.B \f[CB]\-\-app\-image\f[R] <directory path> +.B \f[CB]\-\-app\-image\f[R] \f[I]directory\f[R] Location of the predefined application image that is used to build an installable package .RS .PP -(absolute path or relative to the current directory). +(absolute path or relative to the current directory) .PP See create\-app\-image mode options to create the application image. .RE .TP -.B \f[CB]\-\-file\-associations\f[R] <file path> +.B \f[CB]\-\-file\-associations\f[R] \f[I]path\f[R] Path to a Properties file that contains list of key, value pairs -(absolute path or relative to the current directory) .RS .PP +(absolute path or relative to the current directory) +.PP The keys "extension", "mime\-type", "icon", and "description" can be used to describe the association. .PP This option can be used multiple times. .RE .TP -.B \f[CB]\-\-install\-dir\f[R] <directory path> +.B \f[CB]\-\-install\-dir\f[R] \f[I]path\f[R] Absolute path of the installation directory of the application (on macos or linux), or relative sub\-path of the installation directory such as "Program Files" or "AppData" (on Windows) .RS .RE .TP -.B \f[CB]\-\-license\-file\f[R] <file path> -Path to the license file (absolute path or relative to the current -directory) +.B \f[CB]\-\-license\-file\f[R] \f[I]path\f[R] +Path to the license file .RS +.PP +(absolute path or relative to the current directory) .RE .TP -.B \f[CB]\-\-resource\-dir\f[R] <directory path> -Path to override jpackage resources (absolute path or relative to the -current directory) +.B \f[CB]\-\-resource\-dir\f[R] \f[I]path\f[R] +Path to override jpackage resources .RS .PP +(absolute path or relative to the current directory) +.PP Icons, template files, and other resources of jpackage can be over\-ridden by adding replacement resources to this directory. .RE .TP -.B \f[CB]\-\-runtime\-image\f[R] <directory path> -Path of the predefined runtime image to install (absolute path or -relative to the current directory) +.B \f[CB]\-\-runtime\-image\f[R] \f[I]path\f[R] +Path of the predefined runtime image to install .RS .PP +(absolute path or relative to the current directory) +.PP Option is required when creating a runtime installer. .RE .SS Platform dependent options for creating the application package: @@ -384,7 +405,7 @@ product is installed. .RS .RE .TP -.B \f[CB]\-\-win\-help\-url\f[R] <url> +.B \f[CB]\-\-win\-help\-url\f[R] \f[I]url\f[R] URL where user can obtain further information or technical support .RS .RE @@ -394,7 +415,7 @@ Request to add a Start Menu shortcut for this application .RS .RE .TP -.B \f[CB]\-\-win\-menu\-group\f[R] <menu group name> +.B \f[CB]\-\-win\-menu\-group\f[R] \f[I]menu\-group\-name\f[R] Start Menu group this application is placed in .RS .RE @@ -415,30 +436,30 @@ by installer .RS .RE .TP -.B \f[CB]\-\-win\-update\-url\f[R] <url> +.B \f[CB]\-\-win\-update\-url\f[R] \f[I]url\f[R] URL of available application update information .RS .RE .TP -.B \f[CB]\-\-win\-upgrade\-uuid\f[R] <id string> +.B \f[CB]\-\-win\-upgrade\-uuid\f[R] \f[I]id\f[R] UUID associated with upgrades for this package .RS .RE .SS Linux platform options (available only when running on Linux): .TP -.B \f[CB]\-\-linux\-package\-name\f[R] <package name> +.B \f[CB]\-\-linux\-package\-name\f[R] \f[I]name\f[R] Name for Linux package .RS .PP Defaults to the application name. .RE .TP -.B \f[CB]\-\-linux\-deb\-maintainer\f[R] <email address> +.B \f[CB]\-\-linux\-deb\-maintainer\f[R] \f[I]email\-address\f[R] Maintainer for .deb bundle .RS .RE .TP -.B \f[CB]\-\-linux\-menu\-group\f[R] <menu\-group\-name> +.B \f[CB]\-\-linux\-menu\-group\f[R] \f[I]menu\-group\-name\f[R] Menu group this application is placed in .RS .RE @@ -448,20 +469,19 @@ Required packages or capabilities for the application .RS .RE .TP -.B \f[CB]\-\-linux\-rpm\-license\-type\f[R] <type string> -Type of the license ("License: <value>" of the RPM .spec) +.B \f[CB]\-\-linux\-rpm\-license\-type\f[R] \f[I]type\f[R] +Type of the license ("License: \f[I]value\f[R]" of the RPM .spec) .RS .RE .TP -.B \f[CB]\-\-linux\-app\-release\f[R] <release string> +.B \f[CB]\-\-linux\-app\-release\f[R] \f[I]release\f[R] Release value of the RPM <name>.spec file or Debian revision value of the DEB control file .RS .RE .TP -.B \f[CB]\-\-linux\-app\-category\f[R] <category string> -Group value of the RPM <name>.spec file or Section value of DEB control -file +.B \f[CB]\-\-linux\-app\-category\f[R] \f[I]category\-value\f[R] +Group value of the RPM /.spec file or Section value of DEB control file .RS .RE .TP @@ -469,6 +489,14 @@ file Creates a shortcut for the application. .RS .RE +.SS macOS platform options (available only when running on macOS): +.TP +.B \[aq]\-\-mac\-dmg\-content \f[I]additional\-content\f[R][,\f[I]additional\-content\f[R]...] +Include all the referenced content in the dmg. +.RS +.PP +This option can be used more than once. +.RE .SH JPACKAGE EXAMPLES .IP .nf diff --git a/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp b/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp index 105b512b260a9544abb2bed34b7341b5946aef3c..db01cd164bc50d0905cc23b59f2ba14d9371d15a 100644 --- a/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp +++ b/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp @@ -23,6 +23,7 @@ * questions. */ +#include <cstddef> #include <cstring> #include "tstrings.h" #include "JvmLauncher.h" diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java index 4b63ad7f200f6518f7c22c7d46e7eab0f75dfb07..a6c92b67e9678cc7aa5235cdfb3b09cf426b7571 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -372,7 +372,7 @@ class Feedback { return ""; } Matcher m = FIELD_PATTERN.matcher(format); - StringBuffer sb = new StringBuffer(format.length()); + StringBuilder sb = new StringBuilder(format.length()); while (m.find()) { String fieldName = m.group(1); String sub = format(fieldName, selector); diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index b257b1323633033dd22c701c6181d12399e6218d..ac78e23eff6565d01c9f9dde51118df57ce4a123 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -254,7 +254,7 @@ public class JShellTool implements MessageHandler { Pattern.compile(OPTION_PRE_PATTERN.pattern() + "(?<dd>-??)(?<flag>-([a-z][a-z\\-]*)?)"); // match an option flag and a (possibly missing or incomplete) value private static final Pattern OPTION_VALUE_PATTERN = - Pattern.compile(OPTION_PATTERN.pattern() + "\\s+(?<val>\\S*)"); + Pattern.compile(OPTION_PATTERN.pattern() + "\\s+(?<val>(\\S|\\\\ )*)"); // Tool id (tid) mapping: the three name spaces NameSpace mainNamespace; @@ -1561,13 +1561,13 @@ public class JShellTool implements MessageHandler { private static CompletionProvider fileCompletions(Predicate<Path> accept) { return (code, cursor, anchor) -> { int lastSlash = code.lastIndexOf('/'); - String path = code.substring(0, lastSlash + 1); - String prefix = lastSlash != (-1) ? code.substring(lastSlash + 1) : code; + String path = code.substring(0, lastSlash + 1).replace("\\ ", " "); + String prefix = (lastSlash != (-1) ? code.substring(lastSlash + 1) : code).replace("\\ ", " "); Path current = toPathResolvingUserHome(path); List<Suggestion> result = new ArrayList<>(); try (Stream<Path> dir = Files.list(current)) { dir.filter(f -> accept.test(f) && f.getFileName().toString().startsWith(prefix)) - .map(f -> new ArgSuggestion(f.getFileName() + (Files.isDirectory(f) ? "/" : ""))) + .map(f -> new ArgSuggestion(f.getFileName().toString().replace(" ", "\\ ") + (Files.isDirectory(f) ? "/" : ""))) .forEach(result::add); } catch (IOException ex) { //ignore... diff --git a/src/jdk.jshell/share/man/jshell.1 b/src/jdk.jshell/share/man/jshell.1 index 1865d30f90ac95bde6a6abb759963336b4ecc48e..0eddce3469c645a5ba8d6b9ae7d8d31cb3803785 100644 --- a/src/jdk.jshell/share/man/jshell.1 +++ b/src/jdk.jshell/share/man/jshell.1 @@ -22,7 +22,7 @@ .\"t .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JSHELL" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JSHELL" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java b/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java index 30fe303fa61c8c337381e8895283ba9a462713fb..5dc7f1fa2fbcec72cb04fb1e24838993ed99394c 100644 --- a/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java +++ b/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package sun.tools.jstatd; +import java.io.ObjectInputFilter; import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.Registry; @@ -47,6 +48,8 @@ public class Jstatd { private static boolean startRegistry = true; private static RemoteHost remoteHost; + private static final String rmiFilterPattern = "sun.jvmstat.monitor.remote.RemoteVm;com.sun.proxy.jdk.proxy*;java.lang.reflect.Proxy;java.rmi.server.RemoteObjectInvocationHandler;java.rmi.server.RemoteObject;!*"; + private static void printUsage() { System.err.println("usage: jstatd [-nr] [-p port] [-r rmiport] [-n rminame]\n" + " jstatd -?|-h|--help"); @@ -72,7 +75,6 @@ public class Jstatd { } } - @SuppressWarnings({"removal","deprecation"}) // Use of RMISecurityManager public static void main(String[] args) { String rminame = null; int rmiPort = 0; @@ -132,10 +134,6 @@ public class Jstatd { System.exit(1); } - if (System.getSecurityManager() == null) { - System.setSecurityManager(new RMISecurityManager()); - } - StringBuilder name = new StringBuilder(); if (port >= 0) { @@ -149,11 +147,10 @@ public class Jstatd { name.append("/").append(rminame); try { - // use 1.5.0 dynamically generated subs. - System.setProperty("java.rmi.server.ignoreSubClasses", "true"); remoteHost = new RemoteHostImpl(rmiPort); + ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(rmiFilterPattern); RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject( - remoteHost, rmiPort); + remoteHost, rmiPort, filter); bind(name.toString(), stub); System.out.println("jstatd started (bound to " + name.toString() + ")"); System.out.flush(); diff --git a/src/jdk.jstatd/share/man/jstatd.1 b/src/jdk.jstatd/share/man/jstatd.1 index ccfe6e000aa213fee8fcd06bd6fda180aedb017f..d13f06b59b17975f648007f16b538f4cd750f765 100644 --- a/src/jdk.jstatd/share/man/jstatd.1 +++ b/src/jdk.jstatd/share/man/jstatd.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JSTATD" "1" "2021" "JDK 18\-ea" "JDK Commands" +.TH "JSTATD" "1" "2022" "JDK 19\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java b/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java index 06856f972783773c04759623b2f8f6b722576437..2d261bfb3a74b0433995752faf27639720ae3444 100644 --- a/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java +++ b/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java @@ -564,8 +564,7 @@ public class Agent { InputStream in = null; try { in = new FileInputStream(configFile); - BufferedInputStream bin = new BufferedInputStream(in); - p.load(bin); + p.load(in); } catch (FileNotFoundException e) { error(CONFIG_FILE_OPEN_FAILED, e.getMessage()); } catch (IOException e) { diff --git a/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java index 6630124f374c3c6d85b31dcd50f4920afbedd2b8..aaa32944ddff771e2199c15b8355111742e97920 100644 --- a/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java +++ b/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java @@ -692,8 +692,7 @@ public final class ConnectorBootstrap { // Load the SSL keystore properties from the config file Properties p = new Properties(); try (InputStream in = new FileInputStream(sslConfigFileName)) { - BufferedInputStream bin = new BufferedInputStream(in); - p.load(bin); + p.load(in); } String keyStore = p.getProperty("javax.net.ssl.keyStore"); diff --git a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java index ed4f2d8a1054a101da37b7edd6a70d6786878ce5..a5508ec45dbcec8d19693d9cedd7d801b3c26d55 100644 --- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java +++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java @@ -148,7 +148,7 @@ public class DnsClient { } } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { close(); } diff --git a/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java b/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java index bea428a60680661ab181d889893ec67a3874d606..d77055d280876bcba0c42636b31bfd88b5ca3e3a 100644 --- a/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java +++ b/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java @@ -120,7 +120,7 @@ public class RegistryContext implements Context, Referenceable { reference = ctx.reference; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { close(); } @@ -596,7 +596,7 @@ class BindingEnumeration implements NamingEnumeration<Binding> { nextName = 0; } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() { ctx.close(); } diff --git a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java index 44692bdd21959169196e3b3c8a4a4bd97f5ef268..a399447405013592703d0b01af25121178375518 100644 --- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java +++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -712,7 +712,7 @@ public class KeyStoreLoginModule implements LoginModule { * {@code login} method), then this method associates a * {@code X500Principal} for the subject distinguished name of the * first certificate in the alias's credentials in the subject's - * principals,the alias's certificate path in the subject's public + * principals, the alias's certificate path in the subject's public * credentials, and a {@code X500PrivateCredential} whose certificate * is the first certificate in the alias's certificate path and whose * private key is the alias's private key in the subject's private diff --git a/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java index 04cc61a5d2e45e29c9eddf9bb4f2f9240f11ead3..afdb7279c170e158fe2f640dc88f2473ca915a3e 100644 --- a/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java +++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java @@ -162,7 +162,7 @@ abstract class GssKrb5Base extends AbstractSaslImpl { } } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws Throwable { dispose(); } diff --git a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java index e0ab5f3dffad290fa3d0d94d39b35b08fc6067d8..2f8d397c6c99baba3aef8341a694491c0517303b 100644 --- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java +++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java @@ -633,8 +633,15 @@ public final class Unsafe { * the field locations in a form usable by {@link #getInt(Object,long)}. * Therefore, code which will be ported to such JVMs on 64-bit platforms * must preserve all bits of static field offsets. + * + * @deprecated The guarantee that a field will always have the same offset + * and base may not be true in a future release. The ability to provide an + * offset and object reference to a heap memory accessor will be removed + * in a future release. Use {@link java.lang.invoke.VarHandle} instead. + * * @see #getInt(Object, long) */ + @Deprecated(since="18") @ForceInline public long objectFieldOffset(Field f) { if (f == null) { @@ -665,8 +672,15 @@ public final class Unsafe { * a few bits to encode an offset within a non-array object, * However, for consistency with other methods in this class, * this method reports its result as a long value. + * + * @deprecated The guarantee that a field will always have the same offset + * and base may not be true in a future release. The ability to provide an + * offset and object reference to a heap memory accessor will be removed + * in a future release. Use {@link java.lang.invoke.VarHandle} instead. + * * @see #getInt(Object, long) */ + @Deprecated(since="18") @ForceInline public long staticFieldOffset(Field f) { if (f == null) { @@ -691,7 +705,13 @@ public final class Unsafe { * which is a "cookie", not guaranteed to be a real Object, and it should * not be used in any way except as argument to the get and put routines in * this class. + * + * @deprecated The guarantee that a field will always have the same offset + * and base may not be true in a future release. The ability to provide an + * offset and object reference to a heap memory accessor will be removed + * in a future release. Use {@link java.lang.invoke.VarHandle} instead. */ + @Deprecated(since="18") @ForceInline public Object staticFieldBase(Field f) { if (f == null) { diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index 4f9b4e427bc57a30b33b5e01c2dcadd49598b13a..dd85df4cc609e83c1a78c6cfaa41200f1d99a611 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -1219,7 +1219,7 @@ class ZipFileSystem extends FileSystem { return zc.toString(name); } - @SuppressWarnings("deprecation") + @SuppressWarnings("removal") protected void finalize() throws IOException { close(); } @@ -1471,6 +1471,13 @@ class ZipFileSystem extends FileSystem { }; } + /** + * Package-private accessor to entry alias map used by ZipPath. + */ + byte[] lookupPath(byte[] resolvedPath) { + return entryLookup.apply(resolvedPath); + } + /** * Create a sorted version map of version -> inode, for inodes <= max version. * 9 -> META-INF/versions/9 diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java index 5cccce8d113e3b017536bdaaa0807ef5481bb775..234c54f5d0287954f8f8d1be31ecdb998ed811c1 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java @@ -200,13 +200,19 @@ final class ZipPath implements Path { return new URI("jar", decodeUri(zfs.getZipFile().toUri().toString()) + "!" + - zfs.getString(toAbsolutePath().path), + getRealPath(), null); } catch (Exception ex) { throw new AssertionError(ex); } } + private String getRealPath() { + byte[] resolvedPath = getResolvedPath(); + byte[] realPath = zfs.lookupPath(resolvedPath); + return zfs.getString(realPath != null ? realPath : resolvedPath); + } + private boolean equalsNameAt(ZipPath other, int index) { int mbegin = offsets[index]; int mlen; diff --git a/test/hotspot/gtest/aarch64/aarch64-asmtest.py b/test/hotspot/gtest/aarch64/aarch64-asmtest.py index e79afecd3dcfbe3fc09e9183a8b31a2cec1a8663..d43733535aec2b2f57e47916dfe05deca1bdec99 100644 --- a/test/hotspot/gtest/aarch64/aarch64-asmtest.py +++ b/test/hotspot/gtest/aarch64/aarch64-asmtest.py @@ -1571,10 +1571,10 @@ generate(SpecialCases, [["ccmn", "__ ccmn(zr, zr, 3u, Assembler::LE);", ["stxpw", "__ stxpw(r6, zr, zr, sp);", "stxp\tw6, wzr, wzr, [sp]"], ["dup", "__ dup(v0, __ T16B, zr);", "dup\tv0.16b, wzr"], ["dup", "__ dup(v0, __ S, v1);", "dup\ts0, v1.s[0]"], - ["mov", "__ mov(v1, __ T1D, 0, zr);", "mov\tv1.d[0], xzr"], - ["mov", "__ mov(v1, __ T2S, 1, zr);", "mov\tv1.s[1], wzr"], - ["mov", "__ mov(v1, __ T4H, 2, zr);", "mov\tv1.h[2], wzr"], - ["mov", "__ mov(v1, __ T8B, 3, zr);", "mov\tv1.b[3], wzr"], + ["mov", "__ mov(v1, __ D, 0, zr);", "mov\tv1.d[0], xzr"], + ["mov", "__ mov(v1, __ S, 1, zr);", "mov\tv1.s[1], wzr"], + ["mov", "__ mov(v1, __ H, 2, zr);", "mov\tv1.h[2], wzr"], + ["mov", "__ mov(v1, __ B, 3, zr);", "mov\tv1.b[3], wzr"], ["smov", "__ smov(r0, v1, __ S, 0);", "smov\tx0, v1.s[0]"], ["smov", "__ smov(r0, v1, __ H, 1);", "smov\tx0, v1.h[1]"], ["smov", "__ smov(r0, v1, __ B, 2);", "smov\tx0, v1.b[2]"], @@ -1723,9 +1723,22 @@ generate(SpecialCases, [["ccmn", "__ ccmn(zr, zr, 3u, Assembler::LE);", ["bic", "__ sve_bic(p10, p7, p9, p11);", "bic\tp10.b, p7/z, p9.b, p11.b"], ["ptest", "__ sve_ptest(p7, p1);", "ptest\tp7, p1.b"], ["ptrue", "__ sve_ptrue(p1, __ B);", "ptrue\tp1.b"], + ["ptrue", "__ sve_ptrue(p1, __ B, 0b00001);", "ptrue\tp1.b, vl1"], + ["ptrue", "__ sve_ptrue(p1, __ B, 0b00101);", "ptrue\tp1.b, vl5"], + ["ptrue", "__ sve_ptrue(p1, __ B, 0b01001);", "ptrue\tp1.b, vl16"], + ["ptrue", "__ sve_ptrue(p1, __ B, 0b01101);", "ptrue\tp1.b, vl256"], ["ptrue", "__ sve_ptrue(p2, __ H);", "ptrue\tp2.h"], + ["ptrue", "__ sve_ptrue(p2, __ H, 0b00010);", "ptrue\tp2.h, vl2"], + ["ptrue", "__ sve_ptrue(p2, __ H, 0b00110);", "ptrue\tp2.h, vl6"], + ["ptrue", "__ sve_ptrue(p2, __ H, 0b01010);", "ptrue\tp2.h, vl32"], ["ptrue", "__ sve_ptrue(p3, __ S);", "ptrue\tp3.s"], + ["ptrue", "__ sve_ptrue(p3, __ S, 0b00011);", "ptrue\tp3.s, vl3"], + ["ptrue", "__ sve_ptrue(p3, __ S, 0b00111);", "ptrue\tp3.s, vl7"], + ["ptrue", "__ sve_ptrue(p3, __ S, 0b01011);", "ptrue\tp3.s, vl64"], ["ptrue", "__ sve_ptrue(p4, __ D);", "ptrue\tp4.d"], + ["ptrue", "__ sve_ptrue(p4, __ D, 0b00100);", "ptrue\tp4.d, vl4"], + ["ptrue", "__ sve_ptrue(p4, __ D, 0b01000);", "ptrue\tp4.d, vl8"], + ["ptrue", "__ sve_ptrue(p4, __ D, 0b01100);", "ptrue\tp4.d, vl128"], ["pfalse", "__ sve_pfalse(p7);", "pfalse\tp7.b"], ["uzp1", "__ sve_uzp1(p0, __ B, p0, p1);", "uzp1\tp0.b, p0.b, p1.b"], ["uzp1", "__ sve_uzp1(p0, __ H, p0, p1);", "uzp1\tp0.h, p0.h, p1.h"], diff --git a/test/hotspot/gtest/aarch64/asmtest.out.h b/test/hotspot/gtest/aarch64/asmtest.out.h index 8bbbdc579f5da9a23a6a8bec798aeb2208320d48..4975cce511dfaff47a566855825dc986ffd323ca 100644 --- a/test/hotspot/gtest/aarch64/asmtest.out.h +++ b/test/hotspot/gtest/aarch64/asmtest.out.h @@ -713,10 +713,10 @@ __ stxpw(r6, zr, zr, sp); // stxp w6, wzr, wzr, [sp] __ dup(v0, __ T16B, zr); // dup v0.16b, wzr __ dup(v0, __ S, v1); // dup s0, v1.s[0] - __ mov(v1, __ T1D, 0, zr); // mov v1.d[0], xzr - __ mov(v1, __ T2S, 1, zr); // mov v1.s[1], wzr - __ mov(v1, __ T4H, 2, zr); // mov v1.h[2], wzr - __ mov(v1, __ T8B, 3, zr); // mov v1.b[3], wzr + __ mov(v1, __ D, 0, zr); // mov v1.d[0], xzr + __ mov(v1, __ S, 1, zr); // mov v1.s[1], wzr + __ mov(v1, __ H, 2, zr); // mov v1.h[2], wzr + __ mov(v1, __ B, 3, zr); // mov v1.b[3], wzr __ smov(r0, v1, __ S, 0); // smov x0, v1.s[0] __ smov(r0, v1, __ H, 1); // smov x0, v1.h[1] __ smov(r0, v1, __ B, 2); // smov x0, v1.b[2] @@ -864,9 +864,22 @@ __ sve_bic(p10, p7, p9, p11); // bic p10.b, p7/z, p9.b, p11.b __ sve_ptest(p7, p1); // ptest p7, p1.b __ sve_ptrue(p1, __ B); // ptrue p1.b + __ sve_ptrue(p1, __ B, 0b00001); // ptrue p1.b, vl1 + __ sve_ptrue(p1, __ B, 0b00101); // ptrue p1.b, vl5 + __ sve_ptrue(p1, __ B, 0b01001); // ptrue p1.b, vl16 + __ sve_ptrue(p1, __ B, 0b01101); // ptrue p1.b, vl256 __ sve_ptrue(p2, __ H); // ptrue p2.h + __ sve_ptrue(p2, __ H, 0b00010); // ptrue p2.h, vl2 + __ sve_ptrue(p2, __ H, 0b00110); // ptrue p2.h, vl6 + __ sve_ptrue(p2, __ H, 0b01010); // ptrue p2.h, vl32 __ sve_ptrue(p3, __ S); // ptrue p3.s + __ sve_ptrue(p3, __ S, 0b00011); // ptrue p3.s, vl3 + __ sve_ptrue(p3, __ S, 0b00111); // ptrue p3.s, vl7 + __ sve_ptrue(p3, __ S, 0b01011); // ptrue p3.s, vl64 __ sve_ptrue(p4, __ D); // ptrue p4.d + __ sve_ptrue(p4, __ D, 0b00100); // ptrue p4.d, vl4 + __ sve_ptrue(p4, __ D, 0b01000); // ptrue p4.d, vl8 + __ sve_ptrue(p4, __ D, 0b01100); // ptrue p4.d, vl128 __ sve_pfalse(p7); // pfalse p7.b __ sve_uzp1(p0, __ B, p0, p1); // uzp1 p0.b, p0.b, p1.b __ sve_uzp1(p0, __ H, p0, p1); // uzp1 p0.h, p0.h, p1.h @@ -1130,30 +1143,30 @@ 0x9101a1a0, 0xb10a5cc8, 0xd10810aa, 0xf10fd061, 0x120cb166, 0x321764bc, 0x52174681, 0x720c0227, 0x9241018e, 0xb25a2969, 0xd278b411, 0xf26aad01, - 0x14000000, 0x17ffffd7, 0x14000398, 0x94000000, - 0x97ffffd4, 0x94000395, 0x3400000a, 0x34fffa2a, - 0x3400724a, 0x35000008, 0x35fff9c8, 0x350071e8, - 0xb400000b, 0xb4fff96b, 0xb400718b, 0xb500001d, - 0xb5fff91d, 0xb500713d, 0x10000013, 0x10fff8b3, - 0x100070d3, 0x90000013, 0x36300016, 0x3637f836, - 0x36307056, 0x3758000c, 0x375ff7cc, 0x37586fec, + 0x14000000, 0x17ffffd7, 0x140003a5, 0x94000000, + 0x97ffffd4, 0x940003a2, 0x3400000a, 0x34fffa2a, + 0x340073ea, 0x35000008, 0x35fff9c8, 0x35007388, + 0xb400000b, 0xb4fff96b, 0xb400732b, 0xb500001d, + 0xb5fff91d, 0xb50072dd, 0x10000013, 0x10fff8b3, + 0x10007273, 0x90000013, 0x36300016, 0x3637f836, + 0x363071f6, 0x3758000c, 0x375ff7cc, 0x3758718c, 0x128313a0, 0x528a32c7, 0x7289173b, 0x92ab3acc, 0xd2a0bf94, 0xf2c285e8, 0x9358722f, 0x330e652f, 0x53067f3b, 0x93577c53, 0xb34a1aac, 0xd35a4016, 0x13946c63, 0x93c3dbc8, 0x54000000, 0x54fff5a0, - 0x54006dc0, 0x54000001, 0x54fff541, 0x54006d61, - 0x54000002, 0x54fff4e2, 0x54006d02, 0x54000002, - 0x54fff482, 0x54006ca2, 0x54000003, 0x54fff423, - 0x54006c43, 0x54000003, 0x54fff3c3, 0x54006be3, - 0x54000004, 0x54fff364, 0x54006b84, 0x54000005, - 0x54fff305, 0x54006b25, 0x54000006, 0x54fff2a6, - 0x54006ac6, 0x54000007, 0x54fff247, 0x54006a67, - 0x54000008, 0x54fff1e8, 0x54006a08, 0x54000009, - 0x54fff189, 0x540069a9, 0x5400000a, 0x54fff12a, - 0x5400694a, 0x5400000b, 0x54fff0cb, 0x540068eb, - 0x5400000c, 0x54fff06c, 0x5400688c, 0x5400000d, - 0x54fff00d, 0x5400682d, 0x5400000e, 0x54ffefae, - 0x540067ce, 0x5400000f, 0x54ffef4f, 0x5400676f, + 0x54006f60, 0x54000001, 0x54fff541, 0x54006f01, + 0x54000002, 0x54fff4e2, 0x54006ea2, 0x54000002, + 0x54fff482, 0x54006e42, 0x54000003, 0x54fff423, + 0x54006de3, 0x54000003, 0x54fff3c3, 0x54006d83, + 0x54000004, 0x54fff364, 0x54006d24, 0x54000005, + 0x54fff305, 0x54006cc5, 0x54000006, 0x54fff2a6, + 0x54006c66, 0x54000007, 0x54fff247, 0x54006c07, + 0x54000008, 0x54fff1e8, 0x54006ba8, 0x54000009, + 0x54fff189, 0x54006b49, 0x5400000a, 0x54fff12a, + 0x54006aea, 0x5400000b, 0x54fff0cb, 0x54006a8b, + 0x5400000c, 0x54fff06c, 0x54006a2c, 0x5400000d, + 0x54fff00d, 0x540069cd, 0x5400000e, 0x54ffefae, + 0x5400696e, 0x5400000f, 0x54ffef4f, 0x5400690f, 0xd40658e1, 0xd4014d22, 0xd4046543, 0xd4273f60, 0xd44cad80, 0xd503201f, 0xd69f03e0, 0xd6bf03e0, 0xd5033fdf, 0xd5033e9f, 0xd50332bf, 0xd61f0200, @@ -1185,7 +1198,7 @@ 0x791f226d, 0xf95aa2f3, 0xb9587bb7, 0x395f7176, 0x795d9143, 0x399e7e08, 0x799a2697, 0x79df3422, 0xb99c2624, 0xfd5c2374, 0xbd5fa1d9, 0xfd1d595a, - 0xbd1b1869, 0x580057bb, 0x1800000b, 0xf8945060, + 0xbd1b1869, 0x5800595b, 0x1800000b, 0xf8945060, 0xd8000000, 0xf8ae6ba0, 0xf99a0080, 0x1a070035, 0x3a0700a8, 0x5a0e0367, 0x7a11009b, 0x9a000380, 0xba1e030c, 0xda0f0320, 0xfa030301, 0x0b340b11, @@ -1308,58 +1321,61 @@ 0xc5b040af, 0xe57080af, 0xe5b080af, 0x25034440, 0x254054c4, 0x25034640, 0x25415a05, 0x25834440, 0x25c54489, 0x250b5d3a, 0x2550dc20, 0x2518e3e1, - 0x2558e3e2, 0x2598e3e3, 0x25d8e3e4, 0x2518e407, - 0x05214800, 0x05614800, 0x05a14800, 0x05e14800, - 0x05214c00, 0x05614c00, 0x05a14c00, 0x05e14c00, - 0x05304001, 0x05314001, 0x1e601000, 0x1e603000, - 0x1e621000, 0x1e623000, 0x1e641000, 0x1e643000, - 0x1e661000, 0x1e663000, 0x1e681000, 0x1e683000, - 0x1e6a1000, 0x1e6a3000, 0x1e6c1000, 0x1e6c3000, - 0x1e6e1000, 0x1e6e3000, 0x1e701000, 0x1e703000, - 0x1e721000, 0x1e723000, 0x1e741000, 0x1e743000, - 0x1e761000, 0x1e763000, 0x1e781000, 0x1e783000, - 0x1e7a1000, 0x1e7a3000, 0x1e7c1000, 0x1e7c3000, - 0x1e7e1000, 0x1e7e3000, 0xf8208193, 0xf83101b6, - 0xf83c13fe, 0xf821239a, 0xf824309e, 0xf826535e, - 0xf8304109, 0xf82c7280, 0xf8216058, 0xf8a08309, - 0xf8ba03d0, 0xf8a312ea, 0xf8aa21e4, 0xf8a2310b, - 0xf8aa522f, 0xf8a2418a, 0xf8ac71af, 0xf8a26287, - 0xf8fa8090, 0xf8e20184, 0xf8f01215, 0xf8f022ab, - 0xf8f7334c, 0xf8f751dc, 0xf8eb4038, 0xf8ec715f, - 0xf8f06047, 0xf863826d, 0xf8710070, 0xf86113cb, - 0xf86521e8, 0xf87d301e, 0xf8745287, 0xf87742bc, - 0xf87b70b9, 0xf8616217, 0xb83f8185, 0xb82901fc, - 0xb83d13f6, 0xb83320bf, 0xb82e33f0, 0xb830529b, - 0xb830416c, 0xb82973c6, 0xb831639b, 0xb8be8147, - 0xb8b4008a, 0xb8b81231, 0xb8b623a3, 0xb8af3276, - 0xb8b35056, 0xb8af4186, 0xb8b071ab, 0xb8b763c1, - 0xb8f38225, 0xb8e202d0, 0xb8ed12aa, 0xb8fd219b, - 0xb8fb3023, 0xb8ff5278, 0xb8f14389, 0xb8fb70ef, - 0xb8f563f7, 0xb87983e2, 0xb87b0150, 0xb8771073, - 0xb8702320, 0xb87a3057, 0xb870508c, 0xb87c43be, - 0xb87070db, 0xb86961fd, 0xce273c87, 0xce080ac9, - 0xce7e8e9b, 0xce808b45, 0xce79806e, 0xce758768, - 0xcec0835a, 0xce608ad8, 0x2520d264, 0x2521cf80, - 0x058074c1, 0x054242c9, 0x05004476, 0x25a0df08, - 0x25a1c206, 0x0583288b, 0x05401c3a, 0x05027e8d, - 0x2520ce05, 0x25a1cb0a, 0x0580989a, 0x0540e096, - 0x0500fb73, 0x2560c2ce, 0x2521d590, 0x05803e97, - 0x05400d31, 0x05003ed0, 0x2520c623, 0x25a1cdd1, - 0x058052ac, 0x0540ba33, 0x05003ed7, 0x25a0c6cd, - 0x2521cf00, 0x0583c5b1, 0x05407336, 0x05001e62, - 0x04e400f4, 0x04a80407, 0x65c402d3, 0x65cb0ac9, - 0x659007c5, 0x0456ac36, 0x04c01608, 0x049a048f, - 0x041087a8, 0x04dab3bc, 0x04590c49, 0x041380fc, - 0x0451963a, 0x04d012a8, 0x0497b6a5, 0x049eb3b6, - 0x04980093, 0x04080677, 0x040a1a77, 0x04c109c8, - 0x049cbeb1, 0x65c0815e, 0x658d812c, 0x65c69098, - 0x65c78b66, 0x65c293cd, 0x04ddb7d6, 0x6582ae69, - 0x6580bd34, 0x6581ae6d, 0x658daa78, 0x65819211, - 0x65a78160, 0x65ef108e, 0x65f52145, 0x65f34123, - 0x65b3786a, 0x04555db7, 0x049e6e3a, 0x043d304e, - 0x04a73295, 0x047a3022, 0x04f13209, 0x05e26880, - 0x05ab6cce, 0x045a33ae, 0x045822c3, 0x04193b63, - 0x04c834f3, 0x044a2cb5, 0x65c726b9, 0x65862071, - 0x65982cf3, 0x0441322e, + 0x2518e021, 0x2518e0a1, 0x2518e121, 0x2518e1a1, + 0x2558e3e2, 0x2558e042, 0x2558e0c2, 0x2558e142, + 0x2598e3e3, 0x2598e063, 0x2598e0e3, 0x2598e163, + 0x25d8e3e4, 0x25d8e084, 0x25d8e104, 0x25d8e184, + 0x2518e407, 0x05214800, 0x05614800, 0x05a14800, + 0x05e14800, 0x05214c00, 0x05614c00, 0x05a14c00, + 0x05e14c00, 0x05304001, 0x05314001, 0x1e601000, + 0x1e603000, 0x1e621000, 0x1e623000, 0x1e641000, + 0x1e643000, 0x1e661000, 0x1e663000, 0x1e681000, + 0x1e683000, 0x1e6a1000, 0x1e6a3000, 0x1e6c1000, + 0x1e6c3000, 0x1e6e1000, 0x1e6e3000, 0x1e701000, + 0x1e703000, 0x1e721000, 0x1e723000, 0x1e741000, + 0x1e743000, 0x1e761000, 0x1e763000, 0x1e781000, + 0x1e783000, 0x1e7a1000, 0x1e7a3000, 0x1e7c1000, + 0x1e7c3000, 0x1e7e1000, 0x1e7e3000, 0xf8208193, + 0xf83101b6, 0xf83c13fe, 0xf821239a, 0xf824309e, + 0xf826535e, 0xf8304109, 0xf82c7280, 0xf8216058, + 0xf8a08309, 0xf8ba03d0, 0xf8a312ea, 0xf8aa21e4, + 0xf8a2310b, 0xf8aa522f, 0xf8a2418a, 0xf8ac71af, + 0xf8a26287, 0xf8fa8090, 0xf8e20184, 0xf8f01215, + 0xf8f022ab, 0xf8f7334c, 0xf8f751dc, 0xf8eb4038, + 0xf8ec715f, 0xf8f06047, 0xf863826d, 0xf8710070, + 0xf86113cb, 0xf86521e8, 0xf87d301e, 0xf8745287, + 0xf87742bc, 0xf87b70b9, 0xf8616217, 0xb83f8185, + 0xb82901fc, 0xb83d13f6, 0xb83320bf, 0xb82e33f0, + 0xb830529b, 0xb830416c, 0xb82973c6, 0xb831639b, + 0xb8be8147, 0xb8b4008a, 0xb8b81231, 0xb8b623a3, + 0xb8af3276, 0xb8b35056, 0xb8af4186, 0xb8b071ab, + 0xb8b763c1, 0xb8f38225, 0xb8e202d0, 0xb8ed12aa, + 0xb8fd219b, 0xb8fb3023, 0xb8ff5278, 0xb8f14389, + 0xb8fb70ef, 0xb8f563f7, 0xb87983e2, 0xb87b0150, + 0xb8771073, 0xb8702320, 0xb87a3057, 0xb870508c, + 0xb87c43be, 0xb87070db, 0xb86961fd, 0xce273c87, + 0xce080ac9, 0xce7e8e9b, 0xce808b45, 0xce79806e, + 0xce758768, 0xcec0835a, 0xce608ad8, 0x2520d264, + 0x2521cf80, 0x058074c1, 0x054242c9, 0x05004476, + 0x25a0df08, 0x25a1c206, 0x0583288b, 0x05401c3a, + 0x05027e8d, 0x2520ce05, 0x25a1cb0a, 0x0580989a, + 0x0540e096, 0x0500fb73, 0x2560c2ce, 0x2521d590, + 0x05803e97, 0x05400d31, 0x05003ed0, 0x2520c623, + 0x25a1cdd1, 0x058052ac, 0x0540ba33, 0x05003ed7, + 0x25a0c6cd, 0x2521cf00, 0x0583c5b1, 0x05407336, + 0x05001e62, 0x04e400f4, 0x04a80407, 0x65c402d3, + 0x65cb0ac9, 0x659007c5, 0x0456ac36, 0x04c01608, + 0x049a048f, 0x041087a8, 0x04dab3bc, 0x04590c49, + 0x041380fc, 0x0451963a, 0x04d012a8, 0x0497b6a5, + 0x049eb3b6, 0x04980093, 0x04080677, 0x040a1a77, + 0x04c109c8, 0x049cbeb1, 0x65c0815e, 0x658d812c, + 0x65c69098, 0x65c78b66, 0x65c293cd, 0x04ddb7d6, + 0x6582ae69, 0x6580bd34, 0x6581ae6d, 0x658daa78, + 0x65819211, 0x65a78160, 0x65ef108e, 0x65f52145, + 0x65f34123, 0x65b3786a, 0x04555db7, 0x049e6e3a, + 0x043d304e, 0x04a73295, 0x047a3022, 0x04f13209, + 0x05e26880, 0x05ab6cce, 0x045a33ae, 0x045822c3, + 0x04193b63, 0x04c834f3, 0x044a2cb5, 0x65c726b9, + 0x65862071, 0x65982cf3, 0x0441322e, }; // END Generated code -- do not edit diff --git a/test/hotspot/gtest/classfile/test_AltHashing.cpp b/test/hotspot/gtest/classfile/test_AltHashing.cpp index d11dc0fb4a202c2d3271ab9f32830f1974d29bd3..0070c4fd2c12fd0b5892adb73acb1c40cc1a43fa 100644 --- a/test/hotspot/gtest/classfile/test_AltHashing.cpp +++ b/test/hotspot/gtest/classfile/test_AltHashing.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include "classfile/altHashing.hpp" #include "utilities/debug.hpp" #include "utilities/formatBuffer.hpp" +#include "utilities/globalDefinitions.hpp" #include "unittest.hpp" class AltHashingTest : public ::testing::Test { diff --git a/test/hotspot/gtest/gc/g1/test_freeRegionList.cpp b/test/hotspot/gtest/gc/g1/test_freeRegionList.cpp index 9a69816558bb71a0416613676d3b6e4cc042d649..2cf82eb403774ae7359f8f9281e6c871c2dfa28f 100644 --- a/test/hotspot/gtest/gc/g1/test_freeRegionList.cpp +++ b/test/hotspot/gtest/gc/g1/test_freeRegionList.cpp @@ -57,7 +57,7 @@ TEST_VM(FreeRegionList, length) { bot_rs.size(), os::vm_page_size(), HeapRegion::GrainBytes, - BOTConstants::N_bytes, + BOTConstants::card_size(), mtGC); G1BlockOffsetTable bot(heap, bot_storage); bot_storage->commit_regions(0, num_regions_in_test); diff --git a/test/hotspot/gtest/gc/g1/test_g1CardSetContainers.cpp b/test/hotspot/gtest/gc/g1/test_g1CardSetContainers.cpp index c2ebeadd4811979a52d0c783cd122bb9598bba1a..9283fc3303fe031a30a749fd30e7351510cfecee 100644 --- a/test/hotspot/gtest/gc/g1/test_g1CardSetContainers.cpp +++ b/test/hotspot/gtest/gc/g1/test_g1CardSetContainers.cpp @@ -240,7 +240,7 @@ TEST_VM_F(G1CardSetContainersTest, basic_cardset_inptr_test) { uint const max = (uint)log2i(HeapRegionBounds::max_size()); for (uint i = min; i <= max; i++) { - G1CardSetContainersTest::cardset_inlineptr_test(i - CardTable::card_shift); + G1CardSetContainersTest::cardset_inlineptr_test(i - CardTable::card_shift()); } } diff --git a/test/hotspot/gtest/gc/shared/test_preservedMarks.cpp b/test/hotspot/gtest/gc/shared/test_preservedMarks.cpp index 4ef7cb20d2408ffa3733ccb685c74cd3e3b54e3d..5f9a361105ec76ac381ee74ada272fb230cb6e2c 100644 --- a/test/hotspot/gtest/gc/shared/test_preservedMarks.cpp +++ b/test/hotspot/gtest/gc/shared/test_preservedMarks.cpp @@ -68,8 +68,8 @@ TEST_VM(PreservedMarks, iterate_and_restore) { ASSERT_MARK_WORD_EQ(o2.mark(), FakeOop::changedMark()); // Push o1 and o2 to have their marks preserved. - pm.push(o1.get_oop(), o1.mark()); - pm.push(o2.get_oop(), o2.mark()); + pm.push_if_necessary(o1.get_oop(), o1.mark()); + pm.push_if_necessary(o2.get_oop(), o2.mark()); // Fake a move from o1->o3 and o2->o4. o1.forward_to(o3.get_oop()); diff --git a/test/hotspot/gtest/logging/logTestUtils.inline.hpp b/test/hotspot/gtest/logging/logTestUtils.inline.hpp index 4295c6a000f2eb52726533ae56e2997e3d379578..3e49c610b4189ddfd7d345264e1769606b2f43ef 100644 --- a/test/hotspot/gtest/logging/logTestUtils.inline.hpp +++ b/test/hotspot/gtest/logging/logTestUtils.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -138,8 +138,8 @@ static inline char* read_line(FILE* fp) { static bool file_contains_substrings_in_order(const char* filename, const char* substrs[]) { AsyncLogWriter::flush(); - FILE* fp = fopen(filename, "r"); - assert(fp != NULL, "error opening file %s: %s", filename, strerror(errno)); + FILE* fp = os::fopen(filename, "r"); + assert(fp != NULL, "error opening file %s: %s", filename, os::strerror(errno)); size_t idx = 0; while (substrs[idx] != NULL) { diff --git a/test/hotspot/gtest/logging/test_asynclog.cpp b/test/hotspot/gtest/logging/test_asynclog.cpp index ffabbb524c2b2bd40f8163e08c9a902732d5995e..16bdd6e18c72440a93796fffa6b397f272df7f37 100644 --- a/test/hotspot/gtest/logging/test_asynclog.cpp +++ b/test/hotspot/gtest/logging/test_asynclog.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,6 +67,38 @@ LOG_LEVEL_LIST log_trace(logging)("log_trace-test"); log_debug(logging)("log_debug-test"); } + + void test_asynclog_drop_messages() { + if (AsyncLogWriter::instance() != nullptr) { + const size_t sz = 100; + + // shrink async buffer. + AutoModifyRestore<size_t> saver(AsyncLogBufferSize, sz * 1024 /*in byte*/); + LogMessage(logging) lm; + + // write 100x more messages than its capacity in burst + for (size_t i = 0; i < sz * 100; ++i) { + lm.debug("a lot of log..."); + } + lm.flush(); + } + } + + // stdout/stderr support + bool write_to_file(const std::string& output) { + FILE* f = os::fopen(TestLogFileName, "w"); + + if (f != NULL) { + size_t sz = output.size(); + size_t written = fwrite(output.c_str(), sizeof(char), output.size(), f); + + if (written == sz * sizeof(char)) { + return fclose(f) == 0; + } + } + + return false; + } }; TEST_VM(AsyncLogBufferTest, fifo) { @@ -198,19 +231,48 @@ TEST_VM_F(AsyncLogTest, logMessage) { TEST_VM_F(AsyncLogTest, droppingMessage) { set_log_config(TestLogFileName, "logging=debug"); - const size_t sz = 100; + test_asynclog_drop_messages(); + AsyncLogWriter::flush(); if (AsyncLogWriter::instance() != nullptr) { - // shrink async buffer. - AutoModifyRestore<size_t> saver(AsyncLogBufferSize, sz * 1024 /*in byte*/); - LogMessage(logging) lm; + EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging")); + } +} - // write 100x more messages than its capacity in burst - for (size_t i = 0; i < sz * 100; ++i) { - lm.debug("a lot of log..."); - } - lm.flush(); - AsyncLogWriter::flush(); +TEST_VM_F(AsyncLogTest, stdoutOutput) { + testing::internal::CaptureStdout(); + set_log_config("stdout", "logging=debug"); + + test_asynclog_ls(); + test_asynclog_drop_messages(); + + AsyncLogWriter::flush(); + EXPECT_TRUE(write_to_file(testing::internal::GetCapturedStdout())); + + EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline")); + + if (AsyncLogWriter::instance() != nullptr) { + EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging")); + } +} + +TEST_VM_F(AsyncLogTest, stderrOutput) { + testing::internal::CaptureStderr(); + set_log_config("stderr", "logging=debug"); + + test_asynclog_ls(); + test_asynclog_drop_messages(); + + AsyncLogWriter::flush(); + EXPECT_TRUE(write_to_file(testing::internal::GetCapturedStderr())); + + EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline")); + + if (AsyncLogWriter::instance() != nullptr) { EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging")); } } diff --git a/test/hotspot/gtest/logging/test_log.cpp b/test/hotspot/gtest/logging/test_log.cpp index ccd928474d438ef339471395bb7907290d4d39a6..7ae276aad376851744d6020a04897b3eb5041bd1 100644 --- a/test/hotspot/gtest/logging/test_log.cpp +++ b/test/hotspot/gtest/logging/test_log.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ TEST_VM_F(LogTest, large_message) { AsyncLogWriter::flush(); ResourceMark rm; - FILE* fp = fopen(TestLogFileName, "r"); + FILE* fp = os::fopen(TestLogFileName, "r"); ASSERT_NE((void*)NULL, fp); char* output = read_line(fp); fclose(fp); diff --git a/test/hotspot/gtest/logging/test_logTagSetDescriptions.cpp b/test/hotspot/gtest/logging/test_logTagSetDescriptions.cpp index 7cb37ff43498f05f7287442c4428217aab8d4bce..84253e19433786937a64aef8cebe056711106d27 100644 --- a/test/hotspot/gtest/logging/test_logTagSetDescriptions.cpp +++ b/test/hotspot/gtest/logging/test_logTagSetDescriptions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ TEST_VM(LogTagSetDescriptions, describe) { TEST_VM(LogTagSetDescriptions, command_line_help) { ResourceMark rm; const char* filename = prepend_temp_dir("logtagset_descriptions"); - FILE* fp = fopen(filename, "w+"); + FILE* fp = os::fopen(filename, "w+"); ASSERT_NE((void*)NULL, fp); fileStream stream(fp); LogConfiguration::print_command_line_help(&stream); diff --git a/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp b/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp index c1aeb3e845ced23769ca0eb17ccc5abd912225a3..ce30fb8d61d71751bf98be76c32abf7106728f30 100644 --- a/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp +++ b/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022 SAP SE. All rights reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,14 +31,10 @@ #include "unittest.hpp" #include "testutils.hpp" -#if INCLUDE_NMT - // This prefix shows up on any c heap corruption NMT detects. If unsure which assert will // come, just use this one. #define COMMON_NMT_HEAP_CORRUPTION_MESSAGE_PREFIX "NMT corruption" - - #define DEFINE_TEST(test_function, expected_assertion_message) \ TEST_VM_FATAL_ERROR_MSG(NMT, test_function, ".*" expected_assertion_message ".*") { \ if (MemTracker::tracking_level() > NMT_off) { \ @@ -165,5 +161,3 @@ TEST_VM(NMT, test_realloc) { } } } - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/nmt/test_nmtpreinit.cpp b/test/hotspot/gtest/nmt/test_nmtpreinit.cpp index 310cbb187b2fe3c393a80c92f47ed260c48210f9..6475e86570881fac7da9c12737066c417e631f3a 100644 --- a/test/hotspot/gtest/nmt/test_nmtpreinit.cpp +++ b/test/hotspot/gtest/nmt/test_nmtpreinit.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 SAP SE. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,8 +54,6 @@ // us. So inside that scope VM initialization ran and with it the NMT initialization. // To be sure, we assert those assumptions. -#if INCLUDE_NMT - // Some shorts to save writing out the flags every time static void* os_malloc(size_t s) { return os::malloc(s, mtTest); } static void* os_realloc(void* old, size_t s) { return os::realloc(old, s, mtTest); } @@ -127,5 +125,3 @@ TEST_VM(NMTPreInit, pre_to_post_allocs) { g_test_allocations.test_post(); g_test_allocations.free_all(); } - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp b/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp index 356c79a8d4a08cfeed10a0cef368b679a749f988..e68d5ca069aae2f8f9e7a8d45c427cf95aa9600c 100644 --- a/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp +++ b/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 SAP SE. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,8 +31,6 @@ #include "utilities/ostream.hpp" #include "unittest.hpp" -#if INCLUDE_NMT - // This tests the NMTPreInitAllocationTable hash table used to store C-heap allocations before NMT initialization ran. static size_t small_random_nonzero_size() { @@ -132,5 +130,3 @@ TEST_VM_ASSERT_MSG(NMTPreInit, assert_on_lu_table_overflow, ".*NMT preinit looku table.verify(); } #endif // ASSERT - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp b/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp index 0abc004a93542aaba5a9f5f21ff8cdba357312e5..b95b86c1247b19eaae31627a61217e19b1771d02 100644 --- a/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp +++ b/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ // Included early because the NMT flags don't include it. #include "utilities/macros.hpp" -#if INCLUDE_NMT - #include "runtime/thread.hpp" #include "services/memTracker.hpp" #include "services/virtualMemoryTracker.hpp" @@ -223,5 +221,3 @@ TEST_VM(CommittedVirtualMemoryTracker, test_committed_virtualmemory_region) { } } - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/runtime/test_os.cpp b/test/hotspot/gtest/runtime/test_os.cpp index 1c8ed269b54c28a03de783d662ed14dc722a6f7a..a0859e7e2960263daf6eeb02c791fe2329f2ea5e 100644 --- a/test/hotspot/gtest/runtime/test_os.cpp +++ b/test/hotspot/gtest/runtime/test_os.cpp @@ -351,6 +351,23 @@ TEST_VM(os, jio_snprintf) { test_snprintf(jio_snprintf, false); } +#ifdef __APPLE__ +// Not all macOS versions can use os::reserve_memory (i.e. anon_mmap) API +// to reserve executable memory, so before attempting to use it, +// we need to verify that we can do so by asking for a tiny executable +// memory chunk. +static inline bool can_reserve_executable_memory(void) { + bool executable = true; + size_t len = 128; + char* p = os::reserve_memory(len, executable); + bool exec_supported = (p != NULL); + if (exec_supported) { + os::release_memory(p, len); + } + return exec_supported; +} +#endif + // Test that os::release_memory() can deal with areas containing multiple mappings. #define PRINT_MAPPINGS(s) { tty->print_cr("%s", s); os::print_memory_mappings((char*)p, total_range_len, tty); } //#define PRINT_MAPPINGS @@ -360,6 +377,13 @@ TEST_VM(os, jio_snprintf) { // (from multiple calls to os::reserve_memory) static address reserve_multiple(int num_stripes, size_t stripe_len) { assert(is_aligned(stripe_len, os::vm_allocation_granularity()), "Sanity"); + +#ifdef __APPLE__ + // Workaround: try reserving executable memory to figure out + // if such operation is supported on this macOS version + const bool exec_supported = can_reserve_executable_memory(); +#endif + size_t total_range_len = num_stripes * stripe_len; // Reserve a large contiguous area to get the address space... address p = (address)os::reserve_memory(total_range_len); @@ -371,7 +395,11 @@ static address reserve_multiple(int num_stripes, size_t stripe_len) { address q = p + (stripe * stripe_len); // Commit, alternatingly with or without exec permission, // to prevent kernel from folding these mappings. +#ifdef __APPLE__ + const bool executable = exec_supported ? (stripe % 2 == 0) : false; +#else const bool executable = stripe % 2 == 0; +#endif q = (address)os::attempt_reserve_memory_at((char*)q, stripe_len, executable); EXPECT_NE(q, (address)NULL); EXPECT_TRUE(os::commit_memory((char*)q, stripe_len, executable)); @@ -413,11 +441,7 @@ struct NUMASwitcher { #endif #ifndef _AIX // JDK-8257041 -#if defined(__APPLE__) && !defined(AARCH64) // See JDK-8267341. - TEST_VM(os, DISABLED_release_multi_mappings) { -#else TEST_VM(os, release_multi_mappings) { -#endif // With NMT enabled, this will trigger JDK-8263464. For now disable the test if NMT=on. if (MemTracker::tracking_level() > NMT_off) { diff --git a/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp b/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp index ae4457f3e9358e5b52ae17b65c14b5275dbfa0ce..4aa058dc160e3c70059801f52d6671380d9a0436 100644 --- a/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp +++ b/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * 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,16 +32,13 @@ #include "precompiled.hpp" -// Included early because the NMT flags don't include it. -#include "utilities/macros.hpp" - -#if INCLUDE_NMT - #include "memory/virtualspace.hpp" #include "services/memTracker.hpp" #include "services/virtualMemoryTracker.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" #include "unittest.hpp" + #include <stdio.h> // #define LOG(...) printf(__VA_ARGS__); printf("\n"); fflush(stdout); @@ -566,5 +563,3 @@ TEST_VM(NMT_VirtualMemoryTracker, remove_uncommitted_region) { tty->print_cr("skipped."); } } - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/threadHelper.inline.hpp b/test/hotspot/gtest/threadHelper.inline.hpp index 52c044850e8def28e7bbd07506b8b67c2e495a60..3c6b951df0a208055ec5d65e60f572d25e54e267 100644 --- a/test/hotspot/gtest/threadHelper.inline.hpp +++ b/test/hotspot/gtest/threadHelper.inline.hpp @@ -49,13 +49,13 @@ static void startTestThread(JavaThread* thread, const char* name) { } } -class VM_StopSafepoint : public VM_Operation { +class VM_GTestStopSafepoint : public VM_Operation { public: Semaphore* _running; Semaphore* _test_complete; - VM_StopSafepoint(Semaphore* running, Semaphore* wait_for) : + VM_GTestStopSafepoint(Semaphore* running, Semaphore* wait_for) : _running(running), _test_complete(wait_for) {} - VMOp_Type type() const { return VMOp_None; } + VMOp_Type type() const { return VMOp_GTestStopSafepoint; } bool evaluate_at_safepoint() const { return false; } void doit() { _running->signal(); _test_complete->wait(); } }; @@ -67,7 +67,7 @@ class VMThreadBlocker : public JavaThread { static void blocker_thread_entry(JavaThread* thread, TRAPS) { VMThreadBlocker* t = static_cast<VMThreadBlocker*>(thread); - VM_StopSafepoint ss(&t->_ready, &t->_unblock); + VM_GTestStopSafepoint ss(&t->_ready, &t->_unblock); VMThread::execute(&ss); } diff --git a/test/hotspot/jtreg/ProblemList-Xcomp.txt b/test/hotspot/jtreg/ProblemList-Xcomp.txt index dab2ab3326f37a7afe54f13cabfb4c078253377b..23f25da41d0aa997b30f091c8c4bc56f3a244c31 100644 --- a/test/hotspot/jtreg/ProblemList-Xcomp.txt +++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt @@ -27,8 +27,6 @@ # ############################################################################# -compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java 8268033 generic-x64 - vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 generic-all vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 linux-x64,windows-x64 @@ -37,4 +35,3 @@ vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 82456 serviceability/sa/TestJhsdbJstackMixed.java 8248675 linux-aarch64 -compiler/codegen/aes/TestAESMain.java 8274323 linux-x64,windows-x64 diff --git a/test/hotspot/jtreg/ProblemList-zgc.txt b/test/hotspot/jtreg/ProblemList-zgc.txt index 5a92dbd5daac05055f006c92776f7649757d0cae..5976517630f09f813666656841a12a95f43ad8ee 100644 --- a/test/hotspot/jtreg/ProblemList-zgc.txt +++ b/test/hotspot/jtreg/ProblemList-zgc.txt @@ -27,8 +27,6 @@ # ############################################################################# -vmTestbase/jit/escape/AdaptiveBlocking/AdaptiveBlocking001/AdaptiveBlocking001.java 8260303 windows-x64 - resourcehogs/serviceability/sa/TestHeapDumpForLargeArray.java 8276539 generic-all serviceability/sa/CDSJMapClstats.java 8276539 generic-all serviceability/sa/ClhsdbJhisto.java 8276539 generic-all diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 696385cad23d03b9999dbd8b9ca122dd5c013f55..e08217cd776225763a835cb44cc4bbebca2e9487 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,7 @@ compiler/whitebox/ClearMethodStateTest.java 8265360 macosx-aarch64 compiler/whitebox/EnqueueMethodForCompilationTest.java 8265360 macosx-aarch64 compiler/whitebox/MakeMethodNotCompilableTest.java 8265360 macosx-aarch64 -compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-x64 +compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-generic compiler/codecache/TestStressCodeBuffers.java 8272094 generic-aarch64 @@ -121,10 +121,10 @@ serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64 serviceability/sa/ClhsdbCDSCore.java 8269982,8267433 macosx-aarch64,macosx-x64 serviceability/sa/ClhsdbFindPC.java#xcomp-core 8269982,8267433 macosx-aarch64,macosx-x64 serviceability/sa/ClhsdbFindPC.java#no-xcomp-core 8269982,8267433 macosx-aarch64,macosx-x64 -serviceability/sa/ClhsdbPmap.java#core 8267433 macosx-x64 +serviceability/sa/ClhsdbPmap.java#core 8269982,8267433 macosx-aarch64,macosx-x64 serviceability/sa/ClhsdbPstack.java#core 8269982,8267433 macosx-aarch64,macosx-x64 -serviceability/sa/TestJmapCore.java 8267433 macosx-x64 -serviceability/sa/TestJmapCoreMetaspace.java 8267433 macosx-x64 +serviceability/sa/TestJmapCore.java 8269982,8267433 macosx-aarch64,macosx-x64 +serviceability/sa/TestJmapCoreMetaspace.java 8269982,8267433 macosx-aarch64,macosx-x64 ############################################################################# diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 9ca2a042577fcb2bacbbb41e51dd238143f82aba..dece67b5474d30febbd1354d270845bba236ca9a 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -46,6 +46,10 @@ hotspot_gc = \ hotspot_runtime = \ runtime +hotspot_runtime_no_cds = \ + runtime \ + -runtime/cds + hotspot_handshake = \ runtime/handshake @@ -71,6 +75,13 @@ hotspot_native_sanity = \ hotspot_containers = \ containers +# Test sets for running inside container environment +hotspot_containers_extended = \ + runtime \ + serviceability \ + vmTestbase/nsk/jvmti \ + vmTestbase/nsk/monitoring + hotspot_vector_1 = \ compiler/c2/cr6340864 \ compiler/codegen \ @@ -94,6 +105,9 @@ hotspot_vector_2 = \ compiler/vectorapi/VectorRebracket128Test.java \ -compiler/intrinsics/string/TestStringLatin1IndexOfChar.java +hotspot_compiler_arraycopy = \ + compiler/arraycopy/stress + tier1_common = \ sanity/BasicVMTest.java \ gtest/GTestWrapper.java \ @@ -115,7 +129,8 @@ hotspot_not_fast_compiler = \ hotspot_slow_compiler = \ compiler/codegen/aes \ compiler/codecache/stress \ - compiler/gcbarriers/PreserveFPRegistersTest.java + compiler/gcbarriers/PreserveFPRegistersTest.java \ + :hotspot_compiler_arraycopy tier1_compiler_1 = \ compiler/arraycopy/ \ @@ -132,6 +147,7 @@ tier1_compiler_1 = \ -compiler/c2/Test6792161.java \ -compiler/c2/Test6603011.java \ -compiler/c2/Test6912517.java \ + -:hotspot_slow_compiler tier1_compiler_2 = \ compiler/classUnloading/ \ @@ -372,6 +388,8 @@ hotspot_cds = \ runtime/cds/ \ runtime/CompressedOops/ +hotspot_cds_only = \ + runtime/cds/ hotspot_appcds_dynamic = \ runtime/cds/appcds/ \ @@ -393,6 +411,7 @@ hotspot_appcds_dynamic = \ -runtime/cds/appcds/BadBSM.java \ -runtime/cds/appcds/DumpClassList.java \ -runtime/cds/appcds/DumpClassListWithLF.java \ + -runtime/cds/appcds/DumpingWithNoCoops.java \ -runtime/cds/appcds/ExtraSymbols.java \ -runtime/cds/appcds/LambdaContainsOldInf.java \ -runtime/cds/appcds/LambdaEagerInit.java \ diff --git a/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java b/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java new file mode 100644 index 0000000000000000000000000000000000000000..e2bc9bfdd16d96175e2bbe89dae59c72ca207cfc --- /dev/null +++ b/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8279125 + * @summary fatal error: no reachable node should have no use + * @requires vm.flavor == "server" + * + * @run main/othervm -XX:-BackgroundCompilation -XX:-DoEscapeAnalysis TestAllocArrayAfterAllocNoUse + * + */ + +public class TestAllocArrayAfterAllocNoUse { + private static Object field; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(); + } + } + + private static void test() { + try { + final TestAllocArrayAfterAllocNoUse o = new TestAllocArrayAfterAllocNoUse(); + } catch (Exception e) { + final int[] array = new int[100]; + field = array; + } + + } +} diff --git a/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java b/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java new file mode 100644 index 0000000000000000000000000000000000000000..9e312a7953031383422e2e9f391130220e0dd9dd --- /dev/null +++ b/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8279062 + * @summary C2: assert(t->meet(t0) == t) failed: Not monotonic after JDK-8278413 + * + * @run main/othervm -XX:-BackgroundCompilation TestCCPAllocateArray + * + */ + +public class TestCCPAllocateArray { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + try { + test(); + } catch (OutOfMemoryError e) { + } + length(42); + } + } + + private static int[] test() { + int i = 2; + for (; i < 4; i *= 2); + return new int[length(i)]; + } + + private static int length(int i) { + return i == 4 ? Integer.MAX_VALUE : 0; + } +} diff --git a/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java b/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java new file mode 100644 index 0000000000000000000000000000000000000000..bd720a9b4f1bfe35b28fdb0925a2a473706c5bf1 --- /dev/null +++ b/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8279219 + * @summary C2 crash when allocating array of size too large + * @library /test/lib / + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -ea -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestFailedAllocationBadGraph + */ + +import sun.hotspot.WhiteBox; +import java.lang.reflect.Method; +import compiler.whitebox.CompilerWhiteBoxTest; + +public class TestFailedAllocationBadGraph { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + private static long[] array; + private static int field; + private static volatile int barrier; + + public static void main(String[] args) throws Exception { + run("test1"); + run("test2"); + } + + private static void run(String method) throws Exception { + Method m = TestFailedAllocationBadGraph.class.getDeclaredMethod(method); + WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); + if (!WHITE_BOX.isMethodCompiled(m) || WHITE_BOX.getMethodCompilationLevel(m) != CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) { + throw new RuntimeException("should still be compiled"); + } + } + + private static int test1() { + int length = Integer.MAX_VALUE; + try { + array = new long[length]; + } catch (OutOfMemoryError outOfMemoryError) { + barrier = 0x42; + length = field; + } + return length; + } + + private static int test2() { + int length = -1; + try { + array = new long[length]; + } catch (OutOfMemoryError outOfMemoryError) { + barrier = 0x42; + length = field; + } + return length; + } +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/AbstractStressArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/AbstractStressArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..f74c9b9cfcc6971a27325c56aff3387c2485f0a7 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/AbstractStressArrayCopy.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Random; + +public abstract class AbstractStressArrayCopy { + /** + * Max array size to test. This should be reasonably high to test + * massive vectorized copies, plus cases that cross the cache lines and + * (small) page boundaries. But it should also be reasonably low to + * keep the test costs down. + * + * A rough guideline: + * - AVX-512: 64-byte copies over 32 registers copies roughly 2K per step. + * - AArch64: small pages can be about 64K large + */ + static final int MAX_SIZE = 128*1024 + 1; + + /** + * Arrays up to this size would be tested exhaustively: with all combinations + * of source/destination starts and copy lengths. Exercise restraint when bumping + * this value, as the test costs are proportional to N^3 of this setting. + */ + static final int EXHAUSTIVE_SIZES = Integer.getInteger("exhaustiveSizes", 192); + + /* + * Larger arrays would fuzzed with this many attempts. + */ + static final int FUZZ_COUNT = Integer.getInteger("fuzzCount", 300); + + public static void throwSeedError(int len, int pos) { + throw new RuntimeException("Error after seed: " + + len + " elements, at pos " + pos); + } + + public static void throwContentsError(int l, int r, int len, int pos) { + throwError("in contents", l, r, len, pos); + } + + public static void throwHeadError(int l, int r, int len, int pos) { + throwError("in head", l, r, len, pos); + } + + public static void throwTailError(int l, int r, int len, int pos) { + throwError("in tail", l, r, len, pos); + } + + private static void throwError(String phase, int l, int r, int len, int pos) { + throw new RuntimeException("Error " + phase + ": " + + len + " elements, " + + "[" + l + ", " + (l+len) + ") -> " + + "[" + r + ", " + (r+len) + "), " + + "at pos " + pos); + } + + protected abstract void testWith(int size, int l, int r, int len); + + private void checkBounds(int size, int l, int r, int len) { + if (l >= size) throw new IllegalStateException("l is out of bounds"); + if (l + len > size) throw new IllegalStateException("l+len is out of bounds"); + if (r >= size) throw new IllegalStateException("r is out of bounds"); + if (r + len > size) throw new IllegalStateException("r+len is out of bounds: " + l + " " + r + " " + len + " " + size); + } + + private void checkDisjoint(int size, int l, int r, int len) { + if (l == r) throw new IllegalStateException("Not disjoint: l == r"); + if (l < r && l + len > r) throw new IllegalStateException("Not disjoint"); + if (l > r && r + len > l) throw new IllegalStateException("Not disjoint"); + } + + private void checkConjoint(int size, int l, int r, int len) { + if (l == r) return; // Definitely conjoint, even with zero len + if (l < r && l + len < r) throw new IllegalStateException("Not conjoint"); + if (l > r && r + len < l) throw new IllegalStateException("Not conjoint"); + } + + public void exhaustiveWith(int size) { + for (int l = 0; l < size; l++) { + for (int r = 0; r < size; r++) { + int maxLen = Math.min(size - l, size - r); + for (int len = 0; len <= maxLen; len++) { + checkBounds(size, l, r, len); + testWith(size, l, r, len); + } + } + } + } + + public void fuzzWith(Random rand, int size) { + // Some basic checks first + testWith(size, 0, 1, 1); + testWith(size, 0, 1, size-1); + + // Test disjoint: + for (int c = 0; c < FUZZ_COUNT; c++) { + int l = rand.nextInt(size / 2); + int len = rand.nextInt((size - l) / 2); + int r = (l + len + 1) + rand.nextInt(size - 2*len - l - 1); + + checkBounds(size, l, r, len); + checkDisjoint(size, l, r, len); + + testWith(size, l, r, len); + testWith(size, r, l, len); + } + + // Test conjoint: + for (int c = 0; c < FUZZ_COUNT; c++) { + int l = rand.nextInt(size); + int len = rand.nextInt(size - l); + int r = Math.min(l + (len > 0 ? rand.nextInt(len) : 0), size - len); + + checkBounds(size, l, r, len); + checkConjoint(size, l, r, len); + + testWith(size, l, r, len); + testWith(size, r, l, len); + } + } + + public void run(Random rand) { + // Exhaustive on all small arrays + for (int size = 1; size <= EXHAUSTIVE_SIZES; size++) { + exhaustiveWith(size); + } + + // Fuzz powers of ten + for (int size = 10; size < MAX_SIZE; size *= 10) { + if (size <= EXHAUSTIVE_SIZES) continue; + fuzzWith(rand, size - 1); + fuzzWith(rand, size); + fuzzWith(rand, size + 1); + } + + // Fuzz powers of two + for (int size = 2; size < MAX_SIZE; size *= 2) { + if (size <= EXHAUSTIVE_SIZES) continue; + fuzzWith(rand, size - 1); + fuzzWith(rand, size); + fuzzWith(rand, size + 1); + } + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressBooleanArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressBooleanArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..bd424c393d85d751da3c88acc8f9d3ff292ffa2f --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressBooleanArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressBooleanArrayCopy extends AbstractStressArrayCopy { + + private static final boolean[] orig = new boolean[MAX_SIZE]; + private static final boolean[] test = new boolean[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = rand.nextBoolean(); + } + new StressBooleanArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressByteArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressByteArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..86d957bf2cb52f6a926cb4a998751046af0bf508 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressByteArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressByteArrayCopy extends AbstractStressArrayCopy { + + private static final byte[] orig = new byte[MAX_SIZE]; + private static final byte[] test = new byte[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = (byte)rand.nextInt(); + } + new StressByteArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressCharArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressCharArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..0770f4aa4881c90d92696d4d8960ab4c8ce395f1 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressCharArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressCharArrayCopy extends AbstractStressArrayCopy { + + private static final char[] orig = new char[MAX_SIZE]; + private static final char[] test = new char[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = (char)rand.nextInt(); + } + new StressCharArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressDoubleArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressDoubleArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..c0cb54ca9694e537e914cd10c3a861abf9b11055 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressDoubleArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressDoubleArrayCopy extends AbstractStressArrayCopy { + + private static final double[] orig = new double[MAX_SIZE]; + private static final double[] test = new double[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = rand.nextDouble(); + } + new StressDoubleArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressFloatArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressFloatArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..d5c10570f373f4beed659f78b0edb3c587cd7bf3 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressFloatArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressFloatArrayCopy extends AbstractStressArrayCopy { + + private static final float[] orig = new float[MAX_SIZE]; + private static final float[] test = new float[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = rand.nextFloat(); + } + new StressFloatArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressIntArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressIntArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..3cad6ce8793fce4c842d7a590b5f68a1e197ad17 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressIntArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressIntArrayCopy extends AbstractStressArrayCopy { + + private static final int[] orig = new int[MAX_SIZE]; + private static final int[] test = new int[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = rand.nextInt(); + } + new StressIntArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressLongArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressLongArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..988e8ad56f9f02298abe3828b5c5ffe3cc708a2a --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressLongArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressLongArrayCopy extends AbstractStressArrayCopy { + + private static final long[] orig = new long[MAX_SIZE]; + private static final long[] test = new long[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = rand.nextLong(); + } + new StressLongArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressObjectArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressObjectArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..562daa4a820e21a8be2f8746c69f9438da2bce1a --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressObjectArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressObjectArrayCopy extends AbstractStressArrayCopy { + + private static final Object[] orig = new Object[MAX_SIZE]; + private static final Object[] test = new Object[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = new Object(); + } + new StressObjectArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/StressShortArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/StressShortArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..1594d54ca3653570f6a37211f9f71fe4942753ca --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/StressShortArrayCopy.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.Arrays; +import java.util.Random; +import jdk.test.lib.Utils; + +public class StressShortArrayCopy extends AbstractStressArrayCopy { + + private static final short[] orig = new short[MAX_SIZE]; + private static final short[] test = new short[MAX_SIZE]; + + protected void testWith(int size, int l, int r, int len) { + // Seed the test from the original + System.arraycopy(orig, 0, test, 0, size); + + // Check the seed is correct + { + int m = Arrays.mismatch(test, 0, size, + orig, 0, size); + if (m != -1) { + throwSeedError(size, m); + } + } + + // Perform the tested copy + System.arraycopy(test, l, test, r, len); + + // Check the copy has proper contents + { + int m = Arrays.mismatch(test, r, r+len, + orig, l, l+len); + if (m != -1) { + throwContentsError(l, r, len, r+m); + } + } + + // Check anything else was not affected: head and tail + { + int m = Arrays.mismatch(test, 0, r, + orig, 0, r); + if (m != -1) { + throwHeadError(l, r, len, m); + } + } + { + int m = Arrays.mismatch(test, r + len, size, + orig, r + len, size); + if (m != -1) { + throwTailError(l, r, len, m); + } + } + } + + public static void main(String... args) { + Random rand = Utils.getRandomInstance(); + for (int c = 0; c < orig.length; c++) { + orig[c] = (short)rand.nextInt(); + } + new StressShortArrayCopy().run(rand); + } + +} diff --git a/test/hotspot/jtreg/compiler/arraycopy/stress/TestStressArrayCopy.java b/test/hotspot/jtreg/compiler/arraycopy/stress/TestStressArrayCopy.java new file mode 100644 index 0000000000000000000000000000000000000000..5153f85c9d7099246f3638f11fc84a5304310825 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arraycopy/stress/TestStressArrayCopy.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.arraycopy.stress; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import jdk.test.lib.Platform; +import jdk.test.lib.Utils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import jdk.test.whitebox.cpuinfo.CPUInfo; + +/** + * @test + * @key stress randomness + * @library /test/lib + * @build compiler.arraycopy.stress.AbstractStressArrayCopy + * compiler.arraycopy.stress.StressBooleanArrayCopy + * compiler.arraycopy.stress.StressByteArrayCopy + * compiler.arraycopy.stress.StressCharArrayCopy + * compiler.arraycopy.stress.StressShortArrayCopy + * compiler.arraycopy.stress.StressIntArrayCopy + * compiler.arraycopy.stress.StressFloatArrayCopy + * compiler.arraycopy.stress.StressLongArrayCopy + * compiler.arraycopy.stress.StressDoubleArrayCopy + * compiler.arraycopy.stress.StressObjectArrayCopy + * jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * + * @run main/othervm/timeout=7200 + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * compiler.arraycopy.stress.TestStressArrayCopy + */ +public class TestStressArrayCopy { + + // These tests are remarkably memory bandwidth hungry. Running multiple + // configs in parallel makes sense only when running a single test in + // isolation, and only on machines with many memory channels. In common + // testing, or even running all arraycopy stress tests at once, overloading + // the system with many configs become counter-productive very quickly. + // + // Default to 1/4 of the CPUs, and allow users to override. + static final int MAX_PARALLELISM = Integer.getInteger("maxParallelism", + Math.max(1, Runtime.getRuntime().availableProcessors() / 4)); + + private static List<String> mix(List<String> o, String... mix) { + List<String> n = new ArrayList<>(o); + for (String m : mix) { + n.add(m); + } + return n; + } + + private static List<List<String>> product(List<List<String>> list, String... mix) { + List<List<String>> newList = new ArrayList<>(); + for (List<String> c : list) { + for (String m : mix) { + newList.add(mix(c, m)); + } + } + return newList; + } + + private static List<List<String>> alternate(List<List<String>> list, String opt) { + return product(list, "-XX:+" + opt, "-XX:-" + opt); + } + + private static boolean containsFuzzy(List<String> list, String sub) { + for (String s : list) { + if (s.contains(sub)) return true; + } + return false; + } + + public static void main(String... args) throws Exception { + List<List<String>> configs = new ArrayList<>(); + List<String> cpuFeatures = CPUInfo.getFeatures(); + + if (Platform.isX64() || Platform.isX86()) { + // If CPU features were not found, provide a default config. + if (cpuFeatures.isEmpty()) { + configs.add(new ArrayList()); + } + + // Otherwise, select the tests that make sense on current platform. + if (containsFuzzy(cpuFeatures, "avx512")) { + configs.add(List.of("-XX:UseAVX=3")); + } + if (containsFuzzy(cpuFeatures, "avx2")) { + configs.add(List.of("-XX:UseAVX=2")); + } + if (containsFuzzy(cpuFeatures, "avx")) { + configs.add(List.of("-XX:UseAVX=1")); + } + if (containsFuzzy(cpuFeatures, "sse4")) { + configs.add(List.of("-XX:UseAVX=0", "-XX:UseSSE=4")); + } + if (containsFuzzy(cpuFeatures, "sse3")) { + configs.add(List.of("-XX:UseAVX=0", "-XX:UseSSE=3")); + } + if (containsFuzzy(cpuFeatures, "sse2")) { + configs.add(List.of("-XX:UseAVX=0", "-XX:UseSSE=2")); + } + + // x86_64 always has UseSSE >= 2. These lower configurations only + // make sense for x86_32. + if (Platform.isX86()) { + if (containsFuzzy(cpuFeatures, "sse")) { + configs.add(List.of("-XX:UseAVX=0", "-XX:UseSSE=1")); + } + + configs.add(List.of("-XX:UseAVX=0", "-XX:UseSSE=0")); + } + + // Alternate configs with other flags + if (Platform.isX64()) { + configs = alternate(configs, "UseCompressedOops"); + } + configs = alternate(configs, "UseUnalignedLoadStores"); + + } else if (Platform.isAArch64()) { + // AArch64. + configs.add(new ArrayList()); + + // Alternate configs with other flags + configs = alternate(configs, "UseCompressedOops"); + configs = alternate(configs, "UseSIMDForMemoryOps"); + } else { + // Generic config. + configs.add(new ArrayList()); + } + + String[] classNames = { + "compiler.arraycopy.stress.StressBooleanArrayCopy", + "compiler.arraycopy.stress.StressByteArrayCopy", + "compiler.arraycopy.stress.StressCharArrayCopy", + "compiler.arraycopy.stress.StressShortArrayCopy", + "compiler.arraycopy.stress.StressIntArrayCopy", + "compiler.arraycopy.stress.StressFloatArrayCopy", + "compiler.arraycopy.stress.StressLongArrayCopy", + "compiler.arraycopy.stress.StressDoubleArrayCopy", + "compiler.arraycopy.stress.StressObjectArrayCopy", + }; + + ArrayList<Fork> forks = new ArrayList<>(); + int jobs = 0; + + for (List<String> c : configs) { + for (String className : classNames) { + // Start a new job + { + ProcessBuilder pb = ProcessTools.createTestJvm(mix(c, "-Xmx256m", className)); + Process p = pb.start(); + OutputAnalyzer oa = new OutputAnalyzer(p); + forks.add(new Fork(p, oa)); + jobs++; + } + + // Wait for the completion of other jobs + while (jobs >= MAX_PARALLELISM) { + Fork f = findDone(forks); + if (f != null) { + OutputAnalyzer oa = f.oa(); + oa.shouldHaveExitValue(0); + forks.remove(f); + jobs--; + } else { + // Nothing is done, wait a little. + Thread.sleep(200); + } + } + } + } + + // Drain the rest + for (Fork f : forks) { + OutputAnalyzer oa = f.oa(); + oa.shouldHaveExitValue(0); + } + } + + private static Fork findDone(List<Fork> forks) { + for (Fork f : forks) { + if (!f.p().isAlive()) { + return f; + } + } + return null; + } + + private static record Fork(Process p, OutputAnalyzer oa) {}; + +} diff --git a/test/hotspot/jtreg/compiler/c1/Test8271202.java b/test/hotspot/jtreg/compiler/c1/Test8271202.java new file mode 100644 index 0000000000000000000000000000000000000000..e867e391114ddb4ed357e73e36c95c41488e3ccf --- /dev/null +++ b/test/hotspot/jtreg/compiler/c1/Test8271202.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8271202 + * @requires vm.debug == true & vm.compiler1.enabled + * @run main/othervm -Xbatch -XX:TieredStopAtLevel=1 -XX:+DeoptimizeALot + * Test8271202 + */ + +public class Test8271202 { + public static void main(String[] strArr) { + try { + test(); + } catch (Exception e) { + // Expected + } + } + + static void test() { + long l6 = 10L; + int counter = 0; + int i2, i26, i29, iArr[] = new int[400]; + boolean b3 = true; + for (int smallinvoc = 0; smallinvoc < 139; smallinvoc++) { + } + for (i2 = 13; i2 < 1000; i2++) { + for (i26 = 2; i26 < 114; l6 += 2) { + // Infinite loop + if (b3) { + for (i29 = 1; i29 < 2; i29++) { + try { + iArr[i26] = 0; + } catch (ArithmeticException a_e) { + } + } + } + counter++; + if (counter == 100000) { + throw new RuntimeException("expected"); + } + } + } + } +} + diff --git a/test/hotspot/jtreg/compiler/c1/Test8275337.java b/test/hotspot/jtreg/compiler/c1/Test8275337.java new file mode 100644 index 0000000000000000000000000000000000000000..5e7ab912e20c010f86b98eb5ce48f8a36e573b1f --- /dev/null +++ b/test/hotspot/jtreg/compiler/c1/Test8275337.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8275337 + * @run main/othervm -Xcomp -XX:TieredStopAtLevel=1 compiler.c1.Test8275337 + */ + + +package compiler.c1; + +public class Test8275337 { + public static final int N = 400; + + public static void mainTest() { + int iArr1[] = new int[N]; + float fArr1[][] = new float[N][N]; + + for (int i = 9; i < 171; i++) { + int z; + try { + z = i % i; + } catch (ArithmeticException a_e) {} + for (int j = 1; j < 155; ++j) { + fArr1[j - 1][i] -= 1; + iArr1[i - 1] = 1; + } + for (int j = 4; j < 155; j++) { + for (int k = 1; k < 2; ++k) { + iArr1[i - 1] += 1; + fArr1[k - 1][j] -= 2; + } + } + } + } + public static void main(String[] strArr) { + + try { + for (int i = 0; i < 10; i++) { + mainTest(); + } + } catch (Exception ex) { + } + } +} diff --git a/test/hotspot/jtreg/compiler/c1/TestC1PhiPlacementPathology.jasm b/test/hotspot/jtreg/compiler/c1/TestC1PhiPlacementPathology.jasm new file mode 100644 index 0000000000000000000000000000000000000000..c504a7bf3fcf56273802b99ec46d1354b6c859cd --- /dev/null +++ b/test/hotspot/jtreg/compiler/c1/TestC1PhiPlacementPathology.jasm @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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. + * + */ +super public class TestC1PhiPlacementPathology + version 62:0 +{ + public static volatile Field sideEffect:I; + + public Method "<init>":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."<init>":"()V"; + return; + } + private static Method effect:"(I)V" + stack 2 locals 1 + { + getstatic Field sideEffect:"I"; + iload_0; + iadd; + putstatic Field sideEffect:"I"; + return; + } + public static Method test:"(I)V" + stack 2 locals 2 + { + iconst_0; + istore_1; + iload_0; + iconst_2; + irem; + ifne MODIFY_LOCAL; + iinc 1, 1; + goto LH2; + MODIFY_LOCAL: stack_frame_type append; + locals_map int; + iinc 1, 2; + iinc 0, 1; + goto LH1; + LH1: stack_frame_type same; + iinc 1, 1; + iload_1; + sipush 10000; + if_icmpge EXIT; + LH2: stack_frame_type same; + iinc 1, 1; + goto LH1; + EXIT: stack_frame_type same; + iload_1; + iload_0; + iadd; + invokestatic Method effect:"(I)V"; + return; + } +} // end Class TestC1PhiPlacementPathology diff --git a/src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.inline.hpp b/test/hotspot/jtreg/compiler/c1/TestC1PhiPlacementPathologyMain.java similarity index 60% rename from src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.inline.hpp rename to test/hotspot/jtreg/compiler/c1/TestC1PhiPlacementPathologyMain.java index 86ed1adada28d3d33c7758afb8fd5c205fcb542a..8edab2967665cbcc59cefa550e345165d30e1735 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailureObjectsSet.inline.hpp +++ b/test/hotspot/jtreg/compiler/c1/TestC1PhiPlacementPathologyMain.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Huawei and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -19,22 +19,22 @@ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. - * */ -#ifndef SHARE_GC_G1_G1EVACFAILUREOBJECTSSET_INLINE_HPP -#define SHARE_GC_G1_G1EVACFAILUREOBJECTSSET_INLINE_HPP - -#include "gc/g1/g1EvacFailureObjectsSet.hpp" -#include "gc/g1/g1CollectedHeap.hpp" -#include "gc/g1/g1SegmentedArray.inline.hpp" -#include "gc/g1/heapRegion.inline.hpp" +/* + * @test + * @bug 8277447 + * @summary Test a pathological case for phi placement with an irreducible loop of a particular shape. + * + * @compile TestC1PhiPlacementPathology.jasm + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,TestC1PhiPlacementPathology::test + * -XX:CompilationMode=quick-only -XX:-UseOnStackReplacement TestC1PhiPlacementPathologyMain + */ -void G1EvacFailureObjectsSet::record(oop obj) { - assert(obj != NULL, "must be"); - assert(_region_idx == G1CollectedHeap::heap()->heap_region_containing(obj)->hrm_index(), "must be"); - OffsetInRegion* e = _offsets.allocate(); - *e = to_offset(obj); +public class TestC1PhiPlacementPathologyMain { + public static void main(String[] args) { + for (int i = 0; i < 11000; i++) { + TestC1PhiPlacementPathology.test(0); + } + } } - -#endif //SHARE_GC_G1_G1EVACFAILUREOBJECTSSET_INLINE_HPP diff --git a/test/hotspot/jtreg/compiler/c2/TestCMoveInfiniteGVN.java b/test/hotspot/jtreg/compiler/c2/TestCMoveInfiniteGVN.java new file mode 100644 index 0000000000000000000000000000000000000000..50d9d02dea651ce3cd4e4edd2d1147293ae32c2c --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestCMoveInfiniteGVN.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 + * @key stress randomness + * @bug 8280123 + * @run main/othervm -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.c2.TestCMoveInfiniteGVN::test + * -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN -XX:StressSeed=43739875 + * compiler.c2.TestCMoveInfiniteGVN + * @run main/othervm -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.c2.TestCMoveInfiniteGVN::test + * -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN + * compiler.c2.TestCMoveInfiniteGVN + */ + +package compiler.c2; + +public class TestCMoveInfiniteGVN { + + static int test(boolean b, int i) { + int iArr[] = new int[2]; + + double d = Math.max(i, i); + for (int i1 = 1; i1 < 2; i1++) { + if (i1 != 0) { + return (b ? 1 : 0); // CMoveI + } + for (int i2 = 1; i2 < 2; i2++) { + switch (i2) { + case 1: d -= Math.max(i1, i2); break; + } + d -= iArr[i1 - 1]; + } + } + return 0; + } + + static void test() { + test(true, 234); + } + + public static void main(String[] strArr) { + test(); // compilation, then nmethod invalidation during execution + test(); // trigger crashing recompilation + } +} diff --git a/test/hotspot/jtreg/compiler/c2/TestSqrt.java b/test/hotspot/jtreg/compiler/c2/TestSqrt.java new file mode 100644 index 0000000000000000000000000000000000000000..9c4871569d77e4681d23aed75dff5f98a09dc5b4 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestSqrt.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2; + +/* + * @test + * @bug 8279076 + * @summary SqrtD/SqrtF should be matched only on supported platforms + * @requires vm.debug + * + * @run main/othervm -XX:-TieredCompilation -Xcomp + * -XX:CompileOnly=compiler/c2/TestSqrt + * -XX:CompileOnly=java/lang/Math + * compiler.c2.TestSqrt + */ +public class TestSqrt { + static float srcF = 42.0f; + static double srcD = 42.0d; + static float dstF; + static double dstD; + + public static void test() { + dstF = (float)Math.sqrt((double)srcF); + dstD = Math.sqrt(srcD); + } + + public static void main(String args[]) { + for (int i = 0; i < 20_000; i++) { + test(); + } + } +} + diff --git a/test/hotspot/jtreg/compiler/c2/TestSubIdealC0Minus_YPlusC1_.java b/test/hotspot/jtreg/compiler/c2/TestSubIdealC0Minus_YPlusC1_.java new file mode 100644 index 0000000000000000000000000000000000000000..b623e1a2393fcec932f023f9d223f5d071a34235 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestSubIdealC0Minus_YPlusC1_.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277882 + * @summary New subnode ideal optimization: converting "c0 - (x + c1)" into "(c0 - c1) - x" + * @library /test/lib + * @run main/othervm -XX:-TieredCompilation -Xbatch + * -XX:CompileCommand=dontinline,compiler.c2.TestSubIdealC0Minus_YPlusC1_::test* + * -XX:CompileCommand=compileonly,compiler.c2.TestSubIdealC0Minus_YPlusC1_::test* + * compiler.c2.TestSubIdealC0Minus_YPlusC1_ + */ +package compiler.c2; + +import jdk.test.lib.Asserts; + +public class TestSubIdealC0Minus_YPlusC1_ { + + private static final int I_C0_0 = 1234; + private static final int I_C1 = 1234; + private static final int I_C0_1 = 4321; + + private static final long L_C0_0 = 123_456_789_123L; + private static final long L_C1 = 123_456_789_123L; + private static final long L_C0_1 = 654_321; + + public static int testIC0EqualsC1(int x) { + return I_C0_0 - (x + I_C1); + } + + public static long testLC0EqualsC1(long x) { + return L_C0_0 - (x + L_C1); + } + + public static int testIC0NotEqualsC1(int x) { + return I_C0_1 - (x + I_C1); + } + + public static long testLC0NotEqualsC1(long x) { + return L_C0_1 - (x + L_C1); + } + + public static int testIXPlusC1IsOverflow(int x) { + return Integer.MAX_VALUE - (x + Integer.MAX_VALUE); + } + + public static long testLXPlusC1IsOverflow(long x) { + return Long.MAX_VALUE - (x + Long.MAX_VALUE); + } + + public static int testIXPlusC1IsUnderflow(int x) { + return Integer.MIN_VALUE - (x + Integer.MIN_VALUE); + } + + public static long testLXPlusC1IsUnderflow(long x) { + return Long.MIN_VALUE - (x + Long.MIN_VALUE); + } + + public static int testIC0MinusC1IsOverflow(int x) { + return Integer.MAX_VALUE - (x + Integer.MIN_VALUE); + } + + public static long testLC0MinusC1IsOverflow(long x) { + return Long.MAX_VALUE - (x + Long.MIN_VALUE); + } + + public static int testIC0MinusC1IsUnderflow(int x) { + return Integer.MIN_VALUE - (x + Integer.MAX_VALUE); + } + + public static long testLC0MinusC1IsUnderflow(long x) { + return Long.MIN_VALUE - (x + Long.MAX_VALUE); + } + + public static int testIResultIsOverflow(int x) { + return 2147483637 - (x + 10); // Integer.MAX_VALUE == 2147483647 + } + + public static long testLResultIsOverflow(long x) { + return 9223372036854775797L - (x + 10); // Long.MAX_VALUE == 9223372036854775807 + } + + public static int testIResultIsUnderflow(int x) { + return -2147483637 - (x + 10); // Integer.MIN_VALUE == -2147483648 + } + + public static long testLResultIsUnderflow(long x) { + return -9223372036854775797L - (x + 10); // Long.MIN_VALUE == -9223372036854775808 + } + + public static void main(String... args) { + for (int i = 0; i < 50_000; i++) { + Asserts.assertTrue(testIC0EqualsC1(10) == -10); + Asserts.assertTrue(testIC0NotEqualsC1(100) == 2987); + Asserts.assertTrue(testIXPlusC1IsOverflow(10) == -10); + Asserts.assertTrue(testIXPlusC1IsUnderflow(-10) == 10); + Asserts.assertTrue(testIC0MinusC1IsOverflow(10) == -11); + Asserts.assertTrue(testIC0MinusC1IsUnderflow(10) == -9); + Asserts.assertTrue(testIResultIsOverflow(-21) == Integer.MIN_VALUE); + Asserts.assertTrue(testIResultIsUnderflow(2) == Integer.MAX_VALUE); + + Asserts.assertTrue(testLC0EqualsC1(10) == -10); + Asserts.assertTrue(testLC0NotEqualsC1(100) == -123456134902L); + Asserts.assertTrue(testLXPlusC1IsOverflow(10) == -10); + Asserts.assertTrue(testLXPlusC1IsUnderflow(-10) == 10); + Asserts.assertTrue(testLC0MinusC1IsOverflow(10) == -11); + Asserts.assertTrue(testLC0MinusC1IsUnderflow(10) == -9); + Asserts.assertTrue(testLResultIsOverflow(-21) == Long.MIN_VALUE); + Asserts.assertTrue(testLResultIsUnderflow(2) == Long.MAX_VALUE); + } + } +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestAutoVectorization2DArray.java b/test/hotspot/jtreg/compiler/c2/irTests/TestAutoVectorization2DArray.java new file mode 100644 index 0000000000000000000000000000000000000000..c79fbf993dbeca0fb80b62158ac2d9f0a31c8cf6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestAutoVectorization2DArray.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8279258 + * @summary Auto-vectorization enhancement for two-dimensional array operations + * @library /test/lib / + * @run driver compiler.c2.irTests.TestAutoVectorization2DArray + */ + +public class TestAutoVectorization2DArray { + final private static int NUM = 64; + + private static double[][] a = new double[NUM][NUM]; + private static double[][] b = new double[NUM][NUM]; + private static double[][] c = new double[NUM][NUM]; + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @IR(counts = { IRNode.LOAD_VECTOR, " >0 " }) + @IR(counts = { IRNode.ADD_VD, " >0 " }) + @IR(counts = { IRNode.STORE_VECTOR, " >0 " }) + private static void testDouble(double[][] a , double[][] b, double[][] c) { + for(int i = 0; i < a.length; i++) { + for (int j = 0; j < a[0].length; j++) { + a[i][j] = b[i][j] + c[i][j]; + } + } + } + + @Run(test = "testDouble") + private void testDouble_runner() { + testDouble(a, b, c); + } +} diff --git a/test/hotspot/jtreg/runtime/NMT/ChangeTrackingLevel.java b/test/hotspot/jtreg/compiler/c2/irTests/TestBackToBackIfs.java similarity index 52% rename from test/hotspot/jtreg/runtime/NMT/ChangeTrackingLevel.java rename to test/hotspot/jtreg/compiler/c2/irTests/TestBackToBackIfs.java index 0cc059c13b93dec578f16e7c5ad2c98595b4b8dd..207b16a806270d0ad46dd2cf08a51bdedbbea1b3 100644 --- a/test/hotspot/jtreg/runtime/NMT/ChangeTrackingLevel.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestBackToBackIfs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,29 +21,45 @@ * questions. */ +package compiler.c2.irTests; + +import compiler.lib.ir_framework.*; +import jdk.test.lib.Utils; +import java.util.Random; + /* * @test - * @bug 8059100 - * @summary Test that you can decrease NMT tracking level but not increase it. - * @modules java.base/jdk.internal.misc - * @library /test/lib - * @build sun.hotspot.WhiteBox - * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail ChangeTrackingLevel + * @bug 8278228 + * @summary C2: Improve identical back-to-back if elimination + * @library /test/lib / + * @run driver compiler.c2.irTests.TestBackToBackIfs */ -import sun.hotspot.WhiteBox; +public class TestBackToBackIfs { + public static void main(String[] args) { + TestFramework.run(); + } -public class ChangeTrackingLevel { + static private int int_field; - public static WhiteBox wb = WhiteBox.getWhiteBox(); - public static void main(String args[]) throws Exception { - boolean testChangeLevel = wb.NMTChangeTrackingLevel(); - if (testChangeLevel) { - System.out.println("NMT level change test passed."); + @Test + @IR(counts = { IRNode.IF, "1" }) + public static void test(int a, int b) { + if (a == b) { + int_field = 0x42; } else { - // it also fails if the VM asserts. - throw new RuntimeException("NMT level change test failed"); + int_field = 42; } + if (a == b) { + int_field = 0x42; + } else { + int_field = 42; + } + } + + @Run(test = "test") + public static void test_runner() { + test(42, 0x42); + test(0x42, 0x42); } -}; +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestIRAbs.java b/test/hotspot/jtreg/compiler/c2/irTests/TestIRAbs.java new file mode 100644 index 0000000000000000000000000000000000000000..8ba786d6f20e5b4acff95e17c7073e3fd3bf48da --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestIRAbs.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import jdk.test.lib.Asserts; +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8276673 8280089 + * @summary Test abs nodes optimization in C2. + * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" + * @library /test/lib / + * @run driver compiler.c2.irTests.TestIRAbs + */ + +public class TestIRAbs { + + public static char [] cspecial = { + 0, 42, 128, 256, 1024, 4096, 65535 + }; + + public static int [] ispecial = { + 0, Integer.MAX_VALUE, Integer.MIN_VALUE, -42, 42, -1, 1 + }; + + public static long [] lspecial = { + 0, Long.MAX_VALUE, Long.MIN_VALUE, -42, 42, -1, 1 + }; + + public static float [] fspecial = { + 0.0f, + -0.0f, + Float.MAX_VALUE, + Float.MIN_VALUE, + -Float.MAX_VALUE, + -Float.MIN_VALUE, + Float.NaN, + Float.POSITIVE_INFINITY, + Float.NEGATIVE_INFINITY, + Integer.MAX_VALUE, + Integer.MIN_VALUE, + Long.MAX_VALUE, + Long.MIN_VALUE, + -1.0f, + 1.0f, + -42.0f, + 42.0f + }; + + public static double [] dspecial = { + 0.0, + -0.0, + Double.MAX_VALUE, + Double.MIN_VALUE, + -Double.MAX_VALUE, + -Double.MIN_VALUE, + Double.NaN, + Double.POSITIVE_INFINITY, + Double.NEGATIVE_INFINITY, + Integer.MAX_VALUE, + Integer.MIN_VALUE, + Long.MIN_VALUE, + Long.MAX_VALUE, + -1, + 1, + 42, + -42, + Math.PI, + Math.E, + Float.MAX_VALUE, + Float.MIN_VALUE, + -Float.MAX_VALUE, + -Float.MIN_VALUE, + Float.NaN, + Float.POSITIVE_INFINITY, + Float.NEGATIVE_INFINITY + }; + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @IR(failOn = {IRNode.ABS_I, IRNode.ABS_L, IRNode.ABS_F, IRNode.ABS_D}) + public void testAbsConstant() { + // Test abs(constant) optimization for int + Asserts.assertEquals(Integer.MAX_VALUE, Math.abs(Integer.MAX_VALUE)); + Asserts.assertEquals(Integer.MIN_VALUE, Math.abs(Integer.MIN_VALUE)); + Asserts.assertEquals(Integer.MAX_VALUE, Math.abs(-Integer.MAX_VALUE)); + + // Test abs(constant) optimization for long + Asserts.assertEquals(Long.MAX_VALUE, Math.abs(Long.MAX_VALUE)); + Asserts.assertEquals(Long.MIN_VALUE, Math.abs(Long.MIN_VALUE)); + Asserts.assertEquals(Long.MAX_VALUE, Math.abs(-Long.MAX_VALUE)); + + // Test abs(constant) optimization for float + Asserts.assertTrue(Float.isNaN(Math.abs(Float.NaN))); + Asserts.assertEquals(Float.POSITIVE_INFINITY, Math.abs(Float.NEGATIVE_INFINITY)); + Asserts.assertEquals(Float.POSITIVE_INFINITY, Math.abs(Float.POSITIVE_INFINITY)); + Asserts.assertEquals(0.0f, Math.abs(0.0f)); + Asserts.assertEquals(0.0f, Math.abs(-0.0f)); + Asserts.assertEquals(Float.MAX_VALUE, Math.abs(Float.MAX_VALUE)); + Asserts.assertEquals(Float.MIN_VALUE, Math.abs(Float.MIN_VALUE)); + Asserts.assertEquals(Float.MAX_VALUE, Math.abs(-Float.MAX_VALUE)); + Asserts.assertEquals(Float.MIN_VALUE, Math.abs(-Float.MIN_VALUE)); + + // Test abs(constant) optimization for double + Asserts.assertTrue(Double.isNaN(Math.abs(Double.NaN))); + Asserts.assertEquals(Double.POSITIVE_INFINITY, Math.abs(Double.NEGATIVE_INFINITY)); + Asserts.assertEquals(Double.POSITIVE_INFINITY, Math.abs(Double.POSITIVE_INFINITY)); + Asserts.assertEquals(0.0, Math.abs(0.0)); + Asserts.assertEquals(0.0, Math.abs(-0.0)); + Asserts.assertEquals(Double.MAX_VALUE, Math.abs(Double.MAX_VALUE)); + Asserts.assertEquals(Double.MIN_VALUE, Math.abs(Double.MIN_VALUE)); + Asserts.assertEquals(Double.MAX_VALUE, Math.abs(-Double.MAX_VALUE)); + Asserts.assertEquals(Double.MIN_VALUE, Math.abs(-Double.MIN_VALUE)); + } + + @Test + @IR(counts = {IRNode.ABS_I, "1"}) + public int testInt0(int x) { + return Math.abs(Math.abs(x)); // transformed to Math.abs(x) + } + + @Test + @IR(failOn = {IRNode.SUB_I}) + @IR(counts = {IRNode.ABS_I, "1"}) + public int testInt1(int x) { + return Math.abs(0 - x); // transformed to Math.abs(x) + } + + @Run(test = {"testInt0", "testInt1"}) + public void checkTestInt(RunInfo info) { + for (int i = 0; i < ispecial.length; i++) { + Asserts.assertEquals(Math.abs(ispecial[i]), testInt0(ispecial[i])); + Asserts.assertEquals(Math.abs(ispecial[i]), testInt1(ispecial[i])); + } + } + + @Test + @IR(counts = {IRNode.ABS_L, "1"}) + public long testLong0(long x) { + return Math.abs(Math.abs(x)); // transformed to Math.abs(x) + } + + @Test + @IR(failOn = {IRNode.SUB_L}) + @IR(counts = {IRNode.ABS_L, "1"}) + public long testLong1(long x) { + return Math.abs(0 - x); // transformed to Math.abs(x) + } + + @Run(test = {"testLong0", "testLong1"}) + public void checkTestLong(RunInfo info) { + for (int i = 0; i < lspecial.length; i++) { + Asserts.assertEquals(Math.abs(lspecial[i]), testLong0(lspecial[i])); + Asserts.assertEquals(Math.abs(lspecial[i]), testLong1(lspecial[i])); + } + } + + @Test + @IR(counts = {IRNode.ABS_F, "1"}) + public float testFloat0(float x) { + return Math.abs(Math.abs(x)); // transformed to Math.abs(x) + } + + @Test + @IR(failOn = {IRNode.SUB_F}) + @IR(counts = {IRNode.ABS_F, "1"}) + public float testFloat1(float x) { + return Math.abs(0 - x); // transformed to Math.abs(x) + } + + @Run(test = {"testFloat0", "testFloat1"}) + public void checkTestFloat(RunInfo info) { + for (int i = 0; i < fspecial.length; i++) { + Asserts.assertEquals(Math.abs(fspecial[i]), testFloat0(fspecial[i])); + Asserts.assertEquals(Math.abs(fspecial[i]), testFloat1(fspecial[i])); + } + } + + @Test + @IR(counts = {IRNode.ABS_D, "1"}) + public double testDouble0(double x) { + return Math.abs(Math.abs(x)); // transformed to Math.abs(x) + } + + @Test + @IR(failOn = {IRNode.SUB_D}) + @IR(counts = {IRNode.ABS_D, "1"}) + public double testDouble1(double x) { + return Math.abs(0 - x); // transformed to Math.abs(x) + } + + @Run(test = {"testDouble0", "testDouble1"}) + public void checkTestDouble(RunInfo info) { + for (int i = 0; i < dspecial.length; i++) { + Asserts.assertEquals(Math.abs(dspecial[i]), testDouble0(dspecial[i])); + Asserts.assertEquals(Math.abs(dspecial[i]), testDouble1(dspecial[i])); + } + } + + @Test + @IR(failOn = {IRNode.ABS_I}) + public void testChar() { + for (int i = 0; i < cspecial.length; i++) { + Asserts.assertEquals(cspecial[i], (char) Math.abs(cspecial[i])); + } + } + } diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestIRAddIdealNotXPlusC.java b/test/hotspot/jtreg/compiler/c2/irTests/TestIRAddIdealNotXPlusC.java new file mode 100644 index 0000000000000000000000000000000000000000..3d632b998566d5565ed1f39b6d345782a2a0961f --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestIRAddIdealNotXPlusC.java @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import jdk.test.lib.Asserts; +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8279607 + * @summary Test that transformation from ~x + c to (c - 1) - x and + * from ~(x + c) to (-c - 1) - x works as intended. + * @library /test/lib / + * @run driver compiler.c2.irTests.TestIRAddIdealNotXPlusC + */ +public class TestIRAddIdealNotXPlusC { + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntConIsNormal1(int x) { + return ~x + 1234; // transformed to 1233 - x + } + + @Run(test = "testIntConIsNormal1") + public void checkTestIntConIsNormal1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(1223, testIntConIsNormal1(10)); + Asserts.assertEquals(1233, testIntConIsNormal1(0)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntConIsNormal2(int x) { + return ~(x + -1234); // transformed to 1233 - x + } + + @Run(test = "testIntConIsNormal2") + public void checkTestIntConIsNormal2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(1223, testIntConIsNormal2(10)); + Asserts.assertEquals(1233, testIntConIsNormal2(0)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongConIsNormal1(long x) { + return ~x + 123_456_789_123L; // transformed to 123_456_789_122L - x + } + + @Run(test = "testLongConIsNormal1") + public void checkTestLongConIsNormal1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(113_456_789_122L, testLongConIsNormal1(10_000_000_000L)); + Asserts.assertEquals(123_456_789_122L, testLongConIsNormal1(0L)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongConIsNormal2(long x) { + return ~(x + -123_456_789_123L); // transformed to 123_456_789_122L - x + } + + @Run(test = "testLongConIsNormal2") + public void checkTestLongConIsNormal2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(113_456_789_122L, testLongConIsNormal2(10_000_000_000L)); + Asserts.assertEquals(123_456_789_122L, testLongConIsNormal2(0L)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntConIsZero1(int x) { + return ~x + 0; // transformed to -1 - x + } + + @Run(test = "testIntConIsZero1") + public void checkTestIntConIsZero1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(-11, testIntConIsZero1(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.SUB_I}) + @IR(counts = {IRNode.XOR_I, "1"}) + public int testIntConIsZero2(int x) { + return ~(x + 0); // should not happen, transformed to ~x + } + + @Run(test = "testIntConIsZero2") + public void checkTestIntConIsZero2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(-11, testIntConIsZero2(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongConIsZero1(long x) { + return ~x + 0L; // transformed to -1 - x + } + + @Run(test = "testLongConIsZero1") + public void checkTestLongConIsZero1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(-10_000_000_001L, testLongConIsZero1(10_000_000_000L)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.SUB_L}) + @IR(counts = {IRNode.XOR_L, "1"}) + public long testLongConIsZero2(long x) { + return ~(x + 0L); // should not happen, transformed to ~x + } + + @Run(test = "testLongConIsZero2") + public void checkTestLongConIsZero2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(-10_000_000_001L, testLongConIsZero2(10_000_000_000L)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntConIsOne1(int x) { + return ~x + 1; // transformed to 0 - x + } + + @Run(test = "testIntConIsOne1") + public void checkTestIntConIsOne1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(-10, testIntConIsOne1(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntConIsNegOne2(int x) { + return ~(x + -1); // transformed to 0 - x + } + + @Run(test = "testIntConIsNegOne2") + public void checkTestIntConIsNegOne2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(-10, testIntConIsNegOne2(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongConIsOne1(long x) { + return ~x + 1L; // transformed to 0 - x + } + + @Run(test = "testLongConIsOne1") + public void checkTestLongConIsOne1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(-10_000_000_000L, testLongConIsOne1(10_000_000_000L)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongConIsNegOne2(long x) { + return ~(x + -1L); // transformed to 0 - x + } + + @Run(test = "testLongConIsNegOne2") + public void checkTestLongConIsNegOne2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(-10_000_000_000L, testLongConIsNegOne2(10_000_000_000L)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntConMinusOneIsUnderflow1(int x) { + return ~x + Integer.MIN_VALUE; // transformed to Integer.MAX_VALUE - x + } + + @Run(test = "testIntConMinusOneIsUnderflow1") + public void checkTestIntConMinusOneIsUnderflow1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(2147483637, testIntConMinusOneIsUnderflow1(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntNegConMinusOneIsUnderflow2(int x) { + return ~(x + Integer.MIN_VALUE); // transformed to Integer.MAX_VALUE - x + } + + @Run(test = "testIntNegConMinusOneIsUnderflow2") + public void checkTestIntNegConMinusOneIsUnderflow2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(2147483637, testIntNegConMinusOneIsUnderflow2(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongConMinusOneIsUnderflow1(long x) { + return ~x + Long.MIN_VALUE; // transformed to Long.MAX_VALUE - x + } + + @Run(test = "testLongConMinusOneIsUnderflow1") + public void checkTestLongConMinusOneIsUnderflow1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(9223372036854775797L, testLongConMinusOneIsUnderflow1(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongNegConMinusOneIsUnderflow2(long x) { + return ~(x + Long.MIN_VALUE); // transformed to Long.MAX_VALUE - x + } + + @Run(test = "testLongNegConMinusOneIsUnderflow2") + public void checkTestLongNegConMinusOneIsUnderflow2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(9223372036854775797L, testLongNegConMinusOneIsUnderflow2(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntResultIsUnderflow1(int x) { + return ~x + -2147483638; // transformed to -2147483639 - x + } + + @Run(test = "testIntResultIsUnderflow1") + public void checkTestIntResultIsUnderflow1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(Integer.MAX_VALUE, testIntResultIsUnderflow1(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntResultIsUnderflow2(int x) { + return ~(x + 2147483638); // transformed to -2147483639 - x + } + + @Run(test = "testIntResultIsUnderflow2") + public void checkTestIntResultIsUnderflow2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(Integer.MAX_VALUE, testIntResultIsUnderflow2(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongResultIsUnderflow1(long x) { + return ~x + -9223372036854775798L; // transformed to -9223372036854775799L - x + } + + @Run(test = "testLongResultIsUnderflow1") + public void checkTestLongResultIsUnderflow1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(Long.MAX_VALUE, testLongResultIsUnderflow1(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongResultIsUnderflow2(long x) { + return ~(x + 9223372036854775798L); // transformed to -9223372036854775799L - x + } + + @Run(test = "testLongResultIsUnderflow2") + public void checkTestLongResultIsUnderflow2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(Long.MAX_VALUE, testLongResultIsUnderflow2(10)); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntResultIsOverflow1(int x) { + return ~x + 2147483637; // transformed to 2147483646 - x + } + + @Run(test = "testIntResultIsOverflow1") + public void checkTestIntResultIsOverflow1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(Integer.MIN_VALUE, testIntResultIsOverflow1(-12)); + } + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.XOR_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int testIntResultIsOverflow2(int x) { + return ~(x + -2147483637); // transformed to 2147483646 - x + } + + @Run(test = "testIntResultIsOverflow2") + public void checkTestIntResultIsOverflow2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(Integer.MIN_VALUE, testIntResultIsOverflow2(-12)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongResultIsOverflow1(long x) { + return ~x + 9223372036854775797L; // transformed to 9223372036854775798L - x + } + + @Run(test = "testLongResultIsOverflow1") + public void checkTestLongResultIsOverflow1(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(Long.MIN_VALUE, testLongResultIsOverflow1(-12)); + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.XOR_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long testLongResultIsOverflow2(long x) { + return ~(x + -9223372036854775797L); // transformed to 9223372036854775798L - x + } + + @Run(test = "testLongResultIsOverflow2") + public void checkTestLongResultIsOverflow2(RunInfo info) { + assertC2Compiled(info); + Asserts.assertEquals(Long.MIN_VALUE, testLongResultIsOverflow2(-12)); + } + + private void assertC2Compiled(RunInfo info) { + // Test VM allows C2 to work + Asserts.assertTrue(info.isC2CompilationEnabled()); + if (!info.isWarmUp()) { + // C2 compilation happens + Asserts.assertTrue(info.isTestC2Compiled()); + } + } +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestIRLShiftIdeal_XPlusX_LShiftC.java b/test/hotspot/jtreg/compiler/c2/irTests/TestIRLShiftIdeal_XPlusX_LShiftC.java new file mode 100644 index 0000000000000000000000000000000000000000..dc42ff9cdc13c3a46c02723624aa952ce4be0b80 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestIRLShiftIdeal_XPlusX_LShiftC.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import jdk.test.lib.Asserts; +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8278114 + * @summary Test that transformation from (x + x) >> c to x >> (c + 1) works as intended. + * @library /test/lib / + * @run driver compiler.c2.irTests.TestIRLShiftIdeal_XPlusX_LShiftC + */ +public class TestIRLShiftIdeal_XPlusX_LShiftC { + + private static final int[] INT_IN = { + -10, -2, -1, 0, 1, 2, 10, + 0x8000_0000, 0x7FFF_FFFF, 0x5678_1234, + }; + + private static final int[][] INT_OUT = { + // Do testInt0(x) for each x in INT_IN + { + -160, -32, -16, 0, 16, 32, 160, + 0x0000_0000, 0xFFFF_FFF0, 0x6781_2340, + }, + + // Do testInt1(x) for each x in INT_IN + { + -10485760, -2097152, -1048576, 0, 1048576, 2097152, 10485760, + 0x0000_0000, 0xFFF0_0000, 0x2340_0000, + }, + }; + + private static final long[] LONG_IN = { + -10L, -2L, -1L, 0L, 1L, 2L, 10L, + 0x8000_0000_0000_0000L, 0x7FFF_FFFF_FFFF_FFFFL, 0x5678_1234_4321_8765L, + }; + + private static final long[][] LONG_OUT = { + // Do testLong0(x) for each x in LONG_IN + { + -160L, -32L, -16L, 0L, 16L, 32L, 160L, + 0x0000_0000_0000_0000L, 0xFFFF_FFFF_FFFF_FFF0L, 0x6781_2344_3218_7650L, + }, + + // Do testLong1(x) for each x in LONG_IN + { + -687194767360L, -137438953472L, -68719476736L, 0L, 68719476736L, 137438953472L, 687194767360L, + 0x0000_0000_0000_0000L, 0xFFFF_FFF0_0000_0000L, 0x3218_7650_0000_0000L, + }, + }; + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @IR(failOn = {IRNode.ADD_I, IRNode.MUL_I}) + @IR(counts = {IRNode.LSHIFT_I, "1"}) + public int testInt0(int x) { + return (x + x) << 3; // transformed to x << 4 + } + + @Run(test = "testInt0") + public void checkTestInt0(RunInfo info) { + assertC2Compiled(info); + for (int i = 0; i < INT_IN.length; i++) { + Asserts.assertEquals(INT_OUT[0][i], testInt0(INT_IN[i])); + } + } + + @Test + @IR(failOn = {IRNode.MUL_I}) + @IR(counts = {IRNode.LSHIFT_I, "1", + IRNode.ADD_I, "1"}) + public int testInt1(int x) { + return (x + x) << 19; // no transformation because 19 is + // greater than 16 (see implementation + // in LShiftINode::Ideal) + } + + @Run(test = "testInt1") + public void checkTestInt1(RunInfo info) { + assertC2Compiled(info); + for (int i = 0; i < INT_IN.length; i++) { + Asserts.assertEquals(INT_OUT[1][i], testInt1(INT_IN[i])); + } + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.MUL_L}) + @IR(counts = {IRNode.LSHIFT_L, "1"}) + public long testLong0(long x) { + return (x + x) << 3; // transformed to x << 4 + } + + @Run(test = "testLong0") + public void checkTestLong0(RunInfo info) { + assertC2Compiled(info); + for (int i = 0; i < LONG_IN.length; i++) { + Asserts.assertEquals(LONG_OUT[0][i], testLong0(LONG_IN[i])); + } + } + + @Test + @IR(failOn = {IRNode.ADD_L, IRNode.MUL_L}) + @IR(counts = {IRNode.LSHIFT_L, "1"}) + public long testLong1(long x) { + return (x + x) << 35; // transformed to x << 36 + } + + @Run(test = "testLong1") + public void checkTestLong1(RunInfo info) { + assertC2Compiled(info); + for (int i = 0; i < LONG_IN.length; i++) { + Asserts.assertEquals(LONG_OUT[1][i], testLong1(LONG_IN[i])); + } + } + + private void assertC2Compiled(RunInfo info) { + // Test VM allows C2 to work + Asserts.assertTrue(info.isC2CompilationEnabled()); + if (!info.isWarmUp()) { + // C2 compilation happens + Asserts.assertTrue(info.isTestC2Compiled()); + } + } +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestIterativeEA.java b/test/hotspot/jtreg/compiler/c2/irTests/TestIterativeEA.java new file mode 100644 index 0000000000000000000000000000000000000000..1bfaebabec84d299450871444ba9878a4d0c0849 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestIterativeEA.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import jdk.test.lib.Asserts; +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8276455 + * @summary Test C2 iterative Escape Analysis to remove all allocations in test + * @library /test/lib / + * @run driver compiler.c2.irTests.TestIterativeEA + */ +public class TestIterativeEA { + + public static void main(String[] args) { + TestFramework.run(); + } + + static class MyClass { + int val; + public MyClass(int val) { + this.val = val; + } + } + + static class AbstractClass { + final int unused; + public AbstractClass() { + unused = 42; + } + } + + static class HolderWithSuper extends AbstractClass { + final MyClass obj; + public HolderWithSuper(MyClass obj) { + this.obj = obj; + } + } + + static class Holder { + final MyClass obj; + public Holder(MyClass obj) { + this.obj = obj; + } + } + + static class GenericHolder { + final Object obj; + public GenericHolder(Object obj) { + this.obj = obj; + } + } + + @Test + @Arguments({ Argument.RANDOM_EACH }) + @IR(failOn = { IRNode.ALLOC }) + public static int testSlow(int val) { + MyClass obj = new MyClass(val); + HolderWithSuper h1 = new HolderWithSuper(obj); + GenericHolder h2 = new GenericHolder(h1); + return ((HolderWithSuper)h2.obj).obj.val; + } + + @Test + @Arguments({ Argument.RANDOM_EACH }) + @IR(failOn = { IRNode.ALLOC }) + public static int testFast(int val) { + MyClass obj = new MyClass(val); + Holder h1 = new Holder(obj); + GenericHolder h2 = new GenericHolder(h1); + return ((Holder)h2.obj).obj.val; + } + + static class A { + int i; + public A(int i) { + this.i = i; + } + } + + static class B { + A a; + public B(A a) { + this.a = a; + } + } + + static class C { + B b; + public C(B b) { + this.b = b; + } + } + + @Test + @Arguments({ Argument.RANDOM_EACH }) + @IR(failOn = { IRNode.ALLOC }) + static int testNested(int i) { + C c = new C(new B(new A(i))); + return c.b.a.i; + } +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestLongRangeChecks.java b/test/hotspot/jtreg/compiler/c2/irTests/TestLongRangeChecks.java index 298f00942011115c9fccd4228d27ffa57e0b5675..4fd677ab4c0ae52108b7a806491df1cc5b27528a 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestLongRangeChecks.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestLongRangeChecks.java @@ -28,7 +28,7 @@ import java.util.Objects; /* * @test - * @bug 8259609 + * @bug 8259609 8276116 * @summary C2: optimize long range checks in long counted loops * @library /test/lib / * @run driver compiler.c2.irTests.TestLongRangeChecks @@ -41,8 +41,8 @@ public class TestLongRangeChecks { @Test - @IR(counts = { IRNode.LOOP, "1"}) - @IR(failOn = { IRNode.COUNTEDLOOP}) + @IR(counts = { IRNode.LOOP, "1" }) + @IR(failOn = { IRNode.COUNTEDLOOP }) public static void testStridePosScalePos(long start, long stop, long length, long offset) { final long scale = 1; final long stride = 1; @@ -60,4 +60,40 @@ public class TestLongRangeChecks { private void testStridePosScalePos_runner() { testStridePosScalePos(0, 100, 100, 0); } + + @Test + @IR(counts = { IRNode.LOOP, "1" }) + @IR(failOn = { IRNode.COUNTEDLOOP }) + public static void testStridePosScalePosInIntLoop1(int start, int stop, long length, long offset) { + final long scale = 2; + final int stride = 1; + + // Same but with int loop + for (int i = start; i < stop; i += stride) { + Objects.checkIndex(scale * i + offset, length); + } + } + + @Run(test = "testStridePosScalePosInIntLoop1") + private void testStridePosScalePosInIntLoop1_runner() { + testStridePosScalePosInIntLoop1(0, 100, 200, 0); + } + + @Test + @IR(counts = { IRNode.LOOP, "1" }) + @IR(failOn = { IRNode.COUNTEDLOOP }) + public static void testStridePosScalePosInIntLoop2(int start, int stop, long length, long offset) { + final int scale = 2; + final int stride = 1; + + // Same but with int loop + for (int i = start; i < stop; i += stride) { + Objects.checkIndex(scale * i + offset, length); + } + } + + @Run(test = "testStridePosScalePosInIntLoop2") + private void testStridePosScalePosInIntLoop2_runner() { + testStridePosScalePosInIntLoop2(0, 100, 200, 0); + } } diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestRemixAddressExpressions.java b/test/hotspot/jtreg/compiler/c2/irTests/TestRemixAddressExpressions.java new file mode 100644 index 0000000000000000000000000000000000000000..f35b9273a56185fbc4b0584e2592e8c52125ecb8 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestRemixAddressExpressions.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8278784 + * @summary C2: Refactor PhaseIdealLoop::remix_address_expressions() so it operates on longs + * @library /test/lib / + * @run driver compiler.c2.irTests.TestRemixAddressExpressions + */ + +public class TestRemixAddressExpressions { + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @IR(counts = { IRNode.ADD_I, "1", IRNode.LSHIFT_I, "2" }) + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + public static float invPlusVarLshiftInt(int inv, int scale) { + float res = 0; + for (int i = 1; i < 100; i *= 11) { + res += (i + inv) << scale; + } + return res; + } + + @Test + @IR(counts = { IRNode.ADD_L, "1", IRNode.LSHIFT_L, "2" }) + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + public static float invPlusVarLshiftLong(long inv, int scale) { + float res = 0; + for (long i = 1; i < 100; i *= 11) { + res += (i + inv) << scale; + } + return res; + } + + @Test + @IR(counts = { IRNode.ADD_I, "1", IRNode.SUB_I, "1", IRNode.LSHIFT_I, "2" }) + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + public static float invMinusVarLshiftInt(int inv, int scale) { + float res = 0; + for (int i = 1; i < 100; i *= 11) { + res += (inv - i) << scale; + } + return res; + } + + @Test + @IR(counts = { IRNode.ADD_L, "1", IRNode.SUB_L, "1", IRNode.LSHIFT_L, "2" }) + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + public static float invMinusVarLshiftLong(long inv, int scale) { + float res = 0; + for (long i = 1; i < 100; i *= 11) { + res += (inv - i) << scale; + } + return res; + } + + @Test + @IR(counts = { IRNode.ADD_I, "1", IRNode.SUB_I, "1", IRNode.LSHIFT_I, "2" }) + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + public static float varMinusInvLshiftInt(int inv, int scale) { + float res = 0; + for (int i = 1; i < 100; i *= 11) { + res += (i - inv) << scale; + } + return res; + } + + @Test + @IR(counts = { IRNode.ADD_L, "1", IRNode.SUB_L, "1", IRNode.LSHIFT_L, "2" }) + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + public static float varMinusInvLshiftLong(long inv, int scale) { + float res = 0; + for (long i = 1; i < 100; i *= 11) { + res += (i - inv) << scale; + } + return res; + } +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestShiftAndMask.java b/test/hotspot/jtreg/compiler/c2/irTests/TestShiftAndMask.java new file mode 100644 index 0000000000000000000000000000000000000000..3423ca075b794162e627e4d69a274214186e0e9c --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestShiftAndMask.java @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import compiler.lib.ir_framework.*; +import jdk.test.lib.Utils; +import java.util.Random; + +/* + * @test + * @bug 8277850 8278949 + * @summary C2: optimize mask checks in counted loops + * @library /test/lib / + * @run driver compiler.c2.irTests.TestShiftAndMask + */ + +public class TestShiftAndMask { + private static final Random RANDOM = Utils.getRandomInstance(); + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @Arguments(Argument.RANDOM_EACH) + @IR(failOn = { IRNode.AND_I, IRNode.LSHIFT_I }) + public static int shiftMaskInt(int i) { + return (i << 2) & 3; // transformed to: return 0; + } + + @Check(test = "shiftMaskInt") + public static void checkShiftMaskInt(int res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @Arguments(Argument.RANDOM_EACH) + @IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_L }) + public static long shiftMaskLong(long i) { + return (i << 2) & 3; // transformed to: return 0; + } + + + @Check(test = "shiftMaskLong") + public static void checkShiftMaskLong(long res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } + + static volatile int barrier; + + @Test + @Arguments({Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE}) + @IR(failOn = { IRNode.AND_I, IRNode.LSHIFT_I }) + public static int shiftNonConstMaskInt(int i, boolean flag) { + int mask; + if (flag) { + barrier = 42; + mask = 3; + } else { + mask = 1; + } + return mask & (i << 2); // transformed to: return 0; + } + + @Check(test = "shiftNonConstMaskInt") + public static void checkShiftNonConstMaskInt(int res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @Arguments({Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE}) + @IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_L }) + public static long shiftNonConstMaskLong(long i, boolean flag) { + long mask; + if (flag) { + barrier = 42; + mask = 3; + } else { + mask = 1; + } + return mask & (i << 2); // transformed to: return 0; + } + + @Check(test = "shiftNonConstMaskLong") + public static void checkShiftNonConstMaskLong(long res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @IR(counts = { IRNode.AND_I, "1" }) + @IR(failOn = { IRNode.ADD_I, IRNode.LSHIFT_I }) + public static int addShiftMaskInt(int i, int j) { + return (j + (i << 2)) & 3; // transformed to: return j & 3; + } + + @Run(test = "addShiftMaskInt") + public static void addShiftMaskInt_runner() { + int i = RANDOM.nextInt(); + int j = RANDOM.nextInt(); + int res = addShiftMaskInt(i, j); + if (res != (j & 3)) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @IR(counts = { IRNode.AND_I, "1" }) + @IR(failOn = { IRNode.ADD_I, IRNode.LSHIFT_I }) + public static int addSshiftNonConstMaskInt(int i, int j, boolean flag) { + int mask; + if (flag) { + barrier = 42; + mask = 3; + } else { + mask = 1; + } + return mask & (j + (i << 2)); // transformed to: return j & mask; + } + + @Run(test = "addSshiftNonConstMaskInt") + public static void addSshiftNonConstMaskInt_runner() { + int i = RANDOM.nextInt(); + int j = RANDOM.nextInt(); + int res = addSshiftNonConstMaskInt(i, j, true); + if (res != (j & 3)) { + throw new RuntimeException("incorrect result: " + res); + } + res = addSshiftNonConstMaskInt(i, j, false); + if (res != (j & 1)) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @IR(counts = { IRNode.AND_L, "1" }) + @IR(failOn = { IRNode.ADD_L, IRNode.LSHIFT_L }) + public static long addShiftMaskLong(long i, long j) { + return (j + (i << 2)) & 3; // transformed to: return j & 3; + } + + @Run(test = "addShiftMaskLong") + public static void addShiftMaskLong_runner() { + long i = RANDOM.nextLong(); + long j = RANDOM.nextLong(); + long res = addShiftMaskLong(i, j); + if (res != (j & 3)) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @IR(counts = { IRNode.AND_L, "1" }) + @IR(failOn = { IRNode.ADD_L, IRNode.LSHIFT_L }) + public static long addSshiftNonConstMaskLong(long i, long j, boolean flag) { + int mask; + if (flag) { + barrier = 42; + mask = 3; + } else { + mask = 1; + } + return mask & (j + (i << 2)); // transformed to: return j & mask; + } + + @Run(test = "addSshiftNonConstMaskLong") + public static void addSshiftNonConstMaskLong_runner() { + long i = RANDOM.nextLong(); + long j = RANDOM.nextLong(); + long res = addSshiftNonConstMaskLong(i, j, true); + if (res != (j & 3)) { + throw new RuntimeException("incorrect result: " + res); + } + res = addSshiftNonConstMaskLong(i, j, false); + if (res != (j & 1)) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + @IR(failOn = { IRNode.AND_I, IRNode.ADD_I, IRNode.LSHIFT_I }) + public static int addShiftMaskInt2(int i, int j) { + return ((j << 2) + (i << 2)) & 3; // transformed to: return 0; + } + + @Check(test = "addShiftMaskInt2") + public static void checkAddShiftMaskInt2(int res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + @IR(failOn = { IRNode.AND_L, IRNode.ADD_L, IRNode.LSHIFT_L }) + public static long addShiftMaskLong2(long i, long j) { + return ((j << 2) + (i << 2)) & 3; // transformed to: return 0; + } + + @Check(test = "addShiftMaskLong2") + public static void checkAddShiftMaskLong2(long res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } + + // Try to get add inputs swapped compared to other tests + @Test + @IR(counts = { IRNode.AND_I, "1" }) + @IR(failOn = { IRNode.ADD_I, IRNode.LSHIFT_I }) + public static int addShiftMaskInt3(int i, long j) { + int add1 = (i << 2); + int add2 = (int)j; + return (add1 + add2) & 3; // transformed to: return j & 3; + } + + @Run(test = "addShiftMaskInt3") + public static void addShiftMaskInt3_runner() { + int i = RANDOM.nextInt(); + int j = RANDOM.nextInt(); + int res = addShiftMaskInt3(i, j); + if (res != (j & 3)) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @IR(counts = { IRNode.AND_L, "1" }) + @IR(failOn = { IRNode.ADD_L, IRNode.LSHIFT_L }) + public static long addShiftMaskLong3(long i, float j) { + long add1 = (i << 2); + long add2 = (long)j; + return (add1 + add2) & 3; // transformed to: return j & 3; + } + + @Run(test = "addShiftMaskLong3") + public static void addShiftMaskLong3_runner() { + long i = RANDOM.nextLong(); + float j = RANDOM.nextFloat(); + long res = addShiftMaskLong3(i, j); + if (res != (((long)j) & 3)) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @Arguments({Argument.RANDOM_EACH}) + @IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_I }) + public static long shiftConvMask(int i) { + return ((long)(i << 2)) & 3; // transformed to: return 0; + } + + @Check(test = "shiftConvMask") + public static void checkShiftConvMask(long res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @Arguments({Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE}) + @IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_L }) + public static long shiftNotConstConvMask(int i, boolean flag) { + long mask; + if (flag) { + barrier = 42; + mask = 3; + } else { + mask = 1; + } + return mask & ((long)(i << 2)); // transformed to: return 0; + } + + @Check(test = "shiftNotConstConvMask") + public static void checkShiftNotConstConvMask(long res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @IR(counts = { IRNode.AND_L, "1" }) + @IR(failOn = { IRNode.ADD_L, IRNode.LSHIFT_I, IRNode.CONV_I2L }) + public static long addShiftConvMask(int i, long j) { + return (j + (i << 2)) & 3; // transformed to: return j & 3; + } + + @Run(test = "addShiftConvMask") + public static void addShiftConvMask_runner() { + int i = RANDOM.nextInt(); + long j = RANDOM.nextLong(); + long res = addShiftConvMask(i, j); + if (res != (j & 3)) { + throw new RuntimeException("incorrect result: " + res); + } + } + + @Test + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH}) + @IR(failOn = { IRNode.AND_L, IRNode.ADD_L, IRNode.LSHIFT_L }) + public static long addShiftConvMask2(int i, int j) { + return (((long)(j << 2)) + ((long)(i << 2))) & 3; // transformed to: return 0; + } + + @Check(test = "addShiftConvMask2") + public static void checkAddShiftConvMask2(long res) { + if (res != 0) { + throw new RuntimeException("incorrect result: " + res); + } + } +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal.java b/test/hotspot/jtreg/compiler/c2/irTests/TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal.java new file mode 100644 index 0000000000000000000000000000000000000000..4cbbcd9330131dcd07e1aba68b146bba29121299 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import jdk.test.lib.Asserts; +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8278471 + * @summary Remove unreached rules in AddNode::IdealIL + * @library /test/lib / + * @run driver compiler.c2.irTests.TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal + */ +/* Test conversion from (a - b) + (b - c) to (a - c) and conversion + * from (a - b) + (c - a) to (c - b) have really happened so we can + * safely remove both. */ +public class TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal { + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) + @IR(failOn = {IRNode.ADD_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int test1Int(int a, int b, int c) { + return (a - b) + (b - c); // transformed to a - c rather than (a + b) - (b + c) + } + + @Test + @Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) + @IR(failOn = {IRNode.ADD_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long test1Long(long a, long b, long c) { + return (a - b) + (b - c); // transformed to a - c rather than (a + b) - (b + c) + } + + @Test + @Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) + @IR(failOn = {IRNode.ADD_I}) + @IR(counts = {IRNode.SUB_I, "1"}) + public int test2Int(int b, int a, int c) { // make sure inputs sorted + return (a - b) + (c - a); // transformed to c - b rather than (a + c) - (b + a) + } + + @Test + @Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) + @IR(failOn = {IRNode.ADD_L}) + @IR(counts = {IRNode.SUB_L, "1"}) + public long test2Long(long b, long a, long c) { // make sure inputs sorted + return (a - b) + (c - a); // transformed to return c - b rather than (a + c) - (b + a) + } +} diff --git a/test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java b/test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java index a450b1e02e138c0d7aff33968e9622990d6159bb..01787593412e44c89cb52b8fe0f77c80354bb92f 100644 --- a/test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java +++ b/test/hotspot/jtreg/compiler/cha/AbstractRootMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,12 +50,23 @@ */ package compiler.cha; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + import static compiler.cha.Utils.*; public class AbstractRootMethod { public static void main(String[] args) { run(AbstractClass.class); run(AbstractInterface.class); + + // Implementation limitation: CHA is not performed by C1 during inlining through MH linkers. + if (!sun.hotspot.code.Compiler.isC1Enabled()) { + run(AbstractClass.TestMH.class, AbstractClass.class); + run(AbstractInterface.TestMH.class, AbstractInterface.class); + } + + System.out.println("TEST PASSED"); } public static class AbstractClass extends ATest<AbstractClass.C> { @@ -124,7 +135,21 @@ public class AbstractRootMethod { call(new G() { public Object m() { return CORRECT; } }); // Gn <: G.m <: C.m ABSTRACT assertCompiled(); } + + public static class TestMH extends AbstractClass { + static final MethodHandle TEST_MH = findVirtualHelper(C.class, "m", Object.class, MethodHandles.lookup()); + + @Override + public Object test(C obj) { + try { + return TEST_MH.invokeExact(obj); // invokevirtual C.m() + } catch (Throwable e) { + throw new InternalError(e); + } + } + } } + public static class AbstractInterface extends ATest<AbstractInterface.C> { public AbstractInterface() { super(C.class, D.class); @@ -193,5 +218,18 @@ public class AbstractRootMethod { call(new G() { public Object m() { return CORRECT; } }); // Gn <: G.m <: C <: I.m ABSTRACT assertCompiled(); } + + public static class TestMH extends AbstractInterface { + static final MethodHandle TEST_MH = findVirtualHelper(C.class, "m", Object.class, MethodHandles.lookup()); + + @Override + public Object test(C obj) { + try { + return TEST_MH.invokeExact(obj); // invokevirtual C.m() + } catch (Throwable e) { + throw new InternalError(e); + } + } + } } } diff --git a/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java b/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java index 354412d77480c47c5d9a0043f7f97e2a4db97a09..a13a9cfdd26a190d8b6f97fd50a35b2e59d5405f 100644 --- a/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java +++ b/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,12 +50,22 @@ */ package compiler.cha; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + import static compiler.cha.Utils.*; public class DefaultRootMethod { public static void main(String[] args) { run(DefaultRoot.class); run(InheritedDefault.class); + + // Implementation limitation: CHA is not performed by C1 during inlining through MH linkers. + if (!sun.hotspot.code.Compiler.isC1Enabled()) { + run(DefaultRoot.TestMH.class, DefaultRoot.class); + run(InheritedDefault.TestMH.class, InheritedDefault.class); + } + System.out.println("TEST PASSED"); } @@ -83,7 +93,7 @@ public class DefaultRootMethod { static class G extends C { public Object m() { return CORRECT; } } @Override - public Object test(C obj) { + public Object test(C obj) throws Throwable { return obj.m(); // invokevirtual C.m() } @@ -122,6 +132,15 @@ public class DefaultRootMethod { call(new G() { public Object m() { return CORRECT; } }); // Gn <: G.m <: C <: I.m DEFAULT assertCompiled(); } + + public static class TestMH extends DefaultRoot { + static final MethodHandle TEST_MH = findVirtualHelper(C.class, "m", Object.class, MethodHandles.lookup()); + + @Override + public Object test(C obj) throws Throwable { + return TEST_MH.invokeExact(obj); // invokevirtual C.m() + } + } } public static class InheritedDefault extends ATest<InheritedDefault.C> { @@ -151,7 +170,7 @@ public class DefaultRootMethod { static class G extends C implements K { /* inherits K.m DEFAULT */ } @Override - public Object test(C obj) { + public Object test(C obj) throws Throwable { return obj.m(); // invokevirtual C.m() } @@ -190,5 +209,14 @@ public class DefaultRootMethod { call(new G() { public Object m() { return CORRECT; } }); // Gn <: G.m <: C <: I.m DEFAULT assertCompiled(); } + + public static class TestMH extends InheritedDefault { + static final MethodHandle TEST_MH = findVirtualHelper(C.class, "m", Object.class, MethodHandles.lookup()); + + @Override + public Object test(C obj) throws Throwable { + return TEST_MH.invokeExact(obj); // invokevirtual C.m() + } + } } } diff --git a/test/hotspot/jtreg/compiler/cha/Utils.java b/test/hotspot/jtreg/compiler/cha/Utils.java index cad185b1110306147f20daa34c76f30eaa782b66..f45ab256fbb710206b0994a0c6e06ea2fd610d17 100644 --- a/test/hotspot/jtreg/compiler/cha/Utils.java +++ b/test/hotspot/jtreg/compiler/cha/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Method; import java.util.HashMap; import java.util.concurrent.Callable; @@ -45,6 +46,7 @@ import static jdk.test.lib.Asserts.assertTrue; public class Utils { public static final Unsafe U = Unsafe.getUnsafe(); + public static final WhiteBox WB = WhiteBox.getWhiteBox(); interface Test<T> { void call(T o); @@ -99,8 +101,6 @@ public class Utils { } public static abstract class ATest<T> implements Test<T> { - public static final WhiteBox WB = WhiteBox.getWhiteBox(); - public static final Object CORRECT = new Object(); public static final Object WRONG = new Object(); @@ -117,7 +117,7 @@ public class Utils { } @DontInline - public abstract Object test(T i); + public abstract Object test(T i) throws Throwable; public abstract void checkInvalidReceiver(); @@ -133,7 +133,6 @@ public class Utils { })); } - public void compile(Runnable r) { while (!WB.isMethodCompiled(TEST)) { for (int i = 0; i < 100; i++) { @@ -161,19 +160,35 @@ public class Utils { @Override public void call(T i) { - assertTrue(test(i) != WRONG); + try { + assertTrue(test(i) != WRONG); + } catch (Throwable e) { + throw new InternalError(e); + } + } + + public static <T> T compute(Callable<T> c) { + try { + return c.call(); + } catch (Exception e) { + throw new Error(e); + } + } + + public static MethodHandle findVirtualHelper(Class<?> refc, String name, Class<?> returnType, MethodHandles.Lookup lookup) { + return compute(() -> lookup.findVirtual(refc, name, MethodType.methodType(returnType))); } } @Retention(value = RetentionPolicy.RUNTIME) public @interface TestCase {} - static void run(Class<?> test) { + static void run(Class<?> test, Class<?> enclosed) { try { - for (Method m : test.getDeclaredMethods()) { + for (Method m : test.getMethods()) { if (m.isAnnotationPresent(TestCase.class)) { System.out.println(m.toString()); - ClassLoader cl = new MyClassLoader(test); + ClassLoader cl = new MyClassLoader(enclosed); Class<?> c = cl.loadClass(test.getName()); c.getMethod(m.getName()).invoke(c.getDeclaredConstructor().newInstance()); } @@ -183,6 +198,10 @@ public class Utils { } } + static void run(Class<?> test) { + run(test, test); + } + static class ObjectToStringHelper { static Object testHelper(Object o) { throw new Error("not used"); @@ -303,7 +322,7 @@ public class Utils { try { r.run(); throw new AssertionError("Exception not thrown: " + expectedException.getName()); - } catch(Throwable e) { + } catch (Throwable e) { if (expectedException == e.getClass()) { // success: proper exception is thrown } else { @@ -320,12 +339,4 @@ public class Utils { throw new Error(e); } } - - static <T> T compute(Callable<T> c) { - try { - return c.call(); - } catch (Exception e) { - throw new Error(e); - } - } } diff --git a/test/hotspot/jtreg/compiler/codecache/OverflowCodeCacheTest.java b/test/hotspot/jtreg/compiler/codecache/OverflowCodeCacheTest.java index 1dc02e25312292cef167b78215c84df82b90fdf1..cd69d0a31daaffd6d7b8f77d701f9bc44045510a 100644 --- a/test/hotspot/jtreg/compiler/codecache/OverflowCodeCacheTest.java +++ b/test/hotspot/jtreg/compiler/codecache/OverflowCodeCacheTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * 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 OverflowCodeCacheTest - * @bug 8059550 + * @bug 8059550 8279356 * @summary testing of code cache segments overflow * @library /test/lib * @modules java.base/jdk.internal.misc @@ -33,11 +33,14 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::* - * -XX:-SegmentedCodeCache - * compiler.codecache.OverflowCodeCacheTest + * -XX:-SegmentedCodeCache -Xmixed + * compiler.codecache.OverflowCodeCacheTest CompilationDisabled * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::* - * -XX:+SegmentedCodeCache + * -XX:+SegmentedCodeCache -Xmixed + * compiler.codecache.OverflowCodeCacheTest CompilationDisabled + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache -Xmixed * compiler.codecache.OverflowCodeCacheTest */ @@ -49,13 +52,21 @@ import sun.hotspot.code.BlobType; import sun.hotspot.code.CodeBlob; import java.lang.management.MemoryPoolMXBean; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.EnumSet; +class Helper { + // Uncommon signature to prevent sharing and force creation of a new adapter + public void method(float a, float b, float c, Object o) { } +} + public class OverflowCodeCacheTest { private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static boolean COMPILATION_DISABLED = false; public static void main(String[] args) { + COMPILATION_DISABLED = args.length > 0; EnumSet<BlobType> blobTypes = BlobType.getAvailable(); for (BlobType type : blobTypes) { new OverflowCodeCacheTest(type).test(); @@ -74,6 +85,8 @@ public class OverflowCodeCacheTest { System.out.println("allocating till possible..."); ArrayList<Long> blobs = new ArrayList<>(); int compilationActivityMode = -1; + // Lock compilation to be able to better control code cache space + WHITE_BOX.lockCompilation(); try { long addr; int size = (int) (getHeapSize() >> 7); @@ -88,15 +101,43 @@ public class OverflowCodeCacheTest { } } /* now, remember compilationActivityMode to check it later, after freeing, since we - possibly have no free cache for futher work */ + possibly have no free cache for further work */ compilationActivityMode = WHITE_BOX.getCompilationActivityMode(); + + // Use smallest allocation size to make sure all of the available space + // is filled up. Don't free these below to put some pressure on the sweeper. + while ((addr = WHITE_BOX.allocateCodeBlob(1, type.id)) != 0) { } } finally { + try { + // Trigger creation of a new adapter for Helper::method + // which will fail because we are out of code cache space. + Helper helper = new Helper(); + } catch (VirtualMachineError e) { + // Expected + } + // Free code cache space for (Long blob : blobs) { WHITE_BOX.freeCodeBlob(blob); } + + // Convert some nmethods to zombie and then free them to re-enable compilation + WHITE_BOX.unlockCompilation(); + WHITE_BOX.forceNMethodSweep(); + WHITE_BOX.forceNMethodSweep(); + + // Trigger compilation of Helper::method which will hit an assert because + // adapter creation failed above due to a lack of code cache space. + Helper helper = new Helper(); + for (int i = 0; i < 100_000; i++) { + helper.method(0, 0, 0, null); + } + } + // Only check this if compilation is disabled, otherwise the sweeper might have + // freed enough nmethods to allow for re-enabling compilation. + if (COMPILATION_DISABLED) { + Asserts.assertNotEquals(compilationActivityMode, 1 /* run_compilation*/, + "Compilation must be disabled when CodeCache(CodeHeap) overflows"); } - Asserts.assertNotEquals(compilationActivityMode, 1 /* run_compilation*/, - "Compilation must be disabled when CodeCache(CodeHeap) overflows"); } private long getHeapSize() { diff --git a/test/hotspot/jtreg/compiler/codecache/stress/ReturnBlobToWrongHeapTest.java b/test/hotspot/jtreg/compiler/codecache/stress/ReturnBlobToWrongHeapTest.java index 37d570e460f52f9995cac40d6e41020569beefbe..1ef65182a0e9b6d0f666e0cc3cae2a97a80494c6 100644 --- a/test/hotspot/jtreg/compiler/codecache/stress/ReturnBlobToWrongHeapTest.java +++ b/test/hotspot/jtreg/compiler/codecache/stress/ReturnBlobToWrongHeapTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ * -XX:+SegmentedCodeCache * -XX:ReservedCodeCacheSize=16M * -XX:CodeCacheMinBlockLength=1 + * -XX:CICompilerCount=2 * compiler.codecache.stress.ReturnBlobToWrongHeapTest */ diff --git a/test/hotspot/jtreg/compiler/escapeAnalysis/TestIterativeEA.java b/test/hotspot/jtreg/compiler/escapeAnalysis/TestIterativeEA.java new file mode 100644 index 0000000000000000000000000000000000000000..ef4db4635164f89216fd93babcf3ae23250126be --- /dev/null +++ b/test/hotspot/jtreg/compiler/escapeAnalysis/TestIterativeEA.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8276455 + * @summary Test C2 iterative Escape Analysis + * @library /test/lib / + * + * @requires vm.flagless + * @requires vm.compiler2.enabled & vm.debug == true + * + * @run driver TestIterativeEA + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestIterativeEA { + + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-server", "-XX:-TieredCompilation", "-Xbatch", "-XX:+PrintEliminateAllocations", + Launcher.class.getName()); + + OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + + System.out.println(analyzer.getOutput()); + + analyzer.shouldHaveExitValue(0); + analyzer.shouldContain("++++ Eliminated: 26 Allocate"); + analyzer.shouldContain("++++ Eliminated: 48 Allocate"); + analyzer.shouldContain("++++ Eliminated: 78 Allocate"); + } + + static class A { + int i; + + public A(int i) { + this.i = i; + } + } + + static class B { + A a; + + public B(A a) { + this.a = a; + } + } + + static class C { + B b; + + public C(B b) { + this.b = b; + } + } + + static int test(int i) { + C c = new C(new B(new A(i))); + return c.b.a.i; + } + + static class Launcher { + public static void main(String[] args) { + for (int i = 0; i < 12000; ++i) { + int j = test(i); + } + } + } + +} diff --git a/test/hotspot/jtreg/compiler/exceptions/TestLateMHInlineExceptions.java b/test/hotspot/jtreg/compiler/exceptions/TestLateMHInlineExceptions.java new file mode 100644 index 0000000000000000000000000000000000000000..6949c9948dfb5fe3eb8ead10a27163a75174369b --- /dev/null +++ b/test/hotspot/jtreg/compiler/exceptions/TestLateMHInlineExceptions.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8275638 8278966 + * @summary GraphKit::combine_exception_states fails with "matching stack sizes" assert + * + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestLateMHInlineExceptions::m + * -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline TestLateMHInlineExceptions + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacements -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * TestLateMHInlineExceptions + * + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class TestLateMHInlineExceptions { + public static void main(String[] args) throws Throwable { + TestLateMHInlineExceptions test = new TestLateMHInlineExceptions(); + for (int i = 0; i < 20_000; i++) { + test1(test); + try { + test1(null); + } catch (NullPointerException npe) { + } + test2(test); + test2(null); + test3(test); + try { + test3(null); + } catch (NullPointerException npe) { + } + test4(test); + test4(null); + test5(test); + try { + test5(null); + } catch (NullPointerException npe) { + } + test6(test); + try { + test6(null); + } catch (NullPointerException npe) { + } + } + } + + void m() { + } + + static void nothing(Throwable t) { + } + + static final MethodHandle mh; + static final MethodHandle mh_nothing; + static final MethodHandle mh2; + static final MethodHandle mh3; + + static { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + try { + mh = lookup.findVirtual(TestLateMHInlineExceptions.class, "m", MethodType.methodType(void.class)); + mh_nothing = lookup.findStatic(TestLateMHInlineExceptions.class, "nothing", MethodType.methodType(void.class, Throwable.class)); + mh2 = MethodHandles.tryFinally(mh, mh_nothing); + mh3 = MethodHandles.catchException(mh, Throwable.class, mh_nothing); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + throw new RuntimeException("Method handle lookup failed"); + } catch (IllegalAccessException e) { + e.printStackTrace(); + throw new RuntimeException("Method handle lookup failed"); + } + } + + private static void test1(TestLateMHInlineExceptions test) throws Throwable { + mh.invokeExact(test); + } + + private static void test2(TestLateMHInlineExceptions test) throws Throwable { + try { + mh.invokeExact(test); + } catch (NullPointerException npe) { + } + } + + private static void inlined(TestLateMHInlineExceptions test) throws Throwable { + mh.invokeExact(test); + } + + + private static void test3(TestLateMHInlineExceptions test) throws Throwable { + inlined(test); + } + + private static void test4(TestLateMHInlineExceptions test) throws Throwable { + try { + inlined(test); + } catch (NullPointerException npe) { + } + } + + private static void test5(TestLateMHInlineExceptions test) throws Throwable { + mh2.invokeExact(test); + } + + private static void test6(TestLateMHInlineExceptions test) throws Throwable { + mh3.invokeExact(test); + } +} diff --git a/test/hotspot/jtreg/compiler/inlining/ResolvedClassTest.java b/test/hotspot/jtreg/compiler/inlining/ResolvedClassTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dfeee6cdd7b1075eb157d53dba07afa49095966b --- /dev/null +++ b/test/hotspot/jtreg/compiler/inlining/ResolvedClassTest.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8279515 + * + * @requires vm.flagless + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * + * @run driver compiler.jsr292.ResolvedClassTest + */ + +package compiler.jsr292; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.io.IOException; + +public class ResolvedClassTest { + /* ======================================================================== */ + static void testStatic() throws IOException { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+IgnoreUnrecognizedVMOptions", "-showversion", + "-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining", + "-Xbatch", "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly," + TestStatic.class.getName() + "::test", + TestStatic.class.getName()); + + OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + + analyzer.shouldHaveExitValue(0); + + analyzer.shouldNotContain("TestStatic$A::m (1 bytes) not inlineable"); + analyzer.shouldNotContain("TestStatic$A::m (1 bytes) no static binding"); + + analyzer.shouldContain("TestStatic$A::m (1 bytes) inline"); + } + + static class TestStatic { + static class A { + static void m() {} + } + static class B extends A {} + + // @DontInline + static void test() { + B.m(); // invokestatic B "m" => A::m + } + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(); + } + } + } + + /* ======================================================================== */ + static void testStaticInit() throws IOException { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+IgnoreUnrecognizedVMOptions", "-showversion", + "-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining", + "-Xbatch", "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly," + TestStaticInit.class.getName() + "::test", + TestStaticInit.class.getName()); + + OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + + analyzer.shouldHaveExitValue(0); + + analyzer.shouldContain("TestStaticInit$A::m (1 bytes) no static binding"); + } + + static class TestStaticInit { + static class A { + static { + for (int i = 0; i < 20_000; i++) { + TestStaticInit.test(); + } + } + + static void m() {} + } + static class B extends A {} + + // @DontInline + static void test() { + B.m(); // A::<clinit> => test() => A::m() + } + + public static void main(String[] args) { + A.m(); // trigger initialization of A + } + } + + /* ======================================================================== */ + static void testIndy() throws IOException { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+IgnoreUnrecognizedVMOptions", "-showversion", + "-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining", + "-Xbatch", "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly," + TestIndy.class.getName() + "::test", + TestIndy.class.getName()); + + OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + + analyzer.shouldHaveExitValue(0); + + analyzer.shouldNotContain("java.lang.invoke.Invokers$Holder::linkToTargetMethod (9 bytes) not inlineable"); + + analyzer.shouldContain("java.lang.invoke.Invokers$Holder::linkToTargetMethod (9 bytes) force inline by annotation"); + analyzer.shouldContain("java/lang/invoke/MethodHandle::invokeBasic (not loaded) not inlineable"); + } + + static class TestIndy { + static String str = ""; + + // @DontInline + static void test() { + String s1 = "" + str; // indy (linked) + + for (int i = 0; i < 200_000; i++) {} // trigger OSR compilation + + String s2 = "" + str; // indy (not linked) + } + + public static void main(String[] args) { + test(); + } + } + + /* ======================================================================== */ + + public static void main(String[] args) throws IOException { + testStatic(); + testStaticInit(); + testIndy(); + } +} diff --git a/test/hotspot/jtreg/compiler/interpreter/Custom.jasm b/test/hotspot/jtreg/compiler/interpreter/Custom.jasm new file mode 100644 index 0000000000000000000000000000000000000000..e52d513d2facfb221623b8cac01741fdb9d9f9e5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/interpreter/Custom.jasm @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler/interpreter; + +/* JASM simplified from the following Java pattern: + * + * public class Custom { + * + * static void test(int v) { + * int i8 = 1; + * try { + * v += 1; + * } catch (ArithmeticException exc1) { + * } finally { + * for (; i8 < 100; i8++) { + * } + * } + * } + * + */ + +super public class Custom { + + public static Method test:"(I)V" stack 2 locals 3 { + iconst_1; + istore_1; + try t0; + iinc 0, 1; + endtry t0; +Loop: + iload_1; + bipush 100; + if_icmpge Lexit; + iinc 1, 1; + goto Loop; // deoptimize here on backwards branch + catch t0 java/lang/ArithmeticException; // unreachable block + astore_2; +Lexit: + return + } + +} diff --git a/test/hotspot/jtreg/compiler/interpreter/VerifyStackWithUnreachableBlock.java b/test/hotspot/jtreg/compiler/interpreter/VerifyStackWithUnreachableBlock.java new file mode 100644 index 0000000000000000000000000000000000000000..f8aace2b31bc354bb71d7aac735dca3a9f9f33c3 --- /dev/null +++ b/test/hotspot/jtreg/compiler/interpreter/VerifyStackWithUnreachableBlock.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Alibaba Group Holding Limited. All Rights Reserved. + * 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 VerifyStackWithUnreachableBlock + * @bug 8271055 + * @compile Custom.jasm VerifyStackWithUnreachableBlock.java + * @summary Using VerifyStack for method that contains unreachable basic blocks + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+VerifyStack compiler.interpreter.VerifyStackWithUnreachableBlock + */ + +package compiler.interpreter; + +public class VerifyStackWithUnreachableBlock { + public static void main(String[] strArr) { + for (int i = 0; i < 10000; i++) { + Custom.test(i); + } + } +} diff --git a/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java b/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java index 5c9d41cb794d55cef3a51c1651c4b95a5511e37b..16c6749900d37b4ef96f40d1c41d66a7ab7ff06b 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java +++ b/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java @@ -48,6 +48,7 @@ import java.util.Base64.Decoder; import java.util.Base64.Encoder; import java.util.Objects; import java.util.Random; +import java.util.Arrays; import compiler.whitebox.CompilerWhiteBoxTest; import sun.hotspot.code.Compiler; @@ -79,9 +80,9 @@ public class TestBase64 { private static void warmup() { final int warmupCount = 20_000; - final int bufSize = 60; + final int bufSize = 15308; byte[] srcBuf = new byte[bufSize]; - byte[] encBuf = new byte[(bufSize / 3) * 4]; + byte[] encBuf = new byte[((bufSize + 2) / 3) * 4]; byte[] decBuf = new byte[bufSize]; ran.nextBytes(srcBuf); @@ -163,10 +164,13 @@ public class TestBase64 { assertEqual(resEncodeStr, encodedStr); // test int decode(byte[], byte[]) - resArr = new byte[srcArr.length]; + // JDK-8273108: Test for output buffer overrun + resArr = new byte[srcArr.length + 2]; + resArr[srcArr.length + 1] = (byte) 167; len = decoder.decode(encodedArr, resArr); assertEqual(len, srcArr.length); - assertEqual(resArr, srcArr); + assertEqual(Arrays.copyOfRange(resArr, 0, srcArr.length), srcArr); + assertEqual(resArr[srcArr.length + 1], (byte) 167); // test byte[] decode(byte[]) resArr = decoder.decode(encodedArr); diff --git a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java index 93f54bdef73f57e944e47b9381d993d80e6db35f..08f83e1b8f044469ff8c89f42b230fb32fe714f9 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java +++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java @@ -31,6 +31,7 @@ * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/bootclasspath/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+AbortVMOnCompilationFailure + * -XX:CompileCommand=compileonly,compiler.intrinsics.bmi.*::* * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI2Instructions * compiler.intrinsics.bmi.verifycode.BzhiTestI2L */ diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestTranslatedException.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestTranslatedException.java index ac2c220adb540f499655ac10eef69dc71721603d..57a505901a5b35baedf14fb0b4a6a9a25624cf30 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestTranslatedException.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestTranslatedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ /* * @test * @requires vm.jvmci - * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot:open + * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot:+open + * java.base/jdk.internal.misc * @library /compiler/jvmci/jdk.vm.ci.hotspot.test/src * @run testng/othervm * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler @@ -41,6 +42,9 @@ import java.lang.reflect.Method; import org.testng.Assert; import org.testng.annotations.Test; +import jdk.internal.misc.Unsafe; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; + public class TestTranslatedException { @SuppressWarnings("serial") public static class Untranslatable extends RuntimeException { @@ -56,7 +60,7 @@ public class TestTranslatedException { Class<?> translatedExceptionClass = Class.forName("jdk.vm.ci.hotspot.TranslatedException"); Method encode = translatedExceptionClass.getDeclaredMethod("encodeThrowable", Throwable.class); - Method decode = translatedExceptionClass.getDeclaredMethod("decodeThrowable", String.class); + Method decode = translatedExceptionClass.getDeclaredMethod("decodeThrowable", byte[].class); encode.setAccessible(true); decode.setAccessible(true); @@ -64,11 +68,50 @@ public class TestTranslatedException { for (int i = 0; i < 10; i++) { throwable = new ExceptionInInitializerError(new InvocationTargetException(new RuntimeException(String.valueOf(i), throwable), "invoke")); } - String encoding = (String) encode.invoke(null, throwable); + byte[] encoding = (byte[]) encode.invoke(null, throwable); Throwable decoded = (Throwable) decode.invoke(null, encoding); assertThrowableEquals(throwable, decoded); } + @SuppressWarnings("unchecked") + @Test + public void encodeDecodeTest2() throws Exception { + Unsafe unsafe = Unsafe.getUnsafe(); + int bufferSize = 512; + long buffer = 0L; + while (true) { + buffer = unsafe.allocateMemory(bufferSize); + try { + Throwable throwable = new ExceptionInInitializerError(new InvocationTargetException(new Untranslatable("test exception", new NullPointerException()), "invoke")); + for (int i = 0; i < 10; i++) { + throwable = new ExceptionInInitializerError(new InvocationTargetException(new RuntimeException(String.valueOf(i), throwable), "invoke")); + } + + Method encode = HotSpotJVMCIRuntime.class.getDeclaredMethod("encodeThrowable", Throwable.class, long.class, int.class); + Method decode = HotSpotJVMCIRuntime.class.getDeclaredMethod("decodeAndThrowThrowable", long.class); + encode.setAccessible(true); + decode.setAccessible(true); + + int res = (Integer) encode.invoke(null, throwable, buffer, bufferSize); + + if (res < 0) { + bufferSize = -res; + } else { + try { + decode.invoke(null, buffer); + throw new AssertionError("expected decodeAndThrowThrowable to throw an exception"); + } catch (InvocationTargetException e) { + Throwable decoded = e.getCause(); + assertThrowableEquals(throwable, decoded); + } + return; + } + } finally { + unsafe.freeMemory(buffer); + } + } + } + private static void assertThrowableEquals(Throwable original, Throwable decoded) { try { Assert.assertEquals(original == null, decoded == null); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index a995cad3f2d49a68a65aa6d5487c28e4ed2bec44..c2e8a64f2b45939f3f65ef392853ef372aafb427 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,6 +74,7 @@ public class IRNode { public static final String STORE_D = START + "StoreD" + MID + END; public static final String STORE_P = START + "StoreP" + MID + END; public static final String STORE_N = START + "StoreN" + MID + END; + public static final String STORE_VECTOR = START + "StoreVector" + MID + END; public static final String STORE_OF_CLASS = COMPOSITE_PREFIX + START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; public static final String STORE_B_OF_CLASS = COMPOSITE_PREFIX + START + "StoreB" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; public static final String STORE_C_OF_CLASS = COMPOSITE_PREFIX + START + "StoreC" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; @@ -96,6 +97,7 @@ public class IRNode { public static final String LOAD_D = START + "LoadD" + MID + END; public static final String LOAD_P = START + "LoadP" + MID + END; public static final String LOAD_N = START + "LoadN" + MID + END; + public static final String LOAD_VECTOR = START + "LoadVector" + MID + END; public static final String LOAD_OF_CLASS = COMPOSITE_PREFIX + START + "Load(B|UB|S|US|I|L|F|D|P|N)" + MID + "@\\S*"+ IS_REPLACED + LOAD_OF_CLASS_POSTFIX; public static final String LOAD_B_OF_CLASS = COMPOSITE_PREFIX + START + "LoadB" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; public static final String LOAD_UB_OF_CLASS = COMPOSITE_PREFIX + START + "LoadUB" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; @@ -113,6 +115,7 @@ public class IRNode { public static final String LOOP = START + "Loop" + MID + END; public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + END; public static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; + public static final String IF = START + "If\\b" + MID + END; public static final String CALL = START + "Call.*Java" + MID + END; public static final String CALL_OF_METHOD = COMPOSITE_PREFIX + START + "Call.*Java" + MID + IS_REPLACED + " " + END; @@ -133,6 +136,35 @@ public class IRNode { public static final String SCOPE_OBJECT = "(.*# ScObj.*" + END; public static final String MEMBAR = START + "MemBar" + MID + END; + public static final String ABS_I = START + "AbsI" + MID + END; + public static final String ABS_L = START + "AbsL" + MID + END; + public static final String ABS_F = START + "AbsF" + MID + END; + public static final String ABS_D = START + "AbsD" + MID + END; + public static final String AND_I = START + "AndI" + MID + END; + public static final String AND_L = START + "AndL" + MID + END; + public static final String XOR_I = START + "XorI" + MID + END; + public static final String XOR_L = START + "XorL" + MID + END; + public static final String LSHIFT_I = START + "LShiftI" + MID + END; + public static final String LSHIFT_L = START + "LShiftL" + MID + END; + public static final String ADD_I = START + "AddI" + MID + END; + public static final String ADD_L = START + "AddL" + MID + END; + public static final String ADD_VD = START + "AddVD" + MID + END; + public static final String SUB_I = START + "SubI" + MID + END; + public static final String SUB_L = START + "SubL" + MID + END; + public static final String SUB_F = START + "SubF" + MID + END; + public static final String SUB_D = START + "SubD" + MID + END; + public static final String MUL_I = START + "MulI" + MID + END; + public static final String MUL_L = START + "MulL" + MID + END; + public static final String CONV_I2L = START + "ConvI2L" + MID + END; + + public static final String VECTOR_CAST_B2X = START + "VectorCastB2X" + MID + END; + public static final String VECTOR_CAST_S2X = START + "VectorCastS2X" + MID + END; + public static final String VECTOR_CAST_I2X = START + "VectorCastI2X" + MID + END; + public static final String VECTOR_CAST_L2X = START + "VectorCastL2X" + MID + END; + public static final String VECTOR_CAST_F2X = START + "VectorCastF2X" + MID + END; + public static final String VECTOR_CAST_D2X = START + "VectorCastD2X" + MID + END; + public static final String VECTOR_REINTERPRET = START + "VectorReinterpret" + MID + END; + /** * Called by {@link IRMatcher} to merge special composite nodes together with additional user-defined input. */ diff --git a/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead.java b/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead.java new file mode 100644 index 0000000000000000000000000000000000000000..3c40761a77d4cab1d61a9059e90857bfac289da6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8280600 + * @summary C2: assert(!had_error) failed: bad dominance + * @run main/othervm -Xcomp -XX:CompileOnly=TestCastIIMakesMainLoopPhiDead TestCastIIMakesMainLoopPhiDead + */ + +public class TestCastIIMakesMainLoopPhiDead { + int iArr[] = new int[0]; + + void test() { + int x = 8; + try { + for (int i = 0; i < 8; i++) { + iArr[1] = 9; + for (int j = -400; 1 > j; j++) { + iArr[j] = 4; + x -= 2; + } + } + } catch (ArrayIndexOutOfBoundsException e) { + } + } + public static void main(String[] k) { + TestCastIIMakesMainLoopPhiDead t = new TestCastIIMakesMainLoopPhiDead(); + for (int i = 0; i < 3; i++) { + t.test(); + } + } +} diff --git a/test/hotspot/jtreg/compiler/loopopts/TestEliminateNullCheckWithSplitIf.java b/test/hotspot/jtreg/compiler/loopopts/TestEliminateNullCheckWithSplitIf.java new file mode 100644 index 0000000000000000000000000000000000000000..e83b23255b396f0d3b7538462a0a42f86b1e0e0b --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestEliminateNullCheckWithSplitIf.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 + * @key stress randomness + * @bug 8275610 + * @summary Null check for field access of object floats above null check resulting in a segfault. + * @requires vm.compiler2.enabled + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.loopopts.TestEliminateNullCheckWithSplitIf::test + * -XX:+UnlockDiagnosticVMOptions -XX:+StressGCM -XX:StressSeed=42 compiler.loopopts.TestEliminateNullCheckWithSplitIf + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.loopopts.TestEliminateNullCheckWithSplitIf::test + * -XX:+UnlockDiagnosticVMOptions -XX:+StressGCM -XX:+StressIGVN compiler.loopopts.TestEliminateNullCheckWithSplitIf + */ + +package compiler.loopopts; + +public class TestEliminateNullCheckWithSplitIf { + public static int[] iArrFld = new int[20]; + public static int[] iArrFld2 = new int[20]; + public static int iFld = 10; + public static MyClass obj; + + public static void main(String[] strArr) { + for (int i = 0; i < 10000; i++) { + obj = (i % 100 == 0 ? null : new MyClass()); + test(); + } + } + + // The field access obj.iFld requires a null check NC3 and adds a not-null CastPP node on the succeeded projection. + // In the first IGVN after parsing, the null check NC3 can be subsumed by the explicit null check NC2. + // (done in IfNode::simple_subsuming()). The Bool node of NC2 is also shared with the same null check NC1 earlier. + // However, C2 cannot remove the null check NC2, yet, because the IR in between the two checks are too complex + // (IfNode::search_identical() fails). + // Now, loopopts are applied: + // (1) First, the split if optimization is done. It recognizes that NC1 and NC2 are back to back null checks and removes + // the null check NC2 by splitting it through the region R which is removed afterwards. In this process, control dependent + // data nodes on the out projections of NC2 end up at the new regions R1/R2 created for each projection for R. They get + // the last nodes of the if and else block as input. For this example, R1 is a control input to the CastPP node which + // will merge both true projections. + // (2) Later in loop opts, the loop L is transformed into normal code and y will become a constant 1. + // After loopopts, another round of IGVN is done: + // (These steps also depend on the order in which they are applied in order to trigger the bug) + // (1) The region R is removed because one path is dead (a result of the split if optimization). + // (2) The new If node added by the above split if optimization is also folded. This rewires the CastPP node to + // the last control node in the If block which is the true projection of range check RC2. Up until now, the CastPP + // is still after the null check NC1. + // (3) The range check RC2 is removed because the range check RC1 already covers this range (see RangeCheck::Ideal()). + // All data nodes which are control dependent on RC2 will be rewired to the dominating range check RC1, including + // the non-null CastPP node - which now has a control input above the null check NC1. This also means that the field + // load obj.iFld now has the same early control as the CastPP (CastPP -> AddP -> LoadI). Using StressGCM can + // now schedule the obj.iFld load before the null check NC1 because the early control allows it which leads to a + // segmentation fault if obj is null. + public static void test() { + int x = iArrFld[17]; // Emits range check RC1 + if (obj != null) { // Null check NC1 + int y = 0; + for (int i = 0; i < 1; i++) { // Loop L + y++; + } + // Use additional loop to keep the rangecheck for iArrFld[y] in before loopopts. + // y will become constant 1 but only once the loop above is removed in loopopts. + x = iArrFld[y]; // Emits range check RC2 + } else { + x = iArrFld2[18]; + } + // Region R merging the if and else paths above. + if (obj != null) { // Null check NC2 + x = iArrFld2[obj.iFld]; // Emits Null check NC3 for obj.iFld + } + } +} + +class MyClass { + int iFld; +} + + + + diff --git a/test/hotspot/jtreg/compiler/loopopts/TestIterationSplitWithRegionHead.java b/test/hotspot/jtreg/compiler/loopopts/TestIterationSplitWithRegionHead.java new file mode 100644 index 0000000000000000000000000000000000000000..7a29be60908949a710222cd7f3c635c6e5ed7346 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestIterationSplitWithRegionHead.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 vm.compiler2.enabled + * @bug 8279837 + * @summary Tests infinite loop with region head in iteration split. + * @run main/othervm -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.loopopts.TestIterationSplitWithRegionHead::test + * -XX:CompileCommand=dontinline,compiler.loopopts.TestIterationSplitWithRegionHead::* + * compiler.loopopts.TestIterationSplitWithRegionHead + */ + +package compiler.loopopts; + +public class TestIterationSplitWithRegionHead { + + static boolean flagFalse = false; + + public static void main(String[] args) { + test(); + } + + public static void test() { + // 1) The loop tree is built. We find that nested loop N2 is an infinite loop and add a NeverBranch + // to the inner loop to make it reachable. But the current loop tree does not have N2, yet. The + // resulting loop tree is: + // + // Loop: N0/N0 has_call has_sfpt + // Loop: N77/N121 has_call // N1 outer + // Loop: N77/N111 has_call sfpts={ 111 97 } // N1 inner + // + // 2) beautify_loops() finds that the outer loop head of N1 is shared and thus adds a new region + // in merge_many_backedges(). As a result, the loop tree is built again. This time, the NeverBranch + // in the inner loop of N2 allows that a loop tree can be built for it: + // + // Loop: N0/N0 has_call has_sfpt + // Loop: N216/N213 limit_check profile_predicated predicated has_call sfpts={ 111 97 } // N1 shared loop head + // Loop: N196/N201 sfpts={ 201 } // N2 inner loop now discovered with the new NeverBranch + // + // However, a LoopNode is only added by beautify_loops() which won't be called until the next iteration of loop opts. + // This means that we have a Region node (N196) as head in the loop tree which cannot be handled by iteration_split_impl() + // resulting in an assertion failure. + + // Nested loop N1 + while (flagFalse) { + while (dontInlineFalse()) { + } + } + dontInlineFalse(); + + // Nested loop N2 + while (flagFalse) { + while (true) ; // Detected as infinite inner loop by C2 -> NeverBranch added + } + } + + public static boolean dontInlineFalse() { + return false; + } +} diff --git a/test/hotspot/jtreg/compiler/loopopts/TestSkeletonPredicateNegation.java b/test/hotspot/jtreg/compiler/loopopts/TestSkeletonPredicateNegation.java index cbb82a07ea0ed8229b8938a2963c346b23835ad0..759503005840b306d23d7ff2875952f206808416 100644 --- a/test/hotspot/jtreg/compiler/loopopts/TestSkeletonPredicateNegation.java +++ b/test/hotspot/jtreg/compiler/loopopts/TestSkeletonPredicateNegation.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,11 +49,11 @@ public class TestSkeletonPredicateNegation { } public void mainTest (String[] args){ - long loa11[] = new long[1987]; + long loa11[] = new long[19]; for (long lo14 : loa11) { TestSkeletonPredicateNegation.in0 = -128; - for (int i18 = 0; i18 < 52; i18++) { + for (int i18 = 0; i18 < 13; i18++) { try { loa11[TestSkeletonPredicateNegation.in0] %= 2275269548L; Math.ceil(1374905370.2785515599); diff --git a/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitAArch64.java b/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitAArch64.java index 4a66246abe76c6e537ca6f424b501cdac192eca3..86f2d55e19fd6da4ada281185a1c51f145a42818 100644 --- a/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitAArch64.java +++ b/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitAArch64.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon.com Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitAArch64DefaultFlags.java b/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitAArch64DefaultFlags.java index 67a286c6cd909941d1b505f9c1ed3ce011e1b76c..b6da173dda9d59cfe61ad818cf1086dc44f9d835 100644 --- a/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitAArch64DefaultFlags.java +++ b/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitAArch64DefaultFlags.java @@ -1,5 +1,5 @@ /* - * Copyright Amazon.com Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitNoneAArch64.java b/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitNoneAArch64.java index 7b759f605a8aded319621d74d4612786deb0ae2d..7569d9d07a630c747e85d798fb690fc98bb04a6c 100644 --- a/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitNoneAArch64.java +++ b/test/hotspot/jtreg/compiler/onSpinWait/TestOnSpinWaitNoneAArch64.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon.com Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/hotspot/jtreg/compiler/profiling/TestSharedHeadExceptionBackedges.java b/test/hotspot/jtreg/compiler/profiling/TestSharedHeadExceptionBackedges.java new file mode 100644 index 0000000000000000000000000000000000000000..e02df36fa1cc52f7d47bd74794ea09bf9a7ba388 --- /dev/null +++ b/test/hotspot/jtreg/compiler/profiling/TestSharedHeadExceptionBackedges.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8280842 + * @summary Access violation in ciTypeFlow::profiled_count + * @run main/othervm -XX:-BackgroundCompilation TestSharedHeadExceptionBackedges + */ + +public class TestSharedHeadExceptionBackedges { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(); + } + } + + static class MyException extends Exception { + } + + private static void test() { + int i = 0; + while (i < 10) { + try { + int j = 0; + i++; + if (i % 2 == 0) { + throw new MyException(); + } + do { + j++; + } while (j < 100); + + throw new MyException(); + + } catch (MyException me) { + } + } + } +} diff --git a/test/hotspot/jtreg/compiler/rangechecks/TestLongRangeCheck.java b/test/hotspot/jtreg/compiler/rangechecks/TestLongRangeCheck.java index 63a649b886b0a969fa8eb81e1ef3661571418cc3..d56d19278cfb84e435f6a41933fc8cc7095a8c2a 100644 --- a/test/hotspot/jtreg/compiler/rangechecks/TestLongRangeCheck.java +++ b/test/hotspot/jtreg/compiler/rangechecks/TestLongRangeCheck.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8259609 + * @bug 8259609 8276116 * @summary C2: optimize long range checks in long counted loops * @requires vm.compiler2.enabled * @requires vm.compMode != "Xcomp" @@ -32,7 +32,7 @@ * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * - * @run main/othervm -ea -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestLongRangeCheck + * @run main/othervm -ea -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestLongRangeCheck * */ @@ -193,6 +193,115 @@ public class TestLongRangeCheck { m.invoke(null, 0, 100, Long.MAX_VALUE, Long.MAX_VALUE - 50, 0, 50); assertIsCompiled(m); } + + test("testStridePosScalePosInIntLoop", 0, 100, 100, 0); + + test("testStrideNegScaleNegInIntLoop", 0, 100, 100, 100); + + test("testStrideNegScalePosInIntLoop", 0, 100, 100, 0); + + test("testStridePosScaleNegInIntLoop", 0, 100, 100, 99); + + test("testStridePosScalePosNotOneInIntLoop", 0, 100, 1090, 0); + + test("testStrideNegScaleNegNotOneInIntLoop", 0, 100, 1090, 1100); + + test("testStrideNegScalePosNotOneInIntLoop", 0, 100, 1090, 0); + + test("testStridePosScaleNegNotOneInIntLoop", 0, 100, 1090, 1089); + + v = ((long)Integer.MAX_VALUE / 10000) * 9999; + + test("testStridePosNotOneScalePosInIntLoop", -v, v, v * 4, 2 * v); + + test("testStrideNegNotOneScaleNegInIntLoop", -v, v, v * 4, 2 * v); + + test("testStrideNegNotOneScalePosInIntLoop", -v, v, v * 4, 2 * v); + + test("testStridePosNotOneScaleNegInIntLoop", -v, v, v * 4, 2 * v - 1); + + // offset causes overflow + { + Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod("testStridePosScalePosInIntLoop", long.class, long.class, long.class, long.class); + m.invoke(null, 0, 100, 100, 0); + compile(m); + + m.invoke(null, 0, 100, 100, 0); + assertIsCompiled(m); + try { + m.invoke(null, 0, 100, 100, Long.MAX_VALUE - 50); + throw new RuntimeException("should have thrown"); + } catch(InvocationTargetException e) { + if (!(e.getCause() instanceof IndexOutOfBoundsException)) { + throw new RuntimeException("unexpected exception"); + } + } + assertIsNotCompiled(m); + } + // no spurious deopt if the range check doesn't fail because not executed + { + Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod("testStridePosScalePosConditional", long.class, long.class, long.class, long.class, long.class, long.class); + m.invoke(null, 0, 100, 100, 0, 0, 100); + compile(m); + + m.invoke(null, 0, 100, 100, -50, 50, 100); + assertIsCompiled(m); + } + { + Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod("testStridePosScalePosConditional", long.class, long.class, long.class, long.class, long.class, long.class); + m.invoke(null, 0, 100, 100, 0, 0, 100); + compile(m); + + m.invoke(null, 0, 100, Long.MAX_VALUE, Long.MAX_VALUE - 50, 0, 50); + assertIsCompiled(m); + } + + test("testStridePosScalePosNotOneInIntLoop2", 0, 100, 1090, 0); + + test("testStrideNegScaleNegNotOneInIntLoop2", 0, 100, 1090, 1100); + + test("testStrideNegScalePosNotOneInIntLoop2", 0, 100, 1090, 0); + + test("testStridePosScaleNegNotOneInIntLoop2", 0, 100, 1090, 1089); + + { + Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod("testStridePosScalePosInIntLoopOverflow", long.class, long.class, long.class, long.class); + long stride = 1 << 14; + long scale = 1 << 15; + long offset = stride * scale * 4; + long length = offset + stride * scale * 3 + 1; + long stop = stride * 5; + + m.invoke(null, 0, stop, length, offset); + compile(m); + + m.invoke(null, 0, stop, length, offset); + // deoptimizes even though no range check fails + } + { + Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod("testStridePosScalePosInIntLoopOverflow", long.class, long.class, long.class, long.class); + long stride = 1 << 14; + long scale = 1 << 15; + long offset = stride * scale * 4; + long length = offset + stride * scale * 3 + 1; + long stop = stride * 5; + + m.invoke(null, 0, stop, length, offset); + compile(m); + + offset = 0; + stop = stride * 5; + + try { + m.invoke(null, 0, stop, length, offset); + throw new RuntimeException("should have thrown"); + } catch(InvocationTargetException e) { + if (!(e.getCause() instanceof IndexOutOfBoundsException)) { + throw new RuntimeException("unexpected exception"); + } + } + assertIsNotCompiled(m); + } } public static void testStridePosScalePos(long start, long stop, long length, long offset) { @@ -301,4 +410,177 @@ public class TestLongRangeCheck { } } } + + private static void checkInputs(long... inputs) { + for (int i = 0; i < inputs.length; i++) { + if ((long)((int)inputs[i]) != inputs[i]) { + throw new RuntimeException("bad arguments"); + } + } + } + + public static void testStridePosScalePosInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = 1; + final int stride = 1; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStrideNegScaleNegInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = -1; + final int stride = 1; + for (int i = (int)stop; i > (int)start; i -= stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStrideNegScalePosInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = 1; + final int stride = 1; + for (int i = (int)(stop-1); i >= (int)start; i -= stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStridePosScaleNegInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = -1; + final int stride = 1; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStridePosScalePosNotOneInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = 11; + final int stride = 1; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStrideNegScaleNegNotOneInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = -11; + final int stride = 1; + for (int i = (int)stop; i > (int)start; i -= stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStrideNegScalePosNotOneInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = 11; + final int stride = 1; + for (int i = (int)(stop-1); i >= (int)start; i -= stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStridePosScaleNegNotOneInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = -11; + final int stride = 1; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStridePosNotOneScalePosInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = 2; + final int stride = Integer.MAX_VALUE / 10000; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStrideNegNotOneScaleNegInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = -2; + final int stride = Integer.MAX_VALUE / 10000; + for (int i = (int)stop; i > (int)start; i -= stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStrideNegNotOneScalePosInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = 2; + final int stride = Integer.MAX_VALUE / 10000; + for (int i = (int)(stop-1); i >= (int)start; i -= stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStridePosNotOneScaleNegInIntLoop(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final long scale = -2; + final int stride = Integer.MAX_VALUE / 10000; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStridePosScalePosConditionalInIntLoop(long start, long stop, long length, long offset, long start2, long stop2) { + checkInputs(start, stop, start2, stop2); + Preconditions.checkIndex(0, length, null); + final long scale = 1; + final int stride = 1; + for (int i = (int)start; i < (int)stop; i += stride) { + if (i >= (int)start2 && i < (int)stop2) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + } + + public static void testStridePosScalePosNotOneInIntLoop2(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final int scale = 11; + final int stride = 1; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStrideNegScaleNegNotOneInIntLoop2(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final int scale = -11; + final int stride = 1; + for (int i = (int)stop; i > (int)start; i -= stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStrideNegScalePosNotOneInIntLoop2(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final int scale = 11; + final int stride = 1; + for (int i = (int)(stop-1); i >= (int)start; i -= stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStridePosScaleNegNotOneInIntLoop2(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final int scale = -11; + final int stride = 1; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } + + public static void testStridePosScalePosInIntLoopOverflow(long start, long stop, long length, long offset) { + checkInputs(start, stop); + final int scale = 1 << 15; + final int stride = 1 << 14; + for (int i = (int)start; i < (int)stop; i += stride) { + Preconditions.checkIndex(scale * i + offset, length, null); + } + } } diff --git a/test/hotspot/jtreg/compiler/uncommontrap/TraceDeoptimizationNoRealloc.java b/test/hotspot/jtreg/compiler/uncommontrap/TraceDeoptimizationNoRealloc.java index 4a371a525b3889ce5bade9e0da2c087e70051f71..4cd10a1a63e9ede9950d16ed48f84eaac10d6d2e 100644 --- a/test/hotspot/jtreg/compiler/uncommontrap/TraceDeoptimizationNoRealloc.java +++ b/test/hotspot/jtreg/compiler/uncommontrap/TraceDeoptimizationNoRealloc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @summary -XX:+TraceDeoptimization tries to print realloc'ed objects even when there are none * * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement - * -XX:+IgnoreUnrecognizedVMOptions -XX:+TraceDeoptimization + * -XX:+UnlockDiagnosticVMOptions -XX:+TraceDeoptimization * compiler.uncommontrap.TraceDeoptimizationNoRealloc */ diff --git a/test/hotspot/jtreg/compiler/vectorapi/Test8278948.java b/test/hotspot/jtreg/compiler/vectorapi/Test8278948.java new file mode 100644 index 0000000000000000000000000000000000000000..5218e10c4af6275bdafa725767f964e06046402c --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/Test8278948.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import java.util.Random; +import jdk.incubator.vector.ByteVector; +import jdk.incubator.vector.DoubleVector; +import jdk.incubator.vector.ShortVector; +import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; + +/* + * @test + * @bug 8278948 + * @summary Intermediate integer promotion vector length encoding is calculated incorrectly on x86 + * @modules jdk.incubator.vector + * @library /test/lib + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CompileThreshold=100 -XX:UseAVX=1 + * compiler.vectorapi.Test8278948 + */ +public class Test8278948 { + static final int INVOCATIONS = 10000; + + static final Random random = Utils.getRandomInstance(); + static final byte[] BYTES = new byte[8]; + static final short[] SHORTS = new short[4]; + static final double[] DOUBLES = new double[4]; + + + public static void main(String[] args) { + for (int i = 0; i < INVOCATIONS; i++) { + for (int j = 0; j < DOUBLES.length; j++) { + BYTES[j] = (byte)random.nextInt(); + } + bytesToDoubles(); + for (int j = 0; j < DOUBLES.length; j++) { + Asserts.assertEquals((double)BYTES[j], DOUBLES[j]); + } + + for (int j = 0; j < DOUBLES.length; j++) { + SHORTS[j] = (short)random.nextInt(); + } + shortsToDoubles(); + for (int j = 0; j < DOUBLES.length; j++) { + Asserts.assertEquals((double)SHORTS[j], DOUBLES[j]); + } + } + } + + static void bytesToDoubles() { + ((DoubleVector)ByteVector.fromArray(ByteVector.SPECIES_64, BYTES, 0) + .castShape(DoubleVector.SPECIES_256, 0)) + .intoArray(DOUBLES, 0); + } + + static void shortsToDoubles() { + ((DoubleVector)ShortVector.fromArray(ShortVector.SPECIES_64, SHORTS, 0) + .castShape(DoubleVector.SPECIES_256, 0)) + .intoArray(DOUBLES, 0); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestMaskedMacroLogicVector.java b/test/hotspot/jtreg/compiler/vectorapi/TestMaskedMacroLogicVector.java new file mode 100644 index 0000000000000000000000000000000000000000..e5f2e34040d288e5abe6d4a544972ce6348da4ed --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/TestMaskedMacroLogicVector.java @@ -0,0 +1,844 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8273322 + * @key randomness + * @summary Enhance macro logic optimization for masked logic operations. + * @modules jdk.incubator.vector + * @requires vm.compiler2.enabled + * @requires os.simpleArch == "x64" + * @library /test/lib / + * @run driver compiler.vectorapi.TestMaskedMacroLogicVector + */ + +package compiler.vectorapi; + +import java.util.concurrent.Callable; +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.driver.IRViolationException; +import jdk.test.lib.Asserts; +import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; +import java.util.Random; + +import jdk.incubator.vector.*; + +public class TestMaskedMacroLogicVector { + boolean [] br; + boolean [] ba; + boolean [] bb; + + short [] sr; + char [] ca; + char [] cb; + + int [] r; + int [] a; + int [] b; + int [] c; + int [] d; + int [] e; + int [] f; + + long [] rl; + long [] al; + long [] bl; + long [] cl; + + boolean [] mask; + + static boolean booleanFunc1(boolean a, boolean b) { + return a & b; + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV" , " > 0 "}) + public void testSubWordBoolean(boolean[] r, boolean[] a, boolean[] b) { + for (int i = 0; i < r.length; i++) { + r[i] = booleanFunc1(a[i], b[i]); + } + } + public void verifySubWordBoolean(boolean[] r, boolean[] a, boolean[] b) { + for (int i = 0; i < r.length; i++) { + boolean expected = booleanFunc1(a[i], b[i]); + if (r[i] != expected) { + throw new AssertionError( + String.format("at #%d: r=%b, expected = %b = booleanFunc1(%b,%b)", + i, r[i], expected, a[i], b[i])); + } + } + } + + + static short charFunc1(char a, char b) { + return (short)((a & b) & 1); + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV" , " > 0 "}) + public void testSubWordChar(short[] r, char[] a, char[] b) { + for (int i = 0; i < r.length; i++) { + r[i] = charFunc1(a[i], b[i]); + } + } + public void verifySubWordChar(short[] r, char[] a, char[] b) { + for (int i = 0; i < r.length; i++) { + short expected = charFunc1(a[i], b[i]); + if (r[i] != expected) { + throw new AssertionError( + String.format("testSubWordChar: at #%d: r=%d, expected = %d = booleanFunc1(%d,%d)", + i, r[i], expected, (int)a[i], (int)b[i])); + } + } + } + + // Case 1): Unmasked expression tree. + // P_LOP + // L_LOP R_LOP + + static int intFunc1(int a, int b, int c) { + return (a & b) ^ (a & c); + } + + @ForceInline + public void testInt1Kernel(VectorSpecies SPECIES, int [] r, int [] a, int [] b, int [] c) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + va.lanewise(VectorOperators.AND, vc) + .lanewise(VectorOperators.XOR, va.lanewise(VectorOperators.AND, vb)) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt1_Int128(int[] r, int[] a, int[] b, int[] c) { + testInt1Kernel(IntVector.SPECIES_128, r, a, b, c); + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt1_Int256(int[] r, int[] a, int[] b, int[] c) { + testInt1Kernel(IntVector.SPECIES_256, r, a, b, c); + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt1_Int512(int[] r, int[] a, int[] b, int[] c) { + testInt1Kernel(IntVector.SPECIES_512, r, a, b, c); + } + + public void verifyInt1(int[] r, int[] a, int[] b, int[] c) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc1(a[i], b[i], c[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt1: at #%d: r=%d, expected = %d = intFunc1(%d,%d,%d)", + i, r[i], expected, a[i], b[i], c[i])); + } + } + } + + // Case 2): Only right child is masked. + // P_LOP + // L_LOP R_LOP(mask) + + static int intFunc2(int a, int b, int c, boolean mask) { + return (a & b) ^ (mask == true ? a & c : a); + } + + @ForceInline + public void testInt2Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask , i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + va.lanewise(VectorOperators.AND, vb) + .lanewise(VectorOperators.XOR, + va.lanewise(VectorOperators.AND, vc, vmask)) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt2_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt2Kernel(IntVector.SPECIES_128, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt2_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt2Kernel(IntVector.SPECIES_256, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt2_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt2Kernel(IntVector.SPECIES_512, r, a, b, c, mask); + } + + public void verifyInt2(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc2(a[i], b[i], c[i], mask[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt2: at #%d: r=%d, expected = %d = intFunc2(%d,%d,%d,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i])); + } + } + } + + // Case 3): Only left child is masked. + // P_LOP + // L_LOP(mask) R_LOP + + static int intFunc3(int a, int b, int c, boolean mask) { + return (mask == true ? a & b : a) ^ (a & c); + } + + @ForceInline + public void testInt3Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask , i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + va.lanewise(VectorOperators.AND, vb, vmask) + .lanewise(VectorOperators.XOR, + va.lanewise(VectorOperators.AND, vc)) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt3_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt3Kernel(IntVector.SPECIES_128, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt3_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt3Kernel(IntVector.SPECIES_256, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt3_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt3Kernel(IntVector.SPECIES_512, r, a, b, c, mask); + } + + + @ForceInline + public void verifyInt3(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc3(a[i], b[i], c[i], mask[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt3: at #%d: r=%d, expected = %d = intFunc3(%d,%d,%d,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i])); + } + } + } + + // Case 4): Both child nodes are masked. + // P_LOP + // L_LOP(mask) R_LOP(mask) + + static int intFunc4(int a, int b, int c, boolean mask) { + return (mask == true ? b & a : b) ^ (mask == true ? c & a : c); + } + + @ForceInline + public void testInt4Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask , i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + vb.lanewise(VectorOperators.AND, va, vmask) + .lanewise(VectorOperators.XOR, + vc.lanewise(VectorOperators.AND, va, vmask)) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"AndV", " > 0 ", "XorV", " > 0 "}) + public void testInt4_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt4Kernel(IntVector.SPECIES_128, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"AndV", " > 0 ", "XorV", " > 0 "}) + public void testInt4_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt4Kernel(IntVector.SPECIES_256, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"AndV", " > 0 ", "XorV", " > 0 "}) + public void testInt4_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt4Kernel(IntVector.SPECIES_512, r, a, b, c, mask); + } + + public void verifyInt4(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc4(a[i], b[i], c[i], mask[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt4: at #%d: r=%d, expected = %d = intFunc4(%d,%d,%d,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i])); + } + } + } + + // Case 5): Parent is masked with unmasked child expressions. + // P_LOP(mask) + // L_LOP R_LOP + + static int intFunc5(int a, int b, int c, boolean mask) { + return mask == true ? ((a & b) ^ (a & c)) : (a & b); + } + + @ForceInline + public void testInt5Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask , i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + va.lanewise(VectorOperators.AND, vb) + .lanewise(VectorOperators.XOR, + va.lanewise(VectorOperators.AND, vc), vmask) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt5_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt5Kernel(IntVector.SPECIES_128, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt5_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt5Kernel(IntVector.SPECIES_256, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt5_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt5Kernel(IntVector.SPECIES_512, r, a, b, c, mask); + } + + @ForceInline + public void verifyInt5(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc5(a[i], b[i], c[i], mask[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt5: at #%d: r=%d, expected = %d = intFunc5(%d,%d,%d,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i])); + } + } + } + + // Case 6): Parent and right child are masked. + // P_LOP(mask) + // L_LOP R_LOP(mask) + + static int intFunc6(int a, int b, int c, boolean mask) { + return mask == true ? ((a & b) ^ (mask == true ? a & c : a)) : (a & b); + } + + @ForceInline + public void testInt6Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask , i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + va.lanewise(VectorOperators.AND, vb) + .lanewise(VectorOperators.XOR, + va.lanewise(VectorOperators.AND, vc, vmask), vmask) + .intoArray(r, i); + } + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt6_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt6Kernel(IntVector.SPECIES_128, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt6_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt6Kernel(IntVector.SPECIES_256, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt6_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt6Kernel(IntVector.SPECIES_512, r, a, b, c, mask); + } + + + public void verifyInt6(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc6(a[i], b[i], c[i], mask[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt6: at #%d: r=%d, expected = %d = intFunc6(%d,%d,%d,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i])); + } + } + } + + // Case 7): Parent and left child are masked. + // P_LOP(mask) + // L_LOP(mask) R_LOP + + static int intFunc7(int a, int b, int c, boolean mask) { + return mask == true ? ((mask == true ? a & b : a) ^ (a & c)) : a; + } + + @ForceInline + public void testInt7Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask , i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + va.lanewise(VectorOperators.AND, vb, vmask) + .lanewise(VectorOperators.XOR, + va.lanewise(VectorOperators.AND, vc), vmask) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt7_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt7Kernel(IntVector.SPECIES_128, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt7_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt7Kernel(IntVector.SPECIES_256, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt7_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt7Kernel(IntVector.SPECIES_512, r, a, b, c, mask); + } + + public void verifyInt7(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc7(a[i], b[i], c[i], mask[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt7: at #%d: r=%d, expected = %d = intFunc7(%d,%d,%d,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i])); + } + } + } + + // Case 8): Parent and both child expressions are masked. + // P_LOP(mask) + // L_LOP(mask) R_LOP (mask) + + static int intFunc8(int a, int b, int c, boolean mask) { + return mask == true ? ((mask == true ? b & a : b) ^ (mask == true ? c & a : c)) : b; + } + + @ForceInline + public void testInt8Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask , i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + vb.lanewise(VectorOperators.AND, va, vmask) + .lanewise(VectorOperators.XOR, + vc.lanewise(VectorOperators.AND, va, vmask), vmask) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt8_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt8Kernel(IntVector.SPECIES_128, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt8_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt8Kernel(IntVector.SPECIES_256, r, a, b, c, mask); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testInt8_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + testInt8Kernel(IntVector.SPECIES_512, r, a, b, c, mask); + } + + public void verifyInt8(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc8(a[i], b[i], c[i], mask[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt8: at #%d: r=%d, expected = %d = intFunc8(%d,%d,%d,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i])); + } + } + } + + + // ===================================================== // + + static long longFunc(long a, long b, long c) { + long v1 = (a & b) ^ (a & c) ^ (b & c); + long v2 = (~a & b) | (~b & c) | (~c & a); + return v1 & v2; + } + + @ForceInline + public void testLongKernel(VectorSpecies SPECIES, long[] r, long[] a, long[] b, long[] c) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + LongVector va = LongVector.fromArray(SPECIES, a, i); + LongVector vb = LongVector.fromArray(SPECIES, b, i); + LongVector vc = LongVector.fromArray(SPECIES, c, i); + + va.lanewise(VectorOperators.AND, vb) + .lanewise(VectorOperators.XOR, va.lanewise(VectorOperators.AND, vc)) + .lanewise(VectorOperators.XOR, vb.lanewise(VectorOperators.AND, vc)) + .lanewise(VectorOperators.AND, + va.lanewise(VectorOperators.NOT).lanewise(VectorOperators.AND, vb) + .lanewise(VectorOperators.OR, vb.lanewise(VectorOperators.NOT).lanewise(VectorOperators.AND, vc)) + .lanewise(VectorOperators.OR, vc.lanewise(VectorOperators.NOT).lanewise(VectorOperators.AND, va))) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testLong_Long256(long[] r, long[] a, long[] b, long[] c) { + testLongKernel(LongVector.SPECIES_256, r, a, b, c); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {"MacroLogicV", " > 0 "}) + public void testLong_Long512(long[] r, long[] a, long[] b, long[] c) { + testLongKernel(LongVector.SPECIES_512, r, a, b, c); + } + + public void verifyLong(long[] r, long[] a, long[] b, long[] c) { + for (int i = 0; i < r.length; i++) { + long expected = longFunc(a[i], b[i], c[i]); + if (r[i] != expected) { + throw new AssertionError( + String.format("testLong: at #%d: r=%d, expected = %d = longFunc(%d,%d,%d)", + i, r[i], expected, a[i], b[i], c[i])); + } + } + } + + // ===================================================== // + + private static final Random R = Utils.getRandomInstance(); + + static boolean[] fillBooleanRandom(Callable<boolean[]> factory) { + try { + boolean[] arr = factory.call(); + for (int i = 0; i < arr.length; i++) { + arr[i] = R.nextBoolean(); + } + return arr; + } catch (Exception e) { + throw new InternalError(e); + } + } + static char[] fillCharRandom(Callable<char[]> factory) { + try { + char[] arr = factory.call(); + for (int i = 0; i < arr.length; i++) { + arr[i] = (char)R.nextInt(); + } + return arr; + } catch (Exception e) { + throw new InternalError(e); + } + } + static int[] fillIntRandom(Callable<int[]> factory) { + try { + int[] arr = factory.call(); + for (int i = 0; i < arr.length; i++) { + arr[i] = R.nextInt(); + } + return arr; + } catch (Exception e) { + throw new InternalError(e); + } + } + static long[] fillLongRandom(Callable<long[]> factory) { + try { + long[] arr = factory.call(); + for (int i = 0; i < arr.length; i++) { + arr[i] = R.nextLong(); + } + return arr; + } catch (Exception e) { + throw new InternalError(e); + } + } + + // ===================================================== // + + static final int SIZE = 512; + + @Run(test = {"testInt4_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt4_Int128() { + for (int i = 0; i < 10000; i++) { + testInt4_Int128(r, a, b, c, mask); + verifyInt4(r, a, b, c, mask); + } + } + @Run(test = {"testInt4_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt4_Int256() { + for (int i = 0; i < 10000; i++) { + testInt4_Int256(r, a, b, c, mask); + verifyInt4(r, a, b, c, mask); + } + } + @Run(test = {"testInt4_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt4_Int512() { + for (int i = 0; i < 10000; i++) { + testInt4_Int512(r, a, b, c, mask); + verifyInt4(r, a, b, c, mask); + } + } + + @Run(test = {"testSubWordBoolean"}, mode = RunMode.STANDALONE) + public void kernel_test_SubWordBoolean() { + for (int i = 0; i < 10000; i++) { + testSubWordBoolean(br, ba, bb); + verifySubWordBoolean(br, ba, bb); + } + } + + @Run(test = {"testSubWordChar"}, mode = RunMode.STANDALONE) + public void kernel_test_SubWordChar() { + for (int i = 0; i < 10000; i++) { + testSubWordChar(sr, ca, cb); + verifySubWordChar(sr, ca, cb); + } + } + + @Run(test = {"testInt1_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt1_Int128() { + for (int i = 0; i < 10000; i++) { + testInt1_Int128(r, a, b, c); + verifyInt1(r, a, b, c); + } + } + @Run(test = {"testInt1_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt1_Int256() { + for (int i = 0; i < 10000; i++) { + testInt1_Int256(r, a, b, c); + verifyInt1(r, a, b, c); + } + } + @Run(test = {"testInt1_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt1_Int512() { + for (int i = 0; i < 10000; i++) { + testInt1_Int512(r, a, b, c); + verifyInt1(r, a, b, c); + } + } + + @Run(test = {"testInt2_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt2_Int128() { + for (int i = 0; i < 10000; i++) { + testInt2_Int128(r, a, b, c, mask); + verifyInt2(r, a, b, c, mask); + } + } + @Run(test = {"testInt2_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt2_Int256() { + for (int i = 0; i < 10000; i++) { + testInt2_Int256(r, a, b, c, mask); + verifyInt2(r, a, b, c, mask); + } + } + @Run(test = {"testInt2_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt2_Int512() { + for (int i = 0; i < 10000; i++) { + testInt2_Int512(r, a, b, c, mask); + verifyInt2(r, a, b, c, mask); + } + } + + @Run(test = {"testInt3_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt3_Int128() { + for (int i = 0; i < 10000; i++) { + testInt3_Int128(r, a, b, c, mask); + verifyInt3(r, a, b, c, mask); + } + } + @Run(test = {"testInt3_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt3_Int256() { + for (int i = 0; i < 10000; i++) { + testInt3_Int256(r, a, b, c, mask); + verifyInt3(r, a, b, c, mask); + } + } + @Run(test = {"testInt3_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt3_Int512() { + for (int i = 0; i < 10000; i++) { + testInt3_Int512(r, a, b, c, mask); + verifyInt3(r, a, b, c, mask); + } + } + + @Run(test = {"testInt5_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt5_128() { + for (int i = 0; i < 10000; i++) { + testInt5_Int128(r, a, b, c, mask); + verifyInt5(r, a, b, c, mask); + } + } + @Run(test = {"testInt5_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt5_256() { + for (int i = 0; i < 10000; i++) { + testInt5_Int256(r, a, b, c, mask); + verifyInt5(r, a, b, c, mask); + } + } + @Run(test = {"testInt5_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt5_Int512() { + for (int i = 0; i < 10000; i++) { + testInt5_Int512(r, a, b, c, mask); + verifyInt5(r, a, b, c, mask); + } + } + + @Run(test = {"testInt6_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt6_Int128() { + for (int i = 0; i < 10000; i++) { + testInt6_Int128(r, a, b, c, mask); + verifyInt6(r, a, b, c, mask); + } + } + @Run(test = {"testInt6_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt6_Int256() { + for (int i = 0; i < 10000; i++) { + testInt6_Int256(r, a, b, c, mask); + verifyInt6(r, a, b, c, mask); + } + } + @Run(test = {"testInt6_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt6_Int512() { + for (int i = 0; i < 10000; i++) { + testInt6_Int512(r, a, b, c, mask); + verifyInt6(r, a, b, c, mask); + } + } + + @Run(test = {"testInt7_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt7_Int128() { + for (int i = 0; i < 10000; i++) { + testInt7_Int128(r, a, b, c, mask); + verifyInt7(r, a, b, c, mask); + } + } + @Run(test = {"testInt7_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt7_Int256() { + for (int i = 0; i < 10000; i++) { + testInt7_Int256(r, a, b, c, mask); + verifyInt7(r, a, b, c, mask); + } + } + @Run(test = {"testInt7_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt7_Int512() { + for (int i = 0; i < 10000; i++) { + testInt7_Int512(r, a, b, c, mask); + verifyInt7(r, a, b, c, mask); + } + } + + @Run(test = {"testInt8_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt8_Int128() { + for (int i = 0; i < 10000; i++) { + testInt8_Int128(r, a, b, c, mask); + verifyInt8(r, a, b, c, mask); + } + } + @Run(test = {"testInt8_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt8_Int256() { + for (int i = 0; i < 10000; i++) { + testInt8_Int256(r, a, b, c, mask); + verifyInt8(r, a, b, c, mask); + } + } + @Run(test = {"testInt8_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt8_Int512() { + for (int i = 0; i < 10000; i++) { + testInt8_Int512(r, a, b, c, mask); + verifyInt8(r, a, b, c, mask); + } + } + + @Run(test = {"testLong_Long256"}, mode = RunMode.STANDALONE) + public void kernel_testLong_Long256() { + for (int i = 0; i < 10000; i++) { + testLong_Long256(rl, al, bl, cl); + verifyLong(rl, al, bl, cl); + } + } + @Run(test = {"testLong_Long512"}, mode = RunMode.STANDALONE) + public void kernel_testLong_Long512() { + for (int i = 0; i < 10000; i++) { + testLong_Long512(rl, al, bl, cl); + verifyLong(rl, al, bl, cl); + } + } + + public TestMaskedMacroLogicVector() { + br = new boolean[SIZE]; + ba = fillBooleanRandom((()-> new boolean[SIZE])); + bb = fillBooleanRandom((()-> new boolean[SIZE])); + + sr = new short[SIZE]; + ca = fillCharRandom((()-> new char[SIZE])); + cb = fillCharRandom((()-> new char[SIZE])); + + r = new int[SIZE]; + a = fillIntRandom(()-> new int[SIZE]); + b = fillIntRandom(()-> new int[SIZE]); + c = fillIntRandom(()-> new int[SIZE]); + d = fillIntRandom(()-> new int[SIZE]); + e = fillIntRandom(()-> new int[SIZE]); + f = fillIntRandom(()-> new int[SIZE]); + + rl = new long[SIZE]; + al = fillLongRandom(() -> new long[SIZE]); + bl = fillLongRandom(() -> new long[SIZE]); + cl = fillLongRandom(() -> new long[SIZE]); + + mask = fillBooleanRandom((()-> new boolean[SIZE])); + } + + public static void main(String[] args) { + TestFramework.runWithFlags("-XX:-TieredCompilation", + "-XX:UseAVX=3", + "--add-modules=jdk.incubator.vector", + "-XX:CompileThresholdScaling=0.3"); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLoadStoreTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLoadStoreTest.java index 669608b824b6a2aae78d7e519e2846bba14bd3e6..655681f87a83cfa5e5daae9ecb71d063d79ae227 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLoadStoreTest.java +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLoadStoreTest.java @@ -49,6 +49,18 @@ import org.testng.annotations.Test; * @run testng/othervm -XX:-TieredCompilation -XX:CompileThreshold=100 compiler.vectorapi.VectorMaskLoadStoreTest */ +/** + * @test + * @bug 8278584 + * @library /test/lib + * @summary Test the codegen for C2's VectorLongToMaskNode + * "-XX:DisableIntrinsic=_VectorMaskOp" is required to break "VectorMaskToLong (VectorLongToMask l) ==> l" opt. + * This is because when _VectorMaskOp is disabled, VectorMaskToLong won't be generated. + * @modules jdk.incubator.vector + * + * @run testng/othervm -XX:-TieredCompilation -XX:CompileThreshold=100 -XX:+UnlockDiagnosticVMOptions + * -XX:DisableIntrinsic=_VectorMaskOp compiler.vectorapi.VectorMaskLoadStoreTest + */ public class VectorMaskLoadStoreTest{ diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX1.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX1.java new file mode 100644 index 0000000000000000000000000000000000000000..a83364fa51cd8a029a80fdb2bad12089f28b5ab1 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX1.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape; + +import compiler.vectorapi.reshape.tests.TestVectorCast; +import compiler.vectorapi.reshape.utils.TestCastMethods; +import compiler.vectorapi.reshape.utils.VectorReshapeHelper; + +/* + * @test + * @bug 8259610 + * @modules jdk.incubator.vector + * @modules java.base/jdk.internal.misc + * @summary Test that vector cast intrinsics work as intended on avx1. + * @requires vm.cpu.features ~= ".*avx.*" + * @library /test/lib / + * @run driver compiler.vectorapi.reshape.TestVectorCastAVX1 + */ +public class TestVectorCastAVX1 { + public static void main(String[] args) { + VectorReshapeHelper.runMainHelper( + TestVectorCast.class, + TestCastMethods.AVX1_CAST_TESTS.stream(), + "-XX:UseAVX=1"); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX2.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX2.java new file mode 100644 index 0000000000000000000000000000000000000000..1b50613598b2669b12b7aa2c43311d7d4d48a69e --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX2.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape; + +import compiler.vectorapi.reshape.tests.TestVectorCast; +import compiler.vectorapi.reshape.utils.TestCastMethods; +import compiler.vectorapi.reshape.utils.VectorReshapeHelper; + +/* + * @test + * @bug 8259610 + * @modules jdk.incubator.vector + * @modules java.base/jdk.internal.misc + * @summary Test that vector cast intrinsics work as intended on avx2. + * @requires vm.cpu.features ~= ".*avx2.*" + * @library /test/lib / + * @run driver compiler.vectorapi.reshape.TestVectorCastAVX2 + */ +public class TestVectorCastAVX2 { + public static void main(String[] args) { + VectorReshapeHelper.runMainHelper( + TestVectorCast.class, + TestCastMethods.AVX2_CAST_TESTS.stream(), + "-XX:UseAVX=2"); + } +} + diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512.java new file mode 100644 index 0000000000000000000000000000000000000000..749c6a21e06ef4c3d3f1bc01c59f644da12a134f --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape; + +import compiler.vectorapi.reshape.tests.TestVectorCast; +import compiler.vectorapi.reshape.utils.TestCastMethods; +import compiler.vectorapi.reshape.utils.VectorReshapeHelper; + +/* + * @test + * @bug 8259610 + * @modules jdk.incubator.vector + * @modules java.base/jdk.internal.misc + * @summary Test that vector cast intrinsics work as intended on avx512. + * @requires vm.cpu.features ~= ".*avx512.*" + * @library /test/lib / + * @run driver compiler.vectorapi.reshape.TestVectorCastAVX512 + */ +public class TestVectorCastAVX512 { + public static void main(String[] args) { + VectorReshapeHelper.runMainHelper( + TestVectorCast.class, + TestCastMethods.AVX512_CAST_TESTS.stream(), + "-XX:UseAVX=3"); + } +} + diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512BW.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512BW.java new file mode 100644 index 0000000000000000000000000000000000000000..d9fbaf92d844c8595134fc5c295685973ae7bf5f --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512BW.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape; + +import compiler.vectorapi.reshape.tests.TestVectorCast; +import compiler.vectorapi.reshape.utils.TestCastMethods; +import compiler.vectorapi.reshape.utils.VectorReshapeHelper; + +/* + * @test + * @bug 8278623 + * @modules jdk.incubator.vector + * @modules java.base/jdk.internal.misc + * @summary Test that vector cast intrinsics work as intended on avx512bw. + * @requires vm.cpu.features ~= ".*avx512bw.*" + * @library /test/lib / + * @run driver compiler.vectorapi.reshape.TestVectorCastAVX512BW + */ +public class TestVectorCastAVX512BW { + public static void main(String[] args) { + VectorReshapeHelper.runMainHelper( + TestVectorCast.class, + TestCastMethods.AVX512BW_CAST_TESTS.stream(), + "-XX:UseAVX=3"); + } +} + diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512DQ.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512DQ.java new file mode 100644 index 0000000000000000000000000000000000000000..8799cccd918415912c378b4245bc680bbab0a280 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastAVX512DQ.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape; + +import compiler.vectorapi.reshape.tests.TestVectorCast; +import compiler.vectorapi.reshape.utils.TestCastMethods; +import compiler.vectorapi.reshape.utils.VectorReshapeHelper; + +/* + * @test + * @bug 8259610 + * @modules jdk.incubator.vector + * @modules java.base/jdk.internal.misc + * @summary Test that vector cast intrinsics work as intended on avx512dq. + * @requires vm.cpu.features ~= ".*avx512dq.*" + * @library /test/lib / + * @run driver compiler.vectorapi.reshape.TestVectorCastAVX512DQ + */ +public class TestVectorCastAVX512DQ { + public static void main(String[] args) { + VectorReshapeHelper.runMainHelper( + TestVectorCast.class, + TestCastMethods.AVX512DQ_CAST_TESTS.stream(), + "-XX:UseAVX=3"); + } +} + diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastNeon.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastNeon.java new file mode 100644 index 0000000000000000000000000000000000000000..11777a3ccfcf8b211021285017fcb0d4f3f75de5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastNeon.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape; + +import compiler.vectorapi.reshape.tests.TestVectorCast; +import compiler.vectorapi.reshape.utils.TestCastMethods; +import compiler.vectorapi.reshape.utils.VectorReshapeHelper; + +/* + * @test + * @bug 8259610 + * @modules jdk.incubator.vector + * @modules java.base/jdk.internal.misc + * @summary Test that vector cast intrinsics work as intended on neon. + * @requires vm.cpu.features ~= ".*simd.*" + * @library /test/lib / + * @run driver compiler.vectorapi.reshape.TestVectorCastNeon + */ +public class TestVectorCastNeon { + public static void main(String[] args) { + VectorReshapeHelper.runMainHelper( + TestVectorCast.class, + TestCastMethods.NEON_CAST_TESTS.stream(), + "-XX:+UseNeon"); + } +} + + diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastSVE.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastSVE.java new file mode 100644 index 0000000000000000000000000000000000000000..614e8e870de43ae4a286258a6379f5f6f44bbde5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorCastSVE.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape; + +import compiler.vectorapi.reshape.tests.TestVectorCast; +import compiler.vectorapi.reshape.utils.TestCastMethods; +import compiler.vectorapi.reshape.utils.VectorReshapeHelper; + +/* + * @test + * @bug 8259610 + * @modules jdk.incubator.vector + * @modules java.base/jdk.internal.misc + * @summary Test that vector cast intrinsics work as intended on sve. + * @requires vm.cpu.features ~= ".*sve.*" + * @library /test/lib / + * @run driver compiler.vectorapi.reshape.TestVectorCastSVE + */ +public class TestVectorCastSVE { + public static void main(String[] args) { + VectorReshapeHelper.runMainHelper( + TestVectorCast.class, + TestCastMethods.SVE_CAST_TESTS.stream(), + "-XX:UseSVE=1"); + } +} + + diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java new file mode 100644 index 0000000000000000000000000000000000000000..538736193ef25eea797e41b1628425e13ac9d90c --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/TestVectorReinterpret.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape; + +import compiler.vectorapi.reshape.tests.TestVectorDoubleExpandShrink; +import compiler.vectorapi.reshape.tests.TestVectorExpandShrink; +import compiler.vectorapi.reshape.tests.TestVectorRebracket; +import compiler.vectorapi.reshape.utils.VectorReshapeHelper; +import compiler.vectorapi.reshape.utils.VectorSpeciesPair; +import java.util.List; +import jdk.incubator.vector.VectorShape; +import jdk.incubator.vector.VectorSpecies; + +/* + * @test + * @bug 8259610 + * @modules jdk.incubator.vector + * @modules java.base/jdk.internal.misc + * @summary Test that vector reinterpret intrinsics work as intended. + * @library /test/lib / + * @run driver compiler.vectorapi.reshape.TestVectorReinterpret + */ +public class TestVectorReinterpret { + private static final List<VectorShape> SHAPE_LIST = List.of(VectorShape.values()); + private static final List<Class<?>> ETYPE_LIST = List.of( + byte.class, short.class, int.class, long.class, float.class, double.class + ); + + public static void main(String[] args) { + VectorReshapeHelper.runMainHelper( + TestVectorExpandShrink.class, + SHAPE_LIST.stream() + .flatMap(s -> SHAPE_LIST.stream() + .filter(t -> t.vectorBitSize() != s.vectorBitSize()) + .map(t -> VectorSpeciesPair.makePair(VectorSpecies.of(byte.class, s), + VectorSpecies.of(byte.class, t)))) + ); + + VectorReshapeHelper.runMainHelper( + TestVectorDoubleExpandShrink.class, + SHAPE_LIST.stream() + .flatMap(s -> SHAPE_LIST.stream() + .filter(t -> t.vectorBitSize() != s.vectorBitSize()) + .map(t -> VectorSpeciesPair.makePair(VectorSpecies.of(byte.class, s), + VectorSpecies.of(byte.class, t)))) + ); + + VectorReshapeHelper.runMainHelper( + TestVectorRebracket.class, + SHAPE_LIST.stream() + .flatMap(shape -> ETYPE_LIST.stream() + .flatMap(etype -> ETYPE_LIST.stream() + .filter(ftype -> ftype != etype) + .map(ftype -> VectorSpeciesPair.makePair(VectorSpecies.of(etype, shape), + VectorSpecies.of(ftype, shape))))) + .filter(p -> p.isp().length() > 1 && p.osp().length() > 1) + ); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorCast.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorCast.java new file mode 100644 index 0000000000000000000000000000000000000000..5ae64816234047d0a7b8d0305f575d403eeab7e2 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorCast.java @@ -0,0 +1,1365 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape.tests; + +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Test; + +import static compiler.vectorapi.reshape.utils.VectorReshapeHelper.*; +import static jdk.incubator.vector.VectorOperators.*; + +/** + * This class contains all possible cast operations between different vector species. + * The methods only take into consideration the actual cast in C2, as the vectors are + * ofter shrunk or expanded before/after casting if the element numbers mismatch. + * + * We must load from/store to the exact type array since vector support for byte may be + * smaller than that for other types. Failing to intrinsify LoadVectorNode causes C2 + * compilation to stop, which results in non-compilable failure since we only have one + * chance of compilation before IR verification. + * + * In each cast, the VectorCastNode is expected to appear exactly once. + */ +public class TestVectorCast { + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toS64(byte[] input, short[] output) { + vectorCast(B2S, BSPEC64, SSPEC64, input, output); + } + + @Run(test = "testB64toS64") + public static void runB64toS64() throws Throwable { + runCastHelper(B2S, BSPEC64, SSPEC64); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toS128(byte[] input, short[] output) { + vectorCast(B2S, BSPEC64, SSPEC128, input, output); + } + + @Run(test = "testB64toS128") + public static void runB64toS128() throws Throwable { + runCastHelper(B2S, BSPEC64, SSPEC128); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB128toS256(byte[] input, short[] output) { + vectorCast(B2S, BSPEC128, SSPEC256, input, output); + } + + @Run(test = "testB128toS256") + public static void runB128toS256() throws Throwable { + runCastHelper(B2S, BSPEC128, SSPEC256); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB256toS512(byte[] input, short[] output) { + vectorCast(B2S, BSPEC256, SSPEC512, input, output); + } + + @Run(test = "testB256toS512") + public static void runB256toS512() throws Throwable { + runCastHelper(B2S, BSPEC256, SSPEC512); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toI64(byte[] input, int[] output) { + vectorCast(B2I, BSPEC64, ISPEC64, input, output); + } + + @Run(test = "testB64toI64") + public static void runB64toI64() throws Throwable { + runCastHelper(B2I, BSPEC64, ISPEC64); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toI128(byte[] input, int[] output) { + vectorCast(B2I, BSPEC64, ISPEC128, input, output); + } + + @Run(test = "testB64toI128") + public static void runB64toI128() throws Throwable { + runCastHelper(B2I, BSPEC64, ISPEC128); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toI256(byte[] input, int[] output) { + vectorCast(B2I, BSPEC64, ISPEC256, input, output); + } + + @Run(test = "testB64toI256") + public static void runB64toI256() throws Throwable { + runCastHelper(B2I, BSPEC64, ISPEC256); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB128toI512(byte[] input, int[] output) { + vectorCast(B2I, BSPEC128, ISPEC512, input, output); + } + + @Run(test = "testB128toI512") + public static void runB128toI512() throws Throwable { + runCastHelper(B2I, BSPEC128, ISPEC512); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toL64(byte[] input, long[] output) { + vectorCast(B2L, BSPEC64, LSPEC64, input, output); + } + + @Run(test = "testB64toL64") + public static void runB64toL64() throws Throwable { + runCastHelper(B2L, BSPEC64, LSPEC64); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toL128(byte[] input, long[] output) { + vectorCast(B2L, BSPEC64, LSPEC128, input, output); + } + + @Run(test = "testB64toL128") + public static void runB64toL128() throws Throwable { + runCastHelper(B2L, BSPEC64, LSPEC128); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toL256(byte[] input, long[] output) { + vectorCast(B2L, BSPEC64, LSPEC256, input, output); + } + + @Run(test = "testB64toL256") + public static void runB64toL256() throws Throwable { + runCastHelper(B2L, BSPEC64, LSPEC256); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toL512(byte[] input, long[] output) { + vectorCast(B2L, BSPEC64, LSPEC512, input, output); + } + + @Run(test = "testB64toL512") + public static void runB64toL512() throws Throwable { + runCastHelper(B2L, BSPEC64, LSPEC512); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toF64(byte[] input, float[] output) { + vectorCast(B2F, BSPEC64, FSPEC64, input, output); + } + + @Run(test = "testB64toF64") + public static void runB64toF64() throws Throwable { + runCastHelper(B2F, BSPEC64, FSPEC64); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toF128(byte[] input, float[] output) { + vectorCast(B2F, BSPEC64, FSPEC128, input, output); + } + + @Run(test = "testB64toF128") + public static void runB64toF128() throws Throwable { + runCastHelper(B2F, BSPEC64, FSPEC128); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toF256(byte[] input, float[] output) { + vectorCast(B2F, BSPEC64, FSPEC256, input, output); + } + + @Run(test = "testB64toF256") + public static void runB64toF256() throws Throwable { + runCastHelper(B2F, BSPEC64, FSPEC256); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB128toF512(byte[] input, float[] output) { + vectorCast(B2F, BSPEC128, FSPEC512, input, output); + } + + @Run(test = "testB128toF512") + public static void runB128toF512() throws Throwable { + runCastHelper(B2F, BSPEC128, FSPEC512); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toD64(byte[] input, double[] output) { + vectorCast(B2D, BSPEC64, DSPEC64, input, output); + } + + @Run(test = "testB64toD64") + public static void runB64toD64() throws Throwable { + runCastHelper(B2D, BSPEC64, DSPEC64); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toD128(byte[] input, double[] output) { + vectorCast(B2D, BSPEC64, DSPEC128, input, output); + } + + @Run(test = "testB64toD128") + public static void runB64toD128() throws Throwable { + runCastHelper(B2D, BSPEC64, DSPEC128); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toD256(byte[] input, double[] output) { + vectorCast(B2D, BSPEC64, DSPEC256, input, output); + } + + @Run(test = "testB64toD256") + public static void runB64toD256() throws Throwable { + runCastHelper(B2D, BSPEC64, DSPEC256); + } + + @Test + @IR(counts = {B2X_NODE, "1"}) + public static void testB64toD512(byte[] input, double[] output) { + vectorCast(B2D, BSPEC64, DSPEC512, input, output); + } + + @Run(test = "testB64toD512") + public static void runB64toD512() throws Throwable { + runCastHelper(B2D, BSPEC64, DSPEC512); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toB64(short[] input, byte[] output) { + vectorCast(S2B, SSPEC64, BSPEC64, input, output); + } + + @Run(test = "testS64toB64") + public static void runS64toB64() throws Throwable { + runCastHelper(S2B, SSPEC64, BSPEC64); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS128toB64(short[] input, byte[] output) { + vectorCast(S2B, SSPEC128, BSPEC64, input, output); + } + + @Run(test = "testS128toB64") + public static void runS128toB64() throws Throwable { + runCastHelper(S2B, SSPEC128, BSPEC64); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS256toB128(short[] input, byte[] output) { + vectorCast(S2B, SSPEC256, BSPEC128, input, output); + } + + @Run(test = "testS256toB128") + public static void runS256toB128() throws Throwable { + runCastHelper(S2B, SSPEC256, BSPEC128); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS512toB256(short[] input, byte[] output) { + vectorCast(S2B, SSPEC512, BSPEC256, input, output); + } + + @Run(test = "testS512toB256") + public static void runS512toB256() throws Throwable { + runCastHelper(S2B, SSPEC512, BSPEC256); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toI64(short[] input, int[] output) { + vectorCast(S2I, SSPEC64, ISPEC64, input, output); + } + + @Run(test = "testS64toI64") + public static void runS64toI64() throws Throwable { + runCastHelper(S2I, SSPEC64, ISPEC64); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toI128(short[] input, int[] output) { + vectorCast(S2I, SSPEC64, ISPEC128, input, output); + } + + @Run(test = "testS64toI128") + public static void runS64toI128() throws Throwable { + runCastHelper(S2I, SSPEC64, ISPEC128); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS128toI256(short[] input, int[] output) { + vectorCast(S2I, SSPEC128, ISPEC256, input, output); + } + + @Run(test = "testS128toI256") + public static void runS128toI256() throws Throwable { + runCastHelper(S2I, SSPEC128, ISPEC256); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS256toI512(short[] input, int[] output) { + vectorCast(S2I, SSPEC256, ISPEC512, input, output); + } + + @Run(test = "testS256toI512") + public static void runS256toI512() throws Throwable { + runCastHelper(S2I, SSPEC256, ISPEC512); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toL64(short[] input, long[] output) { + vectorCast(S2L, SSPEC64, LSPEC64, input, output); + } + + @Run(test = "testS64toL64") + public static void runS64toL64() throws Throwable { + runCastHelper(S2L, SSPEC64, LSPEC64); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toL128(short[] input, long[] output) { + vectorCast(S2L, SSPEC64, LSPEC128, input, output); + } + + @Run(test = "testS64toL128") + public static void runS64toL128() throws Throwable { + runCastHelper(S2L, SSPEC64, LSPEC128); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toL256(short[] input, long[] output) { + vectorCast(S2L, SSPEC64, LSPEC256, input, output); + } + + @Run(test = "testS64toL256") + public static void runS64toL256() throws Throwable { + runCastHelper(S2L, SSPEC64, LSPEC256); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS128toL512(short[] input, long[] output) { + vectorCast(S2L, SSPEC128, LSPEC512, input, output); + } + + @Run(test = "testS128toL512") + public static void runS128toL512() throws Throwable { + runCastHelper(S2L, SSPEC128, LSPEC512); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toF64(short[] input, float[] output) { + vectorCast(S2F, SSPEC64, FSPEC64, input, output); + } + + @Run(test = "testS64toF64") + public static void runS64toF64() throws Throwable { + runCastHelper(S2F, SSPEC64, FSPEC64); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toF128(short[] input, float[] output) { + vectorCast(S2F, SSPEC64, FSPEC128, input, output); + } + + @Run(test = "testS64toF128") + public static void runS64toF128() throws Throwable { + runCastHelper(S2F, SSPEC64, FSPEC128); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS128toF256(short[] input, float[] output) { + vectorCast(S2F, SSPEC128, FSPEC256, input, output); + } + + @Run(test = "testS128toF256") + public static void runS128toF256() throws Throwable { + runCastHelper(S2F, SSPEC128, FSPEC256); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS256toF512(short[] input, float[] output) { + vectorCast(S2F, SSPEC256, FSPEC512, input, output); + } + + @Run(test = "testS256toF512") + public static void runS256toF512() throws Throwable { + runCastHelper(S2F, SSPEC256, FSPEC512); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toD64(short[] input, double[] output) { + vectorCast(S2D, SSPEC64, DSPEC64, input, output); + } + + @Run(test = "testS64toD64") + public static void runS64toD64() throws Throwable { + runCastHelper(S2D, SSPEC64, DSPEC64); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toD128(short[] input, double[] output) { + vectorCast(S2D, SSPEC64, DSPEC128, input, output); + } + + @Run(test = "testS64toD128") + public static void runS64toD128() throws Throwable { + runCastHelper(S2D, SSPEC64, DSPEC128); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS64toD256(short[] input, double[] output) { + vectorCast(S2D, SSPEC64, DSPEC256, input, output); + } + + @Run(test = "testS64toD256") + public static void runS64toD256() throws Throwable { + runCastHelper(S2D, SSPEC64, DSPEC256); + } + + @Test + @IR(counts = {S2X_NODE, "1"}) + public static void testS128toD512(short[] input, double[] output) { + vectorCast(S2D, SSPEC128, DSPEC512, input, output); + } + + @Run(test = "testS128toD512") + public static void runS128toD512() throws Throwable { + runCastHelper(S2D, SSPEC128, DSPEC512); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI64toB64(int[] input, byte[] output) { + vectorCast(I2B, ISPEC64, BSPEC64, input, output); + } + + @Run(test = "testI64toB64") + public static void runI64toB64() throws Throwable { + runCastHelper(I2B, ISPEC64, BSPEC64); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI128toB64(int[] input, byte[] output) { + vectorCast(I2B, ISPEC128, BSPEC64, input, output); + } + + @Run(test = "testI128toB64") + public static void runI128toB64() throws Throwable { + runCastHelper(I2B, ISPEC128, BSPEC64); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI256toB64(int[] input, byte[] output) { + vectorCast(I2B, ISPEC256, BSPEC64, input, output); + } + + @Run(test = "testI256toB64") + public static void runI256toB64() throws Throwable { + runCastHelper(I2B, ISPEC256, BSPEC64); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI512toB128(int[] input, byte[] output) { + vectorCast(I2B, ISPEC512, BSPEC128, input, output); + } + + @Run(test = "testI512toB128") + public static void runI512toB128() throws Throwable { + runCastHelper(I2B, ISPEC512, BSPEC128); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI64toS64(int[] input, short[] output) { + vectorCast(I2S, ISPEC64, SSPEC64, input, output); + } + + @Run(test = "testI64toS64") + public static void runI64toS64() throws Throwable { + runCastHelper(I2S, ISPEC64, SSPEC64); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI128toS64(int[] input, short[] output) { + vectorCast(I2S, ISPEC128, SSPEC64, input, output); + } + + @Run(test = "testI128toS64") + public static void runI128toS64() throws Throwable { + runCastHelper(I2S, ISPEC128, SSPEC64); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI256toS128(int[] input, short[] output) { + vectorCast(I2S, ISPEC256, SSPEC128, input, output); + } + + @Run(test = "testI256toS128") + public static void runI256toS128() throws Throwable { + runCastHelper(I2S, ISPEC256, SSPEC128); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI512toS256(int[] input, short[] output) { + vectorCast(I2S, ISPEC512, SSPEC256, input, output); + } + + @Run(test = "testI512toS256") + public static void runI512toS256() throws Throwable { + runCastHelper(I2S, ISPEC512, SSPEC256); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI64toL64(int[] input, long[] output) { + vectorCast(I2L, ISPEC64, LSPEC64, input, output); + } + + @Run(test = "testI64toL64") + public static void runI64toL64() throws Throwable { + runCastHelper(I2L, ISPEC64, LSPEC64); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI64toL128(int[] input, long[] output) { + vectorCast(I2L, ISPEC64, LSPEC128, input, output); + } + + @Run(test = "testI64toL128") + public static void runI64toL128() throws Throwable { + runCastHelper(I2L, ISPEC64, LSPEC128); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI128toL256(int[] input, long[] output) { + vectorCast(I2L, ISPEC128, LSPEC256, input, output); + } + + @Run(test = "testI128toL256") + public static void runI128toL256() throws Throwable { + runCastHelper(I2L, ISPEC128, LSPEC256); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI256toL512(int[] input, long[] output) { + vectorCast(I2L, ISPEC256, LSPEC512, input, output); + } + + @Run(test = "testI256toL512") + public static void runI256toL512() throws Throwable { + runCastHelper(I2L, ISPEC256, LSPEC512); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI64toF64(int[] input, float[] output) { + vectorCast(I2F, ISPEC64, FSPEC64, input, output); + } + + @Run(test = "testI64toF64") + public static void runI64toF64() throws Throwable { + runCastHelper(I2F, ISPEC64, FSPEC64); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI128toF128(int[] input, float[] output) { + vectorCast(I2F, ISPEC128, FSPEC128, input, output); + } + + @Run(test = "testI128toF128") + public static void runI128toF128() throws Throwable { + runCastHelper(I2F, ISPEC128, FSPEC128); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI256toF256(int[] input, float[] output) { + vectorCast(I2F, ISPEC256, FSPEC256, input, output); + } + + @Run(test = "testI256toF256") + public static void runI256toF256() throws Throwable { + runCastHelper(I2F, ISPEC256, FSPEC256); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI512toF512(int[] input, float[] output) { + vectorCast(I2F, ISPEC512, FSPEC512, input, output); + } + + @Run(test = "testI512toF512") + public static void runI512toF512() throws Throwable { + runCastHelper(I2F, ISPEC512, FSPEC512); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI64toD64(int[] input, double[] output) { + vectorCast(I2D, ISPEC64, DSPEC64, input, output); + } + + @Run(test = "testI64toD64") + public static void runI64toD64() throws Throwable { + runCastHelper(I2D, ISPEC64, DSPEC64); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI64toD128(int[] input, double[] output) { + vectorCast(I2D, ISPEC64, DSPEC128, input, output); + } + + @Run(test = "testI64toD128") + public static void runI64toD128() throws Throwable { + runCastHelper(I2D, ISPEC64, DSPEC128); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI128toD256(int[] input, double[] output) { + vectorCast(I2D, ISPEC128, DSPEC256, input, output); + } + + @Run(test = "testI128toD256") + public static void runI128toD256() throws Throwable { + runCastHelper(I2D, ISPEC128, DSPEC256); + } + + @Test + @IR(counts = {I2X_NODE, "1"}) + public static void testI256toD512(int[] input, double[] output) { + vectorCast(I2D, ISPEC256, DSPEC512, input, output); + } + + @Run(test = "testI256toD512") + public static void runI256toD512() throws Throwable { + runCastHelper(I2D, ISPEC256, DSPEC512); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL64toB64(long[] input, byte[] output) { + vectorCast(L2B, LSPEC64, BSPEC64, input, output); + } + + @Run(test = "testL64toB64") + public static void runL64toB64() throws Throwable { + runCastHelper(L2B, LSPEC64, BSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL128toB64(long[] input, byte[] output) { + vectorCast(L2B, LSPEC128, BSPEC64, input, output); + } + + @Run(test = "testL128toB64") + public static void runL128toB64() throws Throwable { + runCastHelper(L2B, LSPEC128, BSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL256toB64(long[] input, byte[] output) { + vectorCast(L2B, LSPEC256, BSPEC64, input, output); + } + + @Run(test = "testL256toB64") + public static void runL256toB64() throws Throwable { + runCastHelper(L2B, LSPEC256, BSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL512toB64(long[] input, byte[] output) { + vectorCast(L2B, LSPEC512, BSPEC64, input, output); + } + + @Run(test = "testL512toB64") + public static void runL512toB64() throws Throwable { + runCastHelper(L2B, LSPEC512, BSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL64toS64(long[] input, short[] output) { + vectorCast(L2S, LSPEC64, SSPEC64, input, output); + } + + @Run(test = "testL64toS64") + public static void runL64toS64() throws Throwable { + runCastHelper(L2S, LSPEC64, SSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL128toS64(long[] input, short[] output) { + vectorCast(L2S, LSPEC128, SSPEC64, input, output); + } + + @Run(test = "testL128toS64") + public static void runL128toS64() throws Throwable { + runCastHelper(L2S, LSPEC128, SSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL256toS64(long[] input, short[] output) { + vectorCast(L2S, LSPEC256, SSPEC64, input, output); + } + + @Run(test = "testL256toS64") + public static void runL256toS64() throws Throwable { + runCastHelper(L2S, LSPEC256, SSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL512toS128(long[] input, short[] output) { + vectorCast(L2S, LSPEC512, SSPEC128, input, output); + } + + @Run(test = "testL512toS128") + public static void runL512toS128() throws Throwable { + runCastHelper(L2S, LSPEC512, SSPEC128); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL64toI64(long[] input, int[] output) { + vectorCast(L2I, LSPEC64, ISPEC64, input, output); + } + + @Run(test = "testL64toI64") + public static void runL64toI64() throws Throwable { + runCastHelper(L2I, LSPEC64, ISPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL128toI64(long[] input, int[] output) { + vectorCast(L2I, LSPEC128, ISPEC64, input, output); + } + + @Run(test = "testL128toI64") + public static void runL128toI64() throws Throwable { + runCastHelper(L2I, LSPEC128, ISPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL256toI128(long[] input, int[] output) { + vectorCast(L2I, LSPEC256, ISPEC128, input, output); + } + + @Run(test = "testL256toI128") + public static void runL256toI128() throws Throwable { + runCastHelper(L2I, LSPEC256, ISPEC128); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL512toI256(long[] input, int[] output) { + vectorCast(L2I, LSPEC512, ISPEC256, input, output); + } + + @Run(test = "testL512toI256") + public static void runL512toI256() throws Throwable { + runCastHelper(L2I, LSPEC512, ISPEC256); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL64toF64(long[] input, float[] output) { + vectorCast(L2F, LSPEC64, FSPEC64, input, output); + } + + @Run(test = "testL64toF64") + public static void runL64toF64() throws Throwable { + runCastHelper(L2F, LSPEC64, FSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL128toF64(long[] input, float[] output) { + vectorCast(L2F, LSPEC128, FSPEC64, input, output); + } + + @Run(test = "testL128toF64") + public static void runL128toF64() throws Throwable { + runCastHelper(L2F, LSPEC128, FSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL256toF128(long[] input, float[] output) { + vectorCast(L2F, LSPEC256, FSPEC128, input, output); + } + + @Run(test = "testL256toF128") + public static void runL256toF128() throws Throwable { + runCastHelper(L2F, LSPEC256, FSPEC128); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL512toF256(long[] input, float[] output) { + vectorCast(L2F, LSPEC512, FSPEC256, input, output); + } + + @Run(test = "testL512toF256") + public static void runL512toF256() throws Throwable { + runCastHelper(L2F, LSPEC512, FSPEC256); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL64toD64(long[] input, double[] output) { + vectorCast(L2D, LSPEC64, DSPEC64, input, output); + } + + @Run(test = "testL64toD64") + public static void runL64toD64() throws Throwable { + runCastHelper(L2D, LSPEC64, DSPEC64); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL128toD128(long[] input, double[] output) { + vectorCast(L2D, LSPEC128, DSPEC128, input, output); + } + + @Run(test = "testL128toD128") + public static void runL128toD128() throws Throwable { + runCastHelper(L2D, LSPEC128, DSPEC128); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL256toD256(long[] input, double[] output) { + vectorCast(L2D, LSPEC256, DSPEC256, input, output); + } + + @Run(test = "testL256toD256") + public static void runL256toD256() throws Throwable { + runCastHelper(L2D, LSPEC256, DSPEC256); + } + + @Test + @IR(counts = {L2X_NODE, "1"}) + public static void testL512toD512(long[] input, double[] output) { + vectorCast(L2D, LSPEC512, DSPEC512, input, output); + } + + @Run(test = "testL512toD512") + public static void runL512toD512() throws Throwable { + runCastHelper(L2D, LSPEC512, DSPEC512); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF64toB64(float[] input, byte[] output) { + vectorCast(F2B, FSPEC64, BSPEC64, input, output); + } + + @Run(test = "testF64toB64") + public static void runF64toB64() throws Throwable { + runCastHelper(F2B, FSPEC64, BSPEC64); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF128toB64(float[] input, byte[] output) { + vectorCast(F2B, FSPEC128, BSPEC64, input, output); + } + + @Run(test = "testF128toB64") + public static void runF128toB64() throws Throwable { + runCastHelper(F2B, FSPEC128, BSPEC64); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF256toB64(float[] input, byte[] output) { + vectorCast(F2B, FSPEC256, BSPEC64, input, output); + } + + @Run(test = "testF256toB64") + public static void runF256toB64() throws Throwable { + runCastHelper(F2B, FSPEC256, BSPEC64); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF512toB128(float[] input, byte[] output) { + vectorCast(F2B, FSPEC512, BSPEC128, input, output); + } + + @Run(test = "testF512toB128") + public static void runF512toB128() throws Throwable { + runCastHelper(F2B, FSPEC512, BSPEC128); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF64toS64(float[] input, short[] output) { + vectorCast(F2S, FSPEC64, SSPEC64, input, output); + } + + @Run(test = "testF64toS64") + public static void runF64toS64() throws Throwable { + runCastHelper(F2S, FSPEC64, SSPEC64); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF128toS64(float[] input, short[] output) { + vectorCast(F2S, FSPEC128, SSPEC64, input, output); + } + + @Run(test = "testF128toS64") + public static void runF128toS64() throws Throwable { + runCastHelper(F2S, FSPEC128, SSPEC64); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF256toS128(float[] input, short[] output) { + vectorCast(F2S, FSPEC256, SSPEC128, input, output); + } + + @Run(test = "testF256toS128") + public static void runF256toS128() throws Throwable { + runCastHelper(F2S, FSPEC256, SSPEC128); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF512toS256(float[] input, short[] output) { + vectorCast(F2S, FSPEC512, SSPEC256, input, output); + } + + @Run(test = "testF512toS256") + public static void runF512toS256() throws Throwable { + runCastHelper(F2S, FSPEC512, SSPEC256); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF64toI64(float[] input, int[] output) { + vectorCast(F2I, FSPEC64, ISPEC64, input, output); + } + + @Run(test = "testF64toI64") + public static void runF64toI64() throws Throwable { + runCastHelper(F2I, FSPEC64, ISPEC64); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF128toI128(float[] input, int[] output) { + vectorCast(F2I, FSPEC128, ISPEC128, input, output); + } + + @Run(test = "testF128toI128") + public static void runF128toI128() throws Throwable { + runCastHelper(F2I, FSPEC128, ISPEC128); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF256toI256(float[] input, int[] output) { + vectorCast(F2I, FSPEC256, ISPEC256, input, output); + } + + @Run(test = "testF256toI256") + public static void runF256toI256() throws Throwable { + runCastHelper(F2I, FSPEC256, ISPEC256); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF512toI512(float[] input, int[] output) { + vectorCast(F2I, FSPEC512, ISPEC512, input, output); + } + + @Run(test = "testF512toI512") + public static void runF512toI512() throws Throwable { + runCastHelper(F2I, FSPEC512, ISPEC512); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF64toL64(float[] input, long[] output) { + vectorCast(F2L, FSPEC64, LSPEC64, input, output); + } + + @Run(test = "testF64toL64") + public static void runF64toL64() throws Throwable { + runCastHelper(F2L, FSPEC64, LSPEC64); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF64toL128(float[] input, long[] output) { + vectorCast(F2L, FSPEC64, LSPEC128, input, output); + } + + @Run(test = "testF64toL128") + public static void runF64toL128() throws Throwable { + runCastHelper(F2L, FSPEC64, LSPEC128); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF128toL256(float[] input, long[] output) { + vectorCast(F2L, FSPEC128, LSPEC256, input, output); + } + + @Run(test = "testF128toL256") + public static void runF128toL256() throws Throwable { + runCastHelper(F2L, FSPEC128, LSPEC256); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF256toL512(float[] input, long[] output) { + vectorCast(F2L, FSPEC256, LSPEC512, input, output); + } + + @Run(test = "testF256toL512") + public static void runF256toL512() throws Throwable { + runCastHelper(F2L, FSPEC256, LSPEC512); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF64toD64(float[] input, double[] output) { + vectorCast(F2D, FSPEC64, DSPEC64, input, output); + } + + @Run(test = "testF64toD64") + public static void runF64toD64() throws Throwable { + runCastHelper(F2D, FSPEC64, DSPEC64); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF64toD128(float[] input, double[] output) { + vectorCast(F2D, FSPEC64, DSPEC128, input, output); + } + + @Run(test = "testF64toD128") + public static void runF64toD128() throws Throwable { + runCastHelper(F2D, FSPEC64, DSPEC128); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF128toD256(float[] input, double[] output) { + vectorCast(F2D, FSPEC128, DSPEC256, input, output); + } + + @Run(test = "testF128toD256") + public static void runF128toD256() throws Throwable { + runCastHelper(F2D, FSPEC128, DSPEC256); + } + + @Test + @IR(counts = {F2X_NODE, "1"}) + public static void testF256toD512(float[] input, double[] output) { + vectorCast(F2D, FSPEC256, DSPEC512, input, output); + } + + @Run(test = "testF256toD512") + public static void runF256toD512() throws Throwable { + runCastHelper(F2D, FSPEC256, DSPEC512); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD64toB64(double[] input, byte[] output) { + vectorCast(D2B, DSPEC64, BSPEC64, input, output); + } + + @Run(test = "testD64toB64") + public static void runD64toB64() throws Throwable { + runCastHelper(D2B, DSPEC64, BSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD128toB64(double[] input, byte[] output) { + vectorCast(D2B, DSPEC128, BSPEC64, input, output); + } + + @Run(test = "testD128toB64") + public static void runD128toB64() throws Throwable { + runCastHelper(D2B, DSPEC128, BSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD256toB64(double[] input, byte[] output) { + vectorCast(D2B, DSPEC256, BSPEC64, input, output); + } + + @Run(test = "testD256toB64") + public static void runD256toB64() throws Throwable { + runCastHelper(D2B, DSPEC256, BSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD512toB64(double[] input, byte[] output) { + vectorCast(D2B, DSPEC512, BSPEC64, input, output); + } + + @Run(test = "testD512toB64") + public static void runD512toB64() throws Throwable { + runCastHelper(D2B, DSPEC512, BSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD64toS64(double[] input, short[] output) { + vectorCast(D2S, DSPEC64, SSPEC64, input, output); + } + + @Run(test = "testD64toS64") + public static void runD64toS64() throws Throwable { + runCastHelper(D2S, DSPEC64, SSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD128toS64(double[] input, short[] output) { + vectorCast(D2S, DSPEC128, SSPEC64, input, output); + } + + @Run(test = "testD128toS64") + public static void runD128toS64() throws Throwable { + runCastHelper(D2S, DSPEC128, SSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD256toS64(double[] input, short[] output) { + vectorCast(D2S, DSPEC256, SSPEC64, input, output); + } + + @Run(test = "testD256toS64") + public static void runD256toS64() throws Throwable { + runCastHelper(D2S, DSPEC256, SSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD512toS128(double[] input, short[] output) { + vectorCast(D2S, DSPEC512, SSPEC128, input, output); + } + + @Run(test = "testD512toS128") + public static void runD512toS128() throws Throwable { + runCastHelper(D2S, DSPEC512, SSPEC128); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD64toI64(double[] input, int[] output) { + vectorCast(D2I, DSPEC64, ISPEC64, input, output); + } + + @Run(test = "testD64toI64") + public static void runD64toI64() throws Throwable { + runCastHelper(D2I, DSPEC64, ISPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD128toI64(double[] input, int[] output) { + vectorCast(D2I, DSPEC128, ISPEC64, input, output); + } + + @Run(test = "testD128toI64") + public static void runD128toI64() throws Throwable { + runCastHelper(D2I, DSPEC128, ISPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD256toI128(double[] input, int[] output) { + vectorCast(D2I, DSPEC256, ISPEC128, input, output); + } + + @Run(test = "testD256toI128") + public static void runD256toI128() throws Throwable { + runCastHelper(D2I, DSPEC256, ISPEC128); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD512toI256(double[] input, int[] output) { + vectorCast(D2I, DSPEC512, ISPEC256, input, output); + } + + @Run(test = "testD512toI256") + public static void runD512toI256() throws Throwable { + runCastHelper(D2I, DSPEC512, ISPEC256); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD64toL64(double[] input, long[] output) { + vectorCast(D2L, DSPEC64, LSPEC64, input, output); + } + + @Run(test = "testD64toL64") + public static void runD64toL64() throws Throwable { + runCastHelper(D2L, DSPEC64, LSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD128toL128(double[] input, long[] output) { + vectorCast(D2L, DSPEC128, LSPEC128, input, output); + } + + @Run(test = "testD128toL128") + public static void runD128toL128() throws Throwable { + runCastHelper(D2L, DSPEC128, LSPEC128); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD256toL256(double[] input, long[] output) { + vectorCast(D2L, DSPEC256, LSPEC256, input, output); + } + + @Run(test = "testD256toL256") + public static void runD256toL256() throws Throwable { + runCastHelper(D2L, DSPEC256, LSPEC256); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD512toL512(double[] input, long[] output) { + vectorCast(D2L, DSPEC512, LSPEC512, input, output); + } + + @Run(test = "testD512toL512") + public static void runD512toL512() throws Throwable { + runCastHelper(D2L, DSPEC512, LSPEC512); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD64toF64(double[] input, float[] output) { + vectorCast(D2F, DSPEC64, FSPEC64, input, output); + } + + @Run(test = "testD64toF64") + public static void runD64toF64() throws Throwable { + runCastHelper(D2F, DSPEC64, FSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD128toF64(double[] input, float[] output) { + vectorCast(D2F, DSPEC128, FSPEC64, input, output); + } + + @Run(test = "testD128toF64") + public static void runD128toF64() throws Throwable { + runCastHelper(D2F, DSPEC128, FSPEC64); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD256toF128(double[] input, float[] output) { + vectorCast(D2F, DSPEC256, FSPEC128, input, output); + } + + @Run(test = "testD256toF128") + public static void runD256toF128() throws Throwable { + runCastHelper(D2F, DSPEC256, FSPEC128); + } + + @Test + @IR(counts = {D2X_NODE, "1"}) + public static void testD512toF256(double[] input, float[] output) { + vectorCast(D2F, DSPEC512, FSPEC256, input, output); + } + + @Run(test = "testD512toF256") + public static void runD512toF256() throws Throwable { + runCastHelper(D2F, DSPEC512, FSPEC256); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorDoubleExpandShrink.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorDoubleExpandShrink.java new file mode 100644 index 0000000000000000000000000000000000000000..1056cfedcfcdd038b4280695c8ed57793f7d87fd --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorDoubleExpandShrink.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape.tests; + +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Test; + +import static compiler.vectorapi.reshape.utils.VectorReshapeHelper.*; + +/** + * As spot in 8259353. We need to do a shrink and an expand together to not accidentally + * zero out elements in the physical registers that may not be zero in general cases. + * + * In some methods, 2 consecutive ReinterpretNodes may be optimized out. + */ +public class TestVectorDoubleExpandShrink { + @Test + @IR(failOn = REINTERPRET_NODE) + public static void testB64toB128(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC64, BSPEC128, input, output); + } + + @Run(test = "testB64toB128") + public static void runB64toB128() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC64, BSPEC128); + } + + @Test + @IR(failOn = REINTERPRET_NODE) + public static void testB64toB256(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC64, BSPEC256, input, output); + } + + @Run(test = "testB64toB256") + public static void runB64toB256() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC64, BSPEC256); + } + + @Test + @IR(failOn = REINTERPRET_NODE) + public static void testB64toB512(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC64, BSPEC512, input, output); + } + + @Run(test = "testB64toB512") + public static void runB64toB512() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC64, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "2"}) + public static void testB128toB64(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC128, BSPEC64, input, output); + } + + @Run(test = "testB128toB64") + public static void runB128toB64() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC128, BSPEC64); + } + + @Test + @IR(failOn = REINTERPRET_NODE) + public static void testB128toB256(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC128, BSPEC256, input, output); + } + + @Run(test = "testB128toB256") + public static void runB128toB256() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC128, BSPEC256); + } + + @Test + @IR(failOn = REINTERPRET_NODE) + public static void testB128toB512(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC128, BSPEC512, input, output); + } + + @Run(test = "testB128toB512") + public static void runB128toB512() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC128, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "2"}) + public static void testB256toB64(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC256, BSPEC64, input, output); + } + + @Run(test = "testB256toB64") + public static void runB256toB64() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC256, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "2"}) + public static void testB256toB128(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC256, BSPEC128, input, output); + } + + @Run(test = "testB256toB128") + public static void runB256toB128() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC256, BSPEC128); + } + + @Test + @IR(failOn = REINTERPRET_NODE) + public static void testB256toB512(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC256, BSPEC512, input, output); + } + + @Run(test = "testB256toB512") + public static void runB256toB512() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC256, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "2"}) + public static void testB512toB64(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC512, BSPEC64, input, output); + } + + @Run(test = "testB512toB64") + public static void runB512toB64() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC512, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "2"}) + public static void testB512toB128(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC512, BSPEC128, input, output); + } + + @Run(test = "testB512toB128") + public static void runB512toB128() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC512, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "2"}) + public static void testB512toB256(byte[] input, byte[] output) { + vectorDoubleExpandShrink(BSPEC512, BSPEC256, input, output); + } + + @Run(test = "testB512toB256") + public static void runB512toB256() throws Throwable { + runDoubleExpandShrinkHelper(BSPEC512, BSPEC256); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorExpandShrink.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorExpandShrink.java new file mode 100644 index 0000000000000000000000000000000000000000..f975331cef08077df81729d784cbfdd2a25f5a2d --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorExpandShrink.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape.tests; + +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Test; + +import static compiler.vectorapi.reshape.utils.VectorReshapeHelper.*; + +/** + * This class contains method to ensure a resizing reinterpretation operations work as + * intended. + * + * In each test, the ReinterpretNode is expected to appear exactly once. + */ +public class TestVectorExpandShrink { + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB64toB128(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC64, BSPEC128, input, output); + } + + @Run(test = "testB64toB128") + public static void runB64toB128() throws Throwable { + runExpandShrinkHelper(BSPEC64, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB64toB256(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC64, BSPEC256, input, output); + } + + @Run(test = "testB64toB256") + public static void runB64toB256() throws Throwable { + runExpandShrinkHelper(BSPEC64, BSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB64toB512(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC64, BSPEC512, input, output); + } + + @Run(test = "testB64toB512") + public static void runB64toB512() throws Throwable { + runExpandShrinkHelper(BSPEC64, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB128toB64(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC128, BSPEC64, input, output); + } + + @Run(test = "testB128toB64") + public static void runB128toB64() throws Throwable { + runExpandShrinkHelper(BSPEC128, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB128toB256(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC128, BSPEC256, input, output); + } + + @Run(test = "testB128toB256") + public static void runB128toB256() throws Throwable { + runExpandShrinkHelper(BSPEC128, BSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB128toB512(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC128, BSPEC512, input, output); + } + + @Run(test = "testB128toB512") + public static void runB128toB512() throws Throwable { + runExpandShrinkHelper(BSPEC128, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB256toB64(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC256, BSPEC64, input, output); + } + + @Run(test = "testB256toB64") + public static void runB256toB64() throws Throwable { + runExpandShrinkHelper(BSPEC256, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB256toB128(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC256, BSPEC128, input, output); + } + + @Run(test = "testB256toB128") + public static void runB256toB128() throws Throwable { + runExpandShrinkHelper(BSPEC256, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB256toB512(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC256, BSPEC512, input, output); + } + + @Run(test = "testB256toB512") + public static void runB256toB512() throws Throwable { + runExpandShrinkHelper(BSPEC256, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB512toB64(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC512, BSPEC64, input, output); + } + + @Run(test = "testB512toB64") + public static void runB512toB64() throws Throwable { + runExpandShrinkHelper(BSPEC512, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB512toB128(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC512, BSPEC128, input, output); + } + + @Run(test = "testB512toB128") + public static void runB512toB128() throws Throwable { + runExpandShrinkHelper(BSPEC512, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB512toB256(byte[] input, byte[] output) { + vectorExpandShrink(BSPEC512, BSPEC256, input, output); + } + + @Run(test = "testB512toB256") + public static void runB512toB256() throws Throwable { + runExpandShrinkHelper(BSPEC512, BSPEC256); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorRebracket.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorRebracket.java new file mode 100644 index 0000000000000000000000000000000000000000..2143eb3b500326f42aa99b22ec996849f71060c6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/tests/TestVectorRebracket.java @@ -0,0 +1,1362 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape.tests; + +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Test; + +import static compiler.vectorapi.reshape.utils.VectorReshapeHelper.*; + +/** + * This class contains methods to test for reinterpretation operations that reinterpret + * a vector as a similar vector with another element type. + * + * It is complicated to verify the IR in this case since a load/store with respect to + * byte array will result in additional ReinterpretNodes if the vector element type is + * not byte. As a result, arguments need to be arrays of the correct type. + * + * In each test, the ReinterpretNode is expected to appear exactly once. + */ +public class TestVectorRebracket { + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB64toS64(byte[] input, short[] output) { + vectorRebracket(BSPEC64, SSPEC64, input, output); + } + + @Run(test = "testB64toS64") + public static void runB64toS64() throws Throwable { + runRebracketHelper(BSPEC64, SSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB64toI64(byte[] input, int[] output) { + vectorRebracket(BSPEC64, ISPEC64, input, output); + } + + @Run(test = "testB64toI64") + public static void runB64toI64() throws Throwable { + runRebracketHelper(BSPEC64, ISPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB64toL64(byte[] input, long[] output) { + vectorRebracket(BSPEC64, LSPEC64, input, output); + } + + @Run(test = "testB64toL64") + public static void runB64toL64() throws Throwable { + runRebracketHelper(BSPEC64, LSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB64toF64(byte[] input, float[] output) { + vectorRebracket(BSPEC64, FSPEC64, input, output); + } + + @Run(test = "testB64toF64") + public static void runB64toF64() throws Throwable { + runRebracketHelper(BSPEC64, FSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB64toD64(byte[] input, double[] output) { + vectorRebracket(BSPEC64, DSPEC64, input, output); + } + + @Run(test = "testB64toD64") + public static void runB64toD64() throws Throwable { + runRebracketHelper(BSPEC64, DSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS64toB64(short[] input, byte[] output) { + vectorRebracket(SSPEC64, BSPEC64, input, output); + } + + @Run(test = "testS64toB64") + public static void runS64toB64() throws Throwable { + runRebracketHelper(SSPEC64, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS64toI64(short[] input, int[] output) { + vectorRebracket(SSPEC64, ISPEC64, input, output); + } + + @Run(test = "testS64toI64") + public static void runS64toI64() throws Throwable { + runRebracketHelper(SSPEC64, ISPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS64toL64(short[] input, long[] output) { + vectorRebracket(SSPEC64, LSPEC64, input, output); + } + + @Run(test = "testS64toL64") + public static void runS64toL64() throws Throwable { + runRebracketHelper(SSPEC64, LSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS64toF64(short[] input, float[] output) { + vectorRebracket(SSPEC64, FSPEC64, input, output); + } + + @Run(test = "testS64toF64") + public static void runS64toF64() throws Throwable { + runRebracketHelper(SSPEC64, FSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS64toD64(short[] input, double[] output) { + vectorRebracket(SSPEC64, DSPEC64, input, output); + } + + @Run(test = "testS64toD64") + public static void runS64toD64() throws Throwable { + runRebracketHelper(SSPEC64, DSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI64toB64(int[] input, byte[] output) { + vectorRebracket(ISPEC64, BSPEC64, input, output); + } + + @Run(test = "testI64toB64") + public static void runI64toB64() throws Throwable { + runRebracketHelper(ISPEC64, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI64toS64(int[] input, short[] output) { + vectorRebracket(ISPEC64, SSPEC64, input, output); + } + + @Run(test = "testI64toS64") + public static void runI64toS64() throws Throwable { + runRebracketHelper(ISPEC64, SSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI64toL64(int[] input, long[] output) { + vectorRebracket(ISPEC64, LSPEC64, input, output); + } + + @Run(test = "testI64toL64") + public static void runI64toL64() throws Throwable { + runRebracketHelper(ISPEC64, LSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI64toF64(int[] input, float[] output) { + vectorRebracket(ISPEC64, FSPEC64, input, output); + } + + @Run(test = "testI64toF64") + public static void runI64toF64() throws Throwable { + runRebracketHelper(ISPEC64, FSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI64toD64(int[] input, double[] output) { + vectorRebracket(ISPEC64, DSPEC64, input, output); + } + + @Run(test = "testI64toD64") + public static void runI64toD64() throws Throwable { + runRebracketHelper(ISPEC64, DSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL64toB64(long[] input, byte[] output) { + vectorRebracket(LSPEC64, BSPEC64, input, output); + } + + @Run(test = "testL64toB64") + public static void runL64toB64() throws Throwable { + runRebracketHelper(LSPEC64, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL64toS64(long[] input, short[] output) { + vectorRebracket(LSPEC64, SSPEC64, input, output); + } + + @Run(test = "testL64toS64") + public static void runL64toS64() throws Throwable { + runRebracketHelper(LSPEC64, SSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL64toI64(long[] input, int[] output) { + vectorRebracket(LSPEC64, ISPEC64, input, output); + } + + @Run(test = "testL64toI64") + public static void runL64toI64() throws Throwable { + runRebracketHelper(LSPEC64, ISPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL64toF64(long[] input, float[] output) { + vectorRebracket(LSPEC64, FSPEC64, input, output); + } + + @Run(test = "testL64toF64") + public static void runL64toF64() throws Throwable { + runRebracketHelper(LSPEC64, FSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL64toD64(long[] input, double[] output) { + vectorRebracket(LSPEC64, DSPEC64, input, output); + } + + @Run(test = "testL64toD64") + public static void runL64toD64() throws Throwable { + runRebracketHelper(LSPEC64, DSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF64toB64(float[] input, byte[] output) { + vectorRebracket(FSPEC64, BSPEC64, input, output); + } + + @Run(test = "testF64toB64") + public static void runF64toB64() throws Throwable { + runRebracketHelper(FSPEC64, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF64toS64(float[] input, short[] output) { + vectorRebracket(FSPEC64, SSPEC64, input, output); + } + + @Run(test = "testF64toS64") + public static void runF64toS64() throws Throwable { + runRebracketHelper(FSPEC64, SSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF64toI64(float[] input, int[] output) { + vectorRebracket(FSPEC64, ISPEC64, input, output); + } + + @Run(test = "testF64toI64") + public static void runF64toI64() throws Throwable { + runRebracketHelper(FSPEC64, ISPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF64toL64(float[] input, long[] output) { + vectorRebracket(FSPEC64, LSPEC64, input, output); + } + + @Run(test = "testF64toL64") + public static void runF64toL64() throws Throwable { + runRebracketHelper(FSPEC64, LSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF64toD64(float[] input, double[] output) { + vectorRebracket(FSPEC64, DSPEC64, input, output); + } + + @Run(test = "testF64toD64") + public static void runF64toD64() throws Throwable { + runRebracketHelper(FSPEC64, DSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD64toB64(double[] input, byte[] output) { + vectorRebracket(DSPEC64, BSPEC64, input, output); + } + + @Run(test = "testD64toB64") + public static void runD64toB64() throws Throwable { + runRebracketHelper(DSPEC64, BSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD64toS64(double[] input, short[] output) { + vectorRebracket(DSPEC64, SSPEC64, input, output); + } + + @Run(test = "testD64toS64") + public static void runD64toS64() throws Throwable { + runRebracketHelper(DSPEC64, SSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD64toI64(double[] input, int[] output) { + vectorRebracket(DSPEC64, ISPEC64, input, output); + } + + @Run(test = "testD64toI64") + public static void runD64toI64() throws Throwable { + runRebracketHelper(DSPEC64, ISPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD64toL64(double[] input, long[] output) { + vectorRebracket(DSPEC64, LSPEC64, input, output); + } + + @Run(test = "testD64toL64") + public static void runD64toL64() throws Throwable { + runRebracketHelper(DSPEC64, LSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD64toF64(double[] input, float[] output) { + vectorRebracket(DSPEC64, FSPEC64, input, output); + } + + @Run(test = "testD64toF64") + public static void runD64toF64() throws Throwable { + runRebracketHelper(DSPEC64, FSPEC64); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB128toS128(byte[] input, short[] output) { + vectorRebracket(BSPEC128, SSPEC128, input, output); + } + + @Run(test = "testB128toS128") + public static void runB128toS128() throws Throwable { + runRebracketHelper(BSPEC128, SSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB128toI128(byte[] input, int[] output) { + vectorRebracket(BSPEC128, ISPEC128, input, output); + } + + @Run(test = "testB128toI128") + public static void runB128toI128() throws Throwable { + runRebracketHelper(BSPEC128, ISPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB128toL128(byte[] input, long[] output) { + vectorRebracket(BSPEC128, LSPEC128, input, output); + } + + @Run(test = "testB128toL128") + public static void runB128toL128() throws Throwable { + runRebracketHelper(BSPEC128, LSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB128toF128(byte[] input, float[] output) { + vectorRebracket(BSPEC128, FSPEC128, input, output); + } + + @Run(test = "testB128toF128") + public static void runB128toF128() throws Throwable { + runRebracketHelper(BSPEC128, FSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB128toD128(byte[] input, double[] output) { + vectorRebracket(BSPEC128, DSPEC128, input, output); + } + + @Run(test = "testB128toD128") + public static void runB128toD128() throws Throwable { + runRebracketHelper(BSPEC128, DSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS128toB128(short[] input, byte[] output) { + vectorRebracket(SSPEC128, BSPEC128, input, output); + } + + @Run(test = "testS128toB128") + public static void runS128toB128() throws Throwable { + runRebracketHelper(SSPEC128, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS128toI128(short[] input, int[] output) { + vectorRebracket(SSPEC128, ISPEC128, input, output); + } + + @Run(test = "testS128toI128") + public static void runS128toI128() throws Throwable { + runRebracketHelper(SSPEC128, ISPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS128toL128(short[] input, long[] output) { + vectorRebracket(SSPEC128, LSPEC128, input, output); + } + + @Run(test = "testS128toL128") + public static void runS128toL128() throws Throwable { + runRebracketHelper(SSPEC128, LSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS128toF128(short[] input, float[] output) { + vectorRebracket(SSPEC128, FSPEC128, input, output); + } + + @Run(test = "testS128toF128") + public static void runS128toF128() throws Throwable { + runRebracketHelper(SSPEC128, FSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS128toD128(short[] input, double[] output) { + vectorRebracket(SSPEC128, DSPEC128, input, output); + } + + @Run(test = "testS128toD128") + public static void runS128toD128() throws Throwable { + runRebracketHelper(SSPEC128, DSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI128toB128(int[] input, byte[] output) { + vectorRebracket(ISPEC128, BSPEC128, input, output); + } + + @Run(test = "testI128toB128") + public static void runI128toB128() throws Throwable { + runRebracketHelper(ISPEC128, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI128toS128(int[] input, short[] output) { + vectorRebracket(ISPEC128, SSPEC128, input, output); + } + + @Run(test = "testI128toS128") + public static void runI128toS128() throws Throwable { + runRebracketHelper(ISPEC128, SSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI128toL128(int[] input, long[] output) { + vectorRebracket(ISPEC128, LSPEC128, input, output); + } + + @Run(test = "testI128toL128") + public static void runI128toL128() throws Throwable { + runRebracketHelper(ISPEC128, LSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI128toF128(int[] input, float[] output) { + vectorRebracket(ISPEC128, FSPEC128, input, output); + } + + @Run(test = "testI128toF128") + public static void runI128toF128() throws Throwable { + runRebracketHelper(ISPEC128, FSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI128toD128(int[] input, double[] output) { + vectorRebracket(ISPEC128, DSPEC128, input, output); + } + + @Run(test = "testI128toD128") + public static void runI128toD128() throws Throwable { + runRebracketHelper(ISPEC128, DSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL128toB128(long[] input, byte[] output) { + vectorRebracket(LSPEC128, BSPEC128, input, output); + } + + @Run(test = "testL128toB128") + public static void runL128toB128() throws Throwable { + runRebracketHelper(LSPEC128, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL128toS128(long[] input, short[] output) { + vectorRebracket(LSPEC128, SSPEC128, input, output); + } + + @Run(test = "testL128toS128") + public static void runL128toS128() throws Throwable { + runRebracketHelper(LSPEC128, SSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL128toI128(long[] input, int[] output) { + vectorRebracket(LSPEC128, ISPEC128, input, output); + } + + @Run(test = "testL128toI128") + public static void runL128toI128() throws Throwable { + runRebracketHelper(LSPEC128, ISPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL128toF128(long[] input, float[] output) { + vectorRebracket(LSPEC128, FSPEC128, input, output); + } + + @Run(test = "testL128toF128") + public static void runL128toF128() throws Throwable { + runRebracketHelper(LSPEC128, FSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL128toD128(long[] input, double[] output) { + vectorRebracket(LSPEC128, DSPEC128, input, output); + } + + @Run(test = "testL128toD128") + public static void runL128toD128() throws Throwable { + runRebracketHelper(LSPEC128, DSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF128toB128(float[] input, byte[] output) { + vectorRebracket(FSPEC128, BSPEC128, input, output); + } + + @Run(test = "testF128toB128") + public static void runF128toB128() throws Throwable { + runRebracketHelper(FSPEC128, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF128toS128(float[] input, short[] output) { + vectorRebracket(FSPEC128, SSPEC128, input, output); + } + + @Run(test = "testF128toS128") + public static void runF128toS128() throws Throwable { + runRebracketHelper(FSPEC128, SSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF128toI128(float[] input, int[] output) { + vectorRebracket(FSPEC128, ISPEC128, input, output); + } + + @Run(test = "testF128toI128") + public static void runF128toI128() throws Throwable { + runRebracketHelper(FSPEC128, ISPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF128toL128(float[] input, long[] output) { + vectorRebracket(FSPEC128, LSPEC128, input, output); + } + + @Run(test = "testF128toL128") + public static void runF128toL128() throws Throwable { + runRebracketHelper(FSPEC128, LSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF128toD128(float[] input, double[] output) { + vectorRebracket(FSPEC128, DSPEC128, input, output); + } + + @Run(test = "testF128toD128") + public static void runF128toD128() throws Throwable { + runRebracketHelper(FSPEC128, DSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD128toB128(double[] input, byte[] output) { + vectorRebracket(DSPEC128, BSPEC128, input, output); + } + + @Run(test = "testD128toB128") + public static void runD128toB128() throws Throwable { + runRebracketHelper(DSPEC128, BSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD128toS128(double[] input, short[] output) { + vectorRebracket(DSPEC128, SSPEC128, input, output); + } + + @Run(test = "testD128toS128") + public static void runD128toS128() throws Throwable { + runRebracketHelper(DSPEC128, SSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD128toI128(double[] input, int[] output) { + vectorRebracket(DSPEC128, ISPEC128, input, output); + } + + @Run(test = "testD128toI128") + public static void runD128toI128() throws Throwable { + runRebracketHelper(DSPEC128, ISPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD128toL128(double[] input, long[] output) { + vectorRebracket(DSPEC128, LSPEC128, input, output); + } + + @Run(test = "testD128toL128") + public static void runD128toL128() throws Throwable { + runRebracketHelper(DSPEC128, LSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD128toF128(double[] input, float[] output) { + vectorRebracket(DSPEC128, FSPEC128, input, output); + } + + @Run(test = "testD128toF128") + public static void runD128toF128() throws Throwable { + runRebracketHelper(DSPEC128, FSPEC128); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB256toS256(byte[] input, short[] output) { + vectorRebracket(BSPEC256, SSPEC256, input, output); + } + + @Run(test = "testB256toS256") + public static void runB256toS256() throws Throwable { + runRebracketHelper(BSPEC256, SSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB256toI256(byte[] input, int[] output) { + vectorRebracket(BSPEC256, ISPEC256, input, output); + } + + @Run(test = "testB256toI256") + public static void runB256toI256() throws Throwable { + runRebracketHelper(BSPEC256, ISPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB256toL256(byte[] input, long[] output) { + vectorRebracket(BSPEC256, LSPEC256, input, output); + } + + @Run(test = "testB256toL256") + public static void runB256toL256() throws Throwable { + runRebracketHelper(BSPEC256, LSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB256toF256(byte[] input, float[] output) { + vectorRebracket(BSPEC256, FSPEC256, input, output); + } + + @Run(test = "testB256toF256") + public static void runB256toF256() throws Throwable { + runRebracketHelper(BSPEC256, FSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB256toD256(byte[] input, double[] output) { + vectorRebracket(BSPEC256, DSPEC256, input, output); + } + + @Run(test = "testB256toD256") + public static void runB256toD256() throws Throwable { + runRebracketHelper(BSPEC256, DSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS256toB256(short[] input, byte[] output) { + vectorRebracket(SSPEC256, BSPEC256, input, output); + } + + @Run(test = "testS256toB256") + public static void runS256toB256() throws Throwable { + runRebracketHelper(SSPEC256, BSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS256toI256(short[] input, int[] output) { + vectorRebracket(SSPEC256, ISPEC256, input, output); + } + + @Run(test = "testS256toI256") + public static void runS256toI256() throws Throwable { + runRebracketHelper(SSPEC256, ISPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS256toL256(short[] input, long[] output) { + vectorRebracket(SSPEC256, LSPEC256, input, output); + } + + @Run(test = "testS256toL256") + public static void runS256toL256() throws Throwable { + runRebracketHelper(SSPEC256, LSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS256toF256(short[] input, float[] output) { + vectorRebracket(SSPEC256, FSPEC256, input, output); + } + + @Run(test = "testS256toF256") + public static void runS256toF256() throws Throwable { + runRebracketHelper(SSPEC256, FSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS256toD256(short[] input, double[] output) { + vectorRebracket(SSPEC256, DSPEC256, input, output); + } + + @Run(test = "testS256toD256") + public static void runS256toD256() throws Throwable { + runRebracketHelper(SSPEC256, DSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI256toB256(int[] input, byte[] output) { + vectorRebracket(ISPEC256, BSPEC256, input, output); + } + + @Run(test = "testI256toB256") + public static void runI256toB256() throws Throwable { + runRebracketHelper(ISPEC256, BSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI256toS256(int[] input, short[] output) { + vectorRebracket(ISPEC256, SSPEC256, input, output); + } + + @Run(test = "testI256toS256") + public static void runI256toS256() throws Throwable { + runRebracketHelper(ISPEC256, SSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI256toL256(int[] input, long[] output) { + vectorRebracket(ISPEC256, LSPEC256, input, output); + } + + @Run(test = "testI256toL256") + public static void runI256toL256() throws Throwable { + runRebracketHelper(ISPEC256, LSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI256toF256(int[] input, float[] output) { + vectorRebracket(ISPEC256, FSPEC256, input, output); + } + + @Run(test = "testI256toF256") + public static void runI256toF256() throws Throwable { + runRebracketHelper(ISPEC256, FSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI256toD256(int[] input, double[] output) { + vectorRebracket(ISPEC256, DSPEC256, input, output); + } + + @Run(test = "testI256toD256") + public static void runI256toD256() throws Throwable { + runRebracketHelper(ISPEC256, DSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL256toB256(long[] input, byte[] output) { + vectorRebracket(LSPEC256, BSPEC256, input, output); + } + + @Run(test = "testL256toB256") + public static void runL256toB256() throws Throwable { + runRebracketHelper(LSPEC256, BSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL256toS256(long[] input, short[] output) { + vectorRebracket(LSPEC256, SSPEC256, input, output); + } + + @Run(test = "testL256toS256") + public static void runL256toS256() throws Throwable { + runRebracketHelper(LSPEC256, SSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL256toI256(long[] input, int[] output) { + vectorRebracket(LSPEC256, ISPEC256, input, output); + } + + @Run(test = "testL256toI256") + public static void runL256toI256() throws Throwable { + runRebracketHelper(LSPEC256, ISPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL256toF256(long[] input, float[] output) { + vectorRebracket(LSPEC256, FSPEC256, input, output); + } + + @Run(test = "testL256toF256") + public static void runL256toF256() throws Throwable { + runRebracketHelper(LSPEC256, FSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL256toD256(long[] input, double[] output) { + vectorRebracket(LSPEC256, DSPEC256, input, output); + } + + @Run(test = "testL256toD256") + public static void runL256toD256() throws Throwable { + runRebracketHelper(LSPEC256, DSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF256toB256(float[] input, byte[] output) { + vectorRebracket(FSPEC256, BSPEC256, input, output); + } + + @Run(test = "testF256toB256") + public static void runF256toB256() throws Throwable { + runRebracketHelper(FSPEC256, BSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF256toS256(float[] input, short[] output) { + vectorRebracket(FSPEC256, SSPEC256, input, output); + } + + @Run(test = "testF256toS256") + public static void runF256toS256() throws Throwable { + runRebracketHelper(FSPEC256, SSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF256toI256(float[] input, int[] output) { + vectorRebracket(FSPEC256, ISPEC256, input, output); + } + + @Run(test = "testF256toI256") + public static void runF256toI256() throws Throwable { + runRebracketHelper(FSPEC256, ISPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF256toL256(float[] input, long[] output) { + vectorRebracket(FSPEC256, LSPEC256, input, output); + } + + @Run(test = "testF256toL256") + public static void runF256toL256() throws Throwable { + runRebracketHelper(FSPEC256, LSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF256toD256(float[] input, double[] output) { + vectorRebracket(FSPEC256, DSPEC256, input, output); + } + + @Run(test = "testF256toD256") + public static void runF256toD256() throws Throwable { + runRebracketHelper(FSPEC256, DSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD256toB256(double[] input, byte[] output) { + vectorRebracket(DSPEC256, BSPEC256, input, output); + } + + @Run(test = "testD256toB256") + public static void runD256toB256() throws Throwable { + runRebracketHelper(DSPEC256, BSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD256toS256(double[] input, short[] output) { + vectorRebracket(DSPEC256, SSPEC256, input, output); + } + + @Run(test = "testD256toS256") + public static void runD256toS256() throws Throwable { + runRebracketHelper(DSPEC256, SSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD256toI256(double[] input, int[] output) { + vectorRebracket(DSPEC256, ISPEC256, input, output); + } + + @Run(test = "testD256toI256") + public static void runD256toI256() throws Throwable { + runRebracketHelper(DSPEC256, ISPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD256toL256(double[] input, long[] output) { + vectorRebracket(DSPEC256, LSPEC256, input, output); + } + + @Run(test = "testD256toL256") + public static void runD256toL256() throws Throwable { + runRebracketHelper(DSPEC256, LSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD256toF256(double[] input, float[] output) { + vectorRebracket(DSPEC256, FSPEC256, input, output); + } + + @Run(test = "testD256toF256") + public static void runD256toF256() throws Throwable { + runRebracketHelper(DSPEC256, FSPEC256); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB512toS512(byte[] input, short[] output) { + vectorRebracket(BSPEC512, SSPEC512, input, output); + } + + @Run(test = "testB512toS512") + public static void runB512toS512() throws Throwable { + runRebracketHelper(BSPEC512, SSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB512toI512(byte[] input, int[] output) { + vectorRebracket(BSPEC512, ISPEC512, input, output); + } + + @Run(test = "testB512toI512") + public static void runB512toI512() throws Throwable { + runRebracketHelper(BSPEC512, ISPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB512toL512(byte[] input, long[] output) { + vectorRebracket(BSPEC512, LSPEC512, input, output); + } + + @Run(test = "testB512toL512") + public static void runB512toL512() throws Throwable { + runRebracketHelper(BSPEC512, LSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB512toF512(byte[] input, float[] output) { + vectorRebracket(BSPEC512, FSPEC512, input, output); + } + + @Run(test = "testB512toF512") + public static void runB512toF512() throws Throwable { + runRebracketHelper(BSPEC512, FSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testB512toD512(byte[] input, double[] output) { + vectorRebracket(BSPEC512, DSPEC512, input, output); + } + + @Run(test = "testB512toD512") + public static void runB512toD512() throws Throwable { + runRebracketHelper(BSPEC512, DSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS512toB512(short[] input, byte[] output) { + vectorRebracket(SSPEC512, BSPEC512, input, output); + } + + @Run(test = "testS512toB512") + public static void runS512toB512() throws Throwable { + runRebracketHelper(SSPEC512, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS512toI512(short[] input, int[] output) { + vectorRebracket(SSPEC512, ISPEC512, input, output); + } + + @Run(test = "testS512toI512") + public static void runS512toI512() throws Throwable { + runRebracketHelper(SSPEC512, ISPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS512toL512(short[] input, long[] output) { + vectorRebracket(SSPEC512, LSPEC512, input, output); + } + + @Run(test = "testS512toL512") + public static void runS512toL512() throws Throwable { + runRebracketHelper(SSPEC512, LSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS512toF512(short[] input, float[] output) { + vectorRebracket(SSPEC512, FSPEC512, input, output); + } + + @Run(test = "testS512toF512") + public static void runS512toF512() throws Throwable { + runRebracketHelper(SSPEC512, FSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testS512toD512(short[] input, double[] output) { + vectorRebracket(SSPEC512, DSPEC512, input, output); + } + + @Run(test = "testS512toD512") + public static void runS512toD512() throws Throwable { + runRebracketHelper(SSPEC512, DSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI512toB512(int[] input, byte[] output) { + vectorRebracket(ISPEC512, BSPEC512, input, output); + } + + @Run(test = "testI512toB512") + public static void runI512toB512() throws Throwable { + runRebracketHelper(ISPEC512, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI512toS512(int[] input, short[] output) { + vectorRebracket(ISPEC512, SSPEC512, input, output); + } + + @Run(test = "testI512toS512") + public static void runI512toS512() throws Throwable { + runRebracketHelper(ISPEC512, SSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI512toL512(int[] input, long[] output) { + vectorRebracket(ISPEC512, LSPEC512, input, output); + } + + @Run(test = "testI512toL512") + public static void runI512toL512() throws Throwable { + runRebracketHelper(ISPEC512, LSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI512toF512(int[] input, float[] output) { + vectorRebracket(ISPEC512, FSPEC512, input, output); + } + + @Run(test = "testI512toF512") + public static void runI512toF512() throws Throwable { + runRebracketHelper(ISPEC512, FSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testI512toD512(int[] input, double[] output) { + vectorRebracket(ISPEC512, DSPEC512, input, output); + } + + @Run(test = "testI512toD512") + public static void runI512toD512() throws Throwable { + runRebracketHelper(ISPEC512, DSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL512toB512(long[] input, byte[] output) { + vectorRebracket(LSPEC512, BSPEC512, input, output); + } + + @Run(test = "testL512toB512") + public static void runL512toB512() throws Throwable { + runRebracketHelper(LSPEC512, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL512toS512(long[] input, short[] output) { + vectorRebracket(LSPEC512, SSPEC512, input, output); + } + + @Run(test = "testL512toS512") + public static void runL512toS512() throws Throwable { + runRebracketHelper(LSPEC512, SSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL512toI512(long[] input, int[] output) { + vectorRebracket(LSPEC512, ISPEC512, input, output); + } + + @Run(test = "testL512toI512") + public static void runL512toI512() throws Throwable { + runRebracketHelper(LSPEC512, ISPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL512toF512(long[] input, float[] output) { + vectorRebracket(LSPEC512, FSPEC512, input, output); + } + + @Run(test = "testL512toF512") + public static void runL512toF512() throws Throwable { + runRebracketHelper(LSPEC512, FSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testL512toD512(long[] input, double[] output) { + vectorRebracket(LSPEC512, DSPEC512, input, output); + } + + @Run(test = "testL512toD512") + public static void runL512toD512() throws Throwable { + runRebracketHelper(LSPEC512, DSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF512toB512(float[] input, byte[] output) { + vectorRebracket(FSPEC512, BSPEC512, input, output); + } + + @Run(test = "testF512toB512") + public static void runF512toB512() throws Throwable { + runRebracketHelper(FSPEC512, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF512toS512(float[] input, short[] output) { + vectorRebracket(FSPEC512, SSPEC512, input, output); + } + + @Run(test = "testF512toS512") + public static void runF512toS512() throws Throwable { + runRebracketHelper(FSPEC512, SSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF512toI512(float[] input, int[] output) { + vectorRebracket(FSPEC512, ISPEC512, input, output); + } + + @Run(test = "testF512toI512") + public static void runF512toI512() throws Throwable { + runRebracketHelper(FSPEC512, ISPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF512toL512(float[] input, long[] output) { + vectorRebracket(FSPEC512, LSPEC512, input, output); + } + + @Run(test = "testF512toL512") + public static void runF512toL512() throws Throwable { + runRebracketHelper(FSPEC512, LSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testF512toD512(float[] input, double[] output) { + vectorRebracket(FSPEC512, DSPEC512, input, output); + } + + @Run(test = "testF512toD512") + public static void runF512toD512() throws Throwable { + runRebracketHelper(FSPEC512, DSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD512toB512(double[] input, byte[] output) { + vectorRebracket(DSPEC512, BSPEC512, input, output); + } + + @Run(test = "testD512toB512") + public static void runD512toB512() throws Throwable { + runRebracketHelper(DSPEC512, BSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD512toS512(double[] input, short[] output) { + vectorRebracket(DSPEC512, SSPEC512, input, output); + } + + @Run(test = "testD512toS512") + public static void runD512toS512() throws Throwable { + runRebracketHelper(DSPEC512, SSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD512toI512(double[] input, int[] output) { + vectorRebracket(DSPEC512, ISPEC512, input, output); + } + + @Run(test = "testD512toI512") + public static void runD512toI512() throws Throwable { + runRebracketHelper(DSPEC512, ISPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD512toL512(double[] input, long[] output) { + vectorRebracket(DSPEC512, LSPEC512, input, output); + } + + @Run(test = "testD512toL512") + public static void runD512toL512() throws Throwable { + runRebracketHelper(DSPEC512, LSPEC512); + } + + @Test + @IR(counts = {REINTERPRET_NODE, "1"}) + public static void testD512toF512(double[] input, float[] output) { + vectorRebracket(DSPEC512, FSPEC512, input, output); + } + + @Run(test = "testD512toF512") + public static void runD512toF512() throws Throwable { + runRebracketHelper(DSPEC512, FSPEC512); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java new file mode 100644 index 0000000000000000000000000000000000000000..4bf1c9799f17bd70edba5c5c68b38aeda6a75f18 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape.utils; + +import java.util.List; +import java.util.stream.Stream; + +import static compiler.vectorapi.reshape.utils.VectorReshapeHelper.*; +import static compiler.vectorapi.reshape.utils.VectorSpeciesPair.makePair; + +/** + * The cast intrinsics implemented on each platform. + */ +public class TestCastMethods { + public static final List<VectorSpeciesPair> AVX1_CAST_TESTS = List.of( + makePair(BSPEC64, SSPEC64), + makePair(BSPEC64, SSPEC128), + makePair(BSPEC64, ISPEC128), + makePair(BSPEC64, FSPEC128), + makePair(BSPEC64, DSPEC256), + makePair(SSPEC64, BSPEC64), + makePair(SSPEC128, BSPEC64), + makePair(SSPEC64, ISPEC64), + makePair(SSPEC64, ISPEC128), + makePair(SSPEC64, LSPEC128), + makePair(SSPEC64, FSPEC64), + makePair(SSPEC64, FSPEC128), + makePair(SSPEC64, DSPEC128), + makePair(SSPEC64, DSPEC256), + makePair(ISPEC128, BSPEC64), + makePair(ISPEC64, SSPEC64), + makePair(ISPEC128, SSPEC64), + makePair(ISPEC64, LSPEC128), + makePair(ISPEC64, FSPEC64), + makePair(ISPEC128, FSPEC128), + makePair(ISPEC64, DSPEC128), + makePair(ISPEC128, DSPEC256), + makePair(LSPEC128, SSPEC64), + makePair(LSPEC128, ISPEC64), + makePair(FSPEC64, ISPEC64), + makePair(FSPEC128, ISPEC128), + makePair(FSPEC64, DSPEC128), + makePair(FSPEC128, DSPEC256), + makePair(DSPEC128, FSPEC64), + makePair(DSPEC256, FSPEC128) + ); + + public static final List<VectorSpeciesPair> AVX2_CAST_TESTS = Stream.concat(AVX1_CAST_TESTS.stream(), Stream.of( + makePair(BSPEC128, SSPEC256), + makePair(BSPEC64, ISPEC256), + makePair(BSPEC64, LSPEC256), + makePair(BSPEC64, FSPEC256), + makePair(SSPEC256, BSPEC128), + makePair(SSPEC128, ISPEC256), + makePair(SSPEC64, LSPEC256), + makePair(SSPEC128, FSPEC256), + makePair(ISPEC256, BSPEC64), + makePair(ISPEC256, SSPEC128), + makePair(ISPEC128, LSPEC256), + makePair(ISPEC256, FSPEC256), + makePair(LSPEC256, BSPEC64), + makePair(LSPEC256, SSPEC64), + makePair(LSPEC256, ISPEC128), + makePair(FSPEC256, ISPEC256) + )).toList(); + + public static final List<VectorSpeciesPair> AVX512_CAST_TESTS = Stream.concat(AVX2_CAST_TESTS.stream(), Stream.of( + makePair(BSPEC128, ISPEC512), + makePair(BSPEC64, LSPEC512), + makePair(BSPEC128, FSPEC512), + makePair(BSPEC64, DSPEC512), + makePair(SSPEC256, ISPEC512), + makePair(SSPEC128, LSPEC512), + makePair(SSPEC256, FSPEC512), + makePair(SSPEC128, DSPEC512), + makePair(ISPEC512, BSPEC128), + makePair(ISPEC512, SSPEC256), + makePair(ISPEC256, LSPEC512), + makePair(ISPEC512, FSPEC512), + makePair(ISPEC256, DSPEC512), + makePair(LSPEC512, BSPEC64), + makePair(LSPEC512, SSPEC128), + makePair(LSPEC512, ISPEC256), + makePair(FSPEC512, ISPEC512), + makePair(FSPEC256, DSPEC512), + makePair(DSPEC512, FSPEC256) + )).toList(); + + public static final List<VectorSpeciesPair> AVX512BW_CAST_TESTS = Stream.concat(AVX512_CAST_TESTS.stream(), Stream.of( + makePair(BSPEC256, SSPEC512), + makePair(SSPEC512, BSPEC256) + )).toList(); + + public static final List<VectorSpeciesPair> AVX512DQ_CAST_TESTS = Stream.concat(AVX512_CAST_TESTS.stream(), Stream.of( + makePair(LSPEC128, DSPEC128), + makePair(LSPEC256, DSPEC256), + makePair(LSPEC512, DSPEC512), + makePair(DSPEC128, LSPEC128), + makePair(DSPEC256, LSPEC256), + makePair(DSPEC512, LSPEC512) + )).toList(); + + public static final List<VectorSpeciesPair> SVE_CAST_TESTS = List.of( + makePair(BSPEC64, SSPEC128), + makePair(BSPEC128, SSPEC256), + makePair(BSPEC256, SSPEC512), + makePair(BSPEC64, ISPEC256), + makePair(BSPEC128, ISPEC512), + makePair(BSPEC64, LSPEC512), + makePair(BSPEC64, FSPEC256), + makePair(BSPEC128, FSPEC512), + makePair(BSPEC64, DSPEC512), + makePair(SSPEC128, BSPEC64), + makePair(SSPEC256, BSPEC128), + makePair(SSPEC512, BSPEC256), + makePair(SSPEC64, ISPEC128), + makePair(SSPEC128, ISPEC256), + makePair(SSPEC256, ISPEC512), + makePair(SSPEC64, LSPEC256), + makePair(SSPEC128, LSPEC512), + makePair(SSPEC64, FSPEC128), + makePair(SSPEC128, FSPEC256), + makePair(SSPEC256, FSPEC512), + makePair(SSPEC64, DSPEC256), + makePair(SSPEC128, DSPEC512), + makePair(ISPEC256, BSPEC64), + makePair(ISPEC512, BSPEC128), + makePair(ISPEC128, SSPEC64), + makePair(ISPEC256, SSPEC128), + makePair(ISPEC512, SSPEC256), + makePair(ISPEC64, LSPEC128), + makePair(ISPEC128, LSPEC256), + makePair(ISPEC256, LSPEC512), + makePair(ISPEC64, FSPEC64), + makePair(ISPEC128, FSPEC128), + makePair(ISPEC256, FSPEC256), + makePair(ISPEC512, FSPEC512), + makePair(ISPEC64, DSPEC128), + makePair(ISPEC128, DSPEC256), + makePair(ISPEC256, DSPEC512), + makePair(LSPEC512, BSPEC64), + makePair(LSPEC256, SSPEC64), + makePair(LSPEC512, SSPEC128), + makePair(LSPEC128, ISPEC64), + makePair(LSPEC256, ISPEC128), + makePair(LSPEC512, ISPEC256), + makePair(LSPEC128, FSPEC64), + makePair(LSPEC256, FSPEC128), + makePair(LSPEC512, FSPEC256), + makePair(LSPEC128, DSPEC128), + makePair(LSPEC256, DSPEC256), + makePair(LSPEC512, DSPEC512), + makePair(FSPEC256, BSPEC64), + makePair(FSPEC512, BSPEC128), + makePair(FSPEC128, SSPEC64), + makePair(FSPEC256, SSPEC128), + makePair(FSPEC512, SSPEC256), + makePair(FSPEC64, ISPEC64), + makePair(FSPEC128, ISPEC128), + makePair(FSPEC256, ISPEC256), + makePair(FSPEC512, ISPEC512), + makePair(FSPEC64, LSPEC128), + makePair(FSPEC128, LSPEC256), + makePair(FSPEC256, LSPEC512), + makePair(FSPEC64, DSPEC128), + makePair(FSPEC128, DSPEC256), + makePair(FSPEC256, DSPEC512), + makePair(DSPEC512, BSPEC64), + makePair(DSPEC256, SSPEC64), + makePair(DSPEC512, SSPEC128), + makePair(DSPEC128, ISPEC64), + makePair(DSPEC256, ISPEC128), + makePair(DSPEC512, ISPEC256), + makePair(DSPEC128, LSPEC128), + makePair(DSPEC256, LSPEC256), + makePair(DSPEC512, LSPEC512), + makePair(DSPEC128, FSPEC64), + makePair(DSPEC256, FSPEC128), + makePair(DSPEC512, FSPEC256) + ); + + public static final List<VectorSpeciesPair> NEON_CAST_TESTS = List.of( + makePair(BSPEC64, SSPEC64), + makePair(BSPEC64, SSPEC128), + makePair(BSPEC64, ISPEC128), + makePair(BSPEC64, FSPEC128), + makePair(SSPEC64, BSPEC64), + makePair(SSPEC128, BSPEC64), + makePair(SSPEC64, ISPEC128), + makePair(SSPEC64, FSPEC128), + makePair(ISPEC128, BSPEC64), + makePair(ISPEC128, SSPEC64), + makePair(ISPEC64, LSPEC128), + makePair(ISPEC64, FSPEC64), + makePair(ISPEC128, FSPEC128), + makePair(ISPEC64, DSPEC128), + makePair(LSPEC128, ISPEC64), + makePair(LSPEC128, FSPEC64), + makePair(LSPEC128, DSPEC128), + makePair(FSPEC128, BSPEC64), + makePair(FSPEC128, SSPEC64), + makePair(FSPEC64, ISPEC64), + makePair(FSPEC128, ISPEC128), + makePair(FSPEC64, LSPEC128), + makePair(FSPEC64, DSPEC128), + makePair(DSPEC128, ISPEC64), + makePair(DSPEC128, LSPEC128), + makePair(DSPEC128, FSPEC64) + ); +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/UnsafeUtils.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/UnsafeUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..1f93ebe0c3dc198babef67fd5337a9d462e44794 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/UnsafeUtils.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape.utils; + +import jdk.internal.misc.Unsafe; + +/** + * Unsafe to check for correctness of reinterpret operations. May be replaced with foreign API later. + */ +public class UnsafeUtils { + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + public static long arrayBase(Class<?> etype) { + return UNSAFE.arrayBaseOffset(etype.arrayType()); + } + + public static byte getByte(Object o, long base, int i) { + // This technically leads to UB, what we need is UNSAFE.getByteUnaligned but they seem to be equivalent + return UNSAFE.getByte(o, base + (long)i * Unsafe.ARRAY_BYTE_INDEX_SCALE); + } + + public static void putByte(Object o, long base, int i, byte value) { + // This technically leads to UB, what we need is UNSAFE.putByteUnaligned but they seem to be equivalent + UNSAFE.putByte(o, base + (long)i * Unsafe.ARRAY_BYTE_INDEX_SCALE, value); + } + + public static short getShort(Object o, long base, int i) { + return UNSAFE.getShort(o, base + (long)i * Unsafe.ARRAY_SHORT_INDEX_SCALE); + } + + public static void putShort(Object o, long base, int i, short value) { + UNSAFE.putShort(o, base + (long)i * Unsafe.ARRAY_SHORT_INDEX_SCALE, value); + } + + public static int getInt(Object o, long base, int i) { + return UNSAFE.getInt(o, base + (long)i * Unsafe.ARRAY_INT_INDEX_SCALE); + } + + public static void putInt(Object o, long base, int i, int value) { + UNSAFE.putInt(o, base + (long)i * Unsafe.ARRAY_INT_INDEX_SCALE, value); + } + + public static long getLong(Object o, long base, int i) { + return UNSAFE.getLong(o, base + (long)i * Unsafe.ARRAY_LONG_INDEX_SCALE); + } + + public static void putLong(Object o, long base, int i, long value) { + UNSAFE.putLong(o, base + (long)i * Unsafe.ARRAY_LONG_INDEX_SCALE, value); + } + + public static float getFloat(Object o, long base, int i) { + return UNSAFE.getFloat(o, base + (long)i * Unsafe.ARRAY_FLOAT_INDEX_SCALE); + } + + public static void putFloat(Object o, long base, int i, float value) { + UNSAFE.putFloat(o, base + (long)i * Unsafe.ARRAY_FLOAT_INDEX_SCALE, value); + } + + public static double getDouble(Object o, long base, int i) { + return UNSAFE.getDouble(o, base + (long)i * Unsafe.ARRAY_DOUBLE_INDEX_SCALE); + } + + public static void putDouble(Object o, long base, int i, double value) { + UNSAFE.putDouble(o, base + (long)i * Unsafe.ARRAY_DOUBLE_INDEX_SCALE, value); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/VectorReshapeHelper.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/VectorReshapeHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..c49d45f2a08a4ca19b28688e9fb95f34ce6e250f --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/VectorReshapeHelper.java @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape.utils; + +import compiler.lib.ir_framework.ForceInline; +import compiler.lib.ir_framework.IRNode; +import compiler.lib.ir_framework.TestFramework; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.VarHandle; +import java.lang.reflect.Array; +import java.nio.ByteOrder; +import java.util.List; +import java.util.random.RandomGenerator; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import jdk.incubator.vector.*; +import jdk.test.lib.Asserts; + +public class VectorReshapeHelper { + public static final int INVOCATIONS = 10_000; + + public static final VectorSpecies<Byte> BSPEC64 = ByteVector.SPECIES_64; + public static final VectorSpecies<Short> SSPEC64 = ShortVector.SPECIES_64; + public static final VectorSpecies<Integer> ISPEC64 = IntVector.SPECIES_64; + public static final VectorSpecies<Long> LSPEC64 = LongVector.SPECIES_64; + public static final VectorSpecies<Float> FSPEC64 = FloatVector.SPECIES_64; + public static final VectorSpecies<Double> DSPEC64 = DoubleVector.SPECIES_64; + + public static final VectorSpecies<Byte> BSPEC128 = ByteVector.SPECIES_128; + public static final VectorSpecies<Short> SSPEC128 = ShortVector.SPECIES_128; + public static final VectorSpecies<Integer> ISPEC128 = IntVector.SPECIES_128; + public static final VectorSpecies<Long> LSPEC128 = LongVector.SPECIES_128; + public static final VectorSpecies<Float> FSPEC128 = FloatVector.SPECIES_128; + public static final VectorSpecies<Double> DSPEC128 = DoubleVector.SPECIES_128; + + public static final VectorSpecies<Byte> BSPEC256 = ByteVector.SPECIES_256; + public static final VectorSpecies<Short> SSPEC256 = ShortVector.SPECIES_256; + public static final VectorSpecies<Integer> ISPEC256 = IntVector.SPECIES_256; + public static final VectorSpecies<Long> LSPEC256 = LongVector.SPECIES_256; + public static final VectorSpecies<Float> FSPEC256 = FloatVector.SPECIES_256; + public static final VectorSpecies<Double> DSPEC256 = DoubleVector.SPECIES_256; + + public static final VectorSpecies<Byte> BSPEC512 = ByteVector.SPECIES_512; + public static final VectorSpecies<Short> SSPEC512 = ShortVector.SPECIES_512; + public static final VectorSpecies<Integer> ISPEC512 = IntVector.SPECIES_512; + public static final VectorSpecies<Long> LSPEC512 = LongVector.SPECIES_512; + public static final VectorSpecies<Float> FSPEC512 = FloatVector.SPECIES_512; + public static final VectorSpecies<Double> DSPEC512 = DoubleVector.SPECIES_512; + + public static final String B2X_NODE = IRNode.VECTOR_CAST_B2X; + public static final String S2X_NODE = IRNode.VECTOR_CAST_S2X; + public static final String I2X_NODE = IRNode.VECTOR_CAST_I2X; + public static final String L2X_NODE = IRNode.VECTOR_CAST_L2X; + public static final String F2X_NODE = IRNode.VECTOR_CAST_F2X; + public static final String D2X_NODE = IRNode.VECTOR_CAST_D2X; + public static final String REINTERPRET_NODE = IRNode.VECTOR_REINTERPRET; + + public static void runMainHelper(Class<?> testClass, Stream<VectorSpeciesPair> testMethods, String... flags) { + var test = new TestFramework(testClass); + test.setDefaultWarmup(1); + test.addHelperClasses(VectorReshapeHelper.class); + test.addFlags("--add-modules=jdk.incubator.vector", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED"); + test.addFlags(flags); + String testMethodNames = testMethods + .filter(p -> p.isp().length() <= VectorSpecies.ofLargestShape(p.isp().elementType()).length()) + .filter(p -> p.osp().length() <= VectorSpecies.ofLargestShape(p.osp().elementType()).length()) + .map(VectorSpeciesPair::format) + .collect(Collectors.joining(",")); + test.addFlags("-DTest=" + testMethodNames); + test.start(); + } + + @ForceInline + public static <T, U> void vectorCast(VectorOperators.Conversion<T, U> cop, + VectorSpecies<T> isp, VectorSpecies<U> osp, Object input, Object output) { + var outputVector = readVector(isp, input) + .convertShape(cop, osp, 0); + writeVector(osp, outputVector, output); + } + + public static <T, U> void runCastHelper(VectorOperators.Conversion<T, U> castOp, + VectorSpecies<T> isp, VectorSpecies<U> osp) throws Throwable { + var random = RandomGenerator.getDefault(); + boolean isUnsignedCast = castOp.name().startsWith("ZERO"); + String testMethodName = VectorSpeciesPair.makePair(isp, osp).format(); + var caller = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass(); + var testMethod = MethodHandles.lookup().findStatic(caller, + testMethodName, + MethodType.methodType(void.class, isp.elementType().arrayType(), osp.elementType().arrayType())) + .asType(MethodType.methodType(void.class, Object.class, Object.class)); + Object input = Array.newInstance(isp.elementType(), isp.length()); + Object output = Array.newInstance(osp.elementType(), osp.length()); + long ibase = UnsafeUtils.arrayBase(isp.elementType()); + long obase = UnsafeUtils.arrayBase(osp.elementType()); + for (int iter = 0; iter < INVOCATIONS; iter++) { + // We need to generate arrays with NaN or very large values occasionally + boolean normalArray = random.nextBoolean(); + var abnormalValue = List.of(Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, -1e30, 1e30); + for (int i = 0; i < isp.length(); i++) { + switch (isp.elementType().getName()) { + case "byte" -> UnsafeUtils.putByte(input, ibase, i, (byte)random.nextInt()); + case "short" -> UnsafeUtils.putShort(input, ibase, i, (short)random.nextInt()); + case "int" -> UnsafeUtils.putInt(input, ibase, i, random.nextInt()); + case "long" -> UnsafeUtils.putLong(input, ibase, i, random.nextLong()); + case "float" -> { + if (normalArray || random.nextBoolean()) { + UnsafeUtils.putFloat(input, ibase, i, random.nextFloat(Byte.MIN_VALUE, Byte.MAX_VALUE)); + } else { + UnsafeUtils.putFloat(input, ibase, i, abnormalValue.get(random.nextInt(abnormalValue.size())).floatValue()); + } + } + case "double" -> { + if (normalArray || random.nextBoolean()) { + UnsafeUtils.putDouble(input, ibase, i, random.nextDouble(Byte.MIN_VALUE, Byte.MAX_VALUE)); + } else { + UnsafeUtils.putDouble(input, ibase, i, abnormalValue.get(random.nextInt(abnormalValue.size()))); + } + } + default -> throw new AssertionError(); + } + } + + testMethod.invokeExact(input, output); + + for (int i = 0; i < osp.length(); i++) { + Number expected, actual; + if (i < isp.length()) { + Number initial = switch (isp.elementType().getName()) { + case "byte" -> UnsafeUtils.getByte(input, ibase, i); + case "short" -> UnsafeUtils.getShort(input, ibase, i); + case "int" -> UnsafeUtils.getInt(input, ibase, i); + case "long" -> UnsafeUtils.getLong(input, ibase, i); + case "float" -> UnsafeUtils.getFloat(input, ibase, i); + case "double" -> UnsafeUtils.getDouble(input, ibase, i); + default -> throw new AssertionError(); + }; + expected = switch (osp.elementType().getName()) { + case "byte" -> initial.byteValue(); + case "short" -> { + if (isUnsignedCast) { + yield (short) (initial.longValue() & ((1L << isp.elementSize()) - 1)); + } else { + yield initial.shortValue(); + } + } + case "int" -> { + if (isUnsignedCast) { + yield (int) (initial.longValue() & ((1L << isp.elementSize()) - 1)); + } else { + yield initial.intValue(); + } + } + case "long" -> { + if (isUnsignedCast) { + yield (long) (initial.longValue() & ((1L << isp.elementSize()) - 1)); + } else { + yield initial.longValue(); + } + } + case "float" -> initial.floatValue(); + case "double" -> initial.doubleValue(); + default -> throw new AssertionError(); + }; + } else { + expected = switch (osp.elementType().getName()) { + case "byte" -> (byte)0; + case "short" -> (short)0; + case "int" -> (int)0; + case "long" -> (long)0; + case "float" -> (float)0; + case "double" -> (double)0; + default -> throw new AssertionError(); + }; + } + actual = switch (osp.elementType().getName()) { + case "byte" -> UnsafeUtils.getByte(output, obase, i); + case "short" -> UnsafeUtils.getShort(output, obase, i); + case "int" -> UnsafeUtils.getInt(output, obase, i); + case "long" -> UnsafeUtils.getLong(output, obase, i); + case "float" -> UnsafeUtils.getFloat(output, obase, i); + case "double" -> UnsafeUtils.getDouble(output, obase, i); + default -> throw new AssertionError(); + }; + Asserts.assertEquals(expected, actual); + } + } + } + + @ForceInline + public static void vectorExpandShrink(VectorSpecies<Byte> isp, VectorSpecies<Byte> osp, byte[] input, byte[] output) { + isp.fromByteArray(input, 0, ByteOrder.nativeOrder()) + .reinterpretShape(osp, 0) + .intoByteArray(output, 0, ByteOrder.nativeOrder()); + } + + public static void runExpandShrinkHelper(VectorSpecies<Byte> isp, VectorSpecies<Byte> osp) throws Throwable { + var random = RandomGenerator.getDefault(); + String testMethodName = VectorSpeciesPair.makePair(isp, osp).format(); + var caller = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass(); + var testMethod = MethodHandles.lookup().findStatic(caller, + testMethodName, + MethodType.methodType(void.class, byte.class.arrayType(), byte.class.arrayType())); + byte[] input = new byte[isp.vectorByteSize()]; + byte[] output = new byte[osp.vectorByteSize()]; + for (int iter = 0; iter < INVOCATIONS; iter++) { + random.nextBytes(input); + + testMethod.invokeExact(input, output); + + for (int i = 0; i < osp.vectorByteSize(); i++) { + int expected = i < isp.vectorByteSize() ? input[i] : 0; + int actual = output[i]; + Asserts.assertEquals(expected, actual); + } + } + } + + @ForceInline + public static void vectorDoubleExpandShrink(VectorSpecies<Byte> isp, VectorSpecies<Byte> osp, byte[] input, byte[] output) { + isp.fromByteArray(input, 0, ByteOrder.nativeOrder()) + .reinterpretShape(osp, 0) + .reinterpretShape(isp, 0) + .intoByteArray(output, 0, ByteOrder.nativeOrder()); + } + + public static void runDoubleExpandShrinkHelper(VectorSpecies<Byte> isp, VectorSpecies<Byte> osp) throws Throwable { + var random = RandomGenerator.getDefault(); + String testMethodName = VectorSpeciesPair.makePair(isp, osp).format(); + var caller = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass(); + var testMethod = MethodHandles.lookup().findStatic(caller, + testMethodName, + MethodType.methodType(void.class, byte.class.arrayType(), byte.class.arrayType())); + byte[] input = new byte[isp.vectorByteSize()]; + byte[] output = new byte[isp.vectorByteSize()]; + for (int iter = 0; iter < INVOCATIONS; iter++) { + random.nextBytes(input); + + testMethod.invokeExact(input, output); + + for (int i = 0; i < isp.vectorByteSize(); i++) { + int expected = i < osp.vectorByteSize() ? input[i] : 0; + int actual = output[i]; + Asserts.assertEquals(expected, actual); + } + } + } + + @ForceInline + public static <T, U> void vectorRebracket(VectorSpecies<T> isp, VectorSpecies<U> osp, Object input, Object output) { + var outputVector = readVector(isp, input) + .reinterpretShape(osp, 0); + writeVector(osp, outputVector, output); + } + + public static <T, U> void runRebracketHelper(VectorSpecies<T> isp, VectorSpecies<U> osp) throws Throwable { + var random = RandomGenerator.getDefault(); + String testMethodName = VectorSpeciesPair.makePair(isp, osp).format(); + var caller = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass(); + var testMethod = MethodHandles.lookup().findStatic(caller, + testMethodName, + MethodType.methodType(void.class, isp.elementType().arrayType(), osp.elementType().arrayType())) + .asType(MethodType.methodType(void.class, Object.class, Object.class)); + Object input = Array.newInstance(isp.elementType(), isp.length()); + Object output = Array.newInstance(osp.elementType(), osp.length()); + long ibase = UnsafeUtils.arrayBase(isp.elementType()); + long obase = UnsafeUtils.arrayBase(osp.elementType()); + for (int iter = 0; iter < INVOCATIONS; iter++) { + for (int i = 0; i < isp.vectorByteSize(); i++) { + UnsafeUtils.putByte(input, ibase, i, (byte)random.nextInt()); + } + + testMethod.invokeExact(input, output); + + for (int i = 0; i < osp.vectorByteSize(); i++) { + int expected = i < isp.vectorByteSize() ? UnsafeUtils.getByte(input, ibase, i) : 0; + int actual = UnsafeUtils.getByte(output, obase, i); + Asserts.assertEquals(expected, actual); + } + } + } + + @ForceInline + private static <T> Vector<T> readVector(VectorSpecies<T> isp, Object input) { + return isp.fromArray(input, 0); + } + + @ForceInline + private static <U> void writeVector(VectorSpecies<U> osp, Vector<U> vector, Object output) { + var otype = osp.elementType(); + if (otype == byte.class) { + ((ByteVector)vector).intoArray((byte[])output, 0); + } else if (otype == short.class) { + ((ShortVector)vector).intoArray((short[])output, 0); + } else if (otype == int.class) { + ((IntVector)vector).intoArray((int[])output, 0); + } else if (otype == long.class) { + ((LongVector)vector).intoArray((long[])output, 0); + } else if (otype == float.class) { + ((FloatVector)vector).intoArray((float[])output, 0); + } else if (otype == double.class) { + ((DoubleVector)vector).intoArray((double[])output, 0); + } else { + throw new AssertionError(); + } + } +} diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/VectorSpeciesPair.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/VectorSpeciesPair.java new file mode 100644 index 0000000000000000000000000000000000000000..74497f253abdc0bc84cb8518d20b9f78df6d7904 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/VectorSpeciesPair.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi.reshape.utils; + +import jdk.incubator.vector.VectorSpecies; + +public record VectorSpeciesPair(VectorSpecies<?> isp, VectorSpecies<?> osp, boolean unsignedCast) { + public static VectorSpeciesPair makePair(VectorSpecies<?> isp, VectorSpecies<?> osp, boolean unsignedCast) { + return new VectorSpeciesPair(isp, osp, unsignedCast); + } + + public static VectorSpeciesPair makePair(VectorSpecies<?> isp, VectorSpecies<?> osp) { + return new VectorSpeciesPair(isp, osp, false); + } + + public String format() { + return String.format("test%s%c%dto%c%d", + unsignedCast() ? "U" : "", + Character.toUpperCase(isp().elementType().getName().charAt(0)), + isp().vectorBitSize(), + Character.toUpperCase(osp().elementType().getName().charAt(0)), + osp().vectorBitSize()); + } +} diff --git a/test/hotspot/jtreg/compiler/vectorization/TestPopCountVectorLong.java b/test/hotspot/jtreg/compiler/vectorization/TestPopCountVectorLong.java new file mode 100644 index 0000000000000000000000000000000000000000..e80c7cfac954101dc0049b47d1b766ef6b598543 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorization/TestPopCountVectorLong.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** +* @test +* @summary Test vectorization of popcount for Long +* @requires vm.cpu.features ~= ".*avx512dq.*" +* @requires vm.cpu.features ~= ".*vpopcntdq.*" +* @requires vm.compiler2.enabled +* @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" +* @library /test/lib / +* @run driver compiler.vectorization.TestPopCountVectorLong +*/ + +package compiler.vectorization; +import compiler.lib.ir_framework.*; +import java.util.Random; + + +public class TestPopCountVectorLong { + private long[] input; + private int[] output; + private static final int LEN = 1024; + private Random rng; + + public static void main(String args[]) { + TestFramework.run(TestPopCountVectorLong.class); + } + + public TestPopCountVectorLong() { + input = new long[LEN]; + output = new int[LEN]; + rng = new Random(42); + for (int i = 0; i < LEN; ++i) { + input[i] = rng.nextLong(); + } + } + + @Test // needs to be run in (fast) debug mode + @Warmup(10000) + @IR(counts = {"PopCountVL", ">= 1"}) // Atleast one PopCountVL node is generated if vectorization is successful + public void vectorizeBitCount() { + for (int i = 0; i < LEN; ++i) { + output[i] = Long.bitCount(input[i]); + } + checkResult(); + } + + public void checkResult() { + for (int i = 0; i < LEN; ++i) { + int expected = Long.bitCount(input[i]); + if (output[i] != expected) { + throw new RuntimeException("Invalid result: output[" + i + "] = " + output[i] + " != " + expected); + } + } + } +} + diff --git a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java index 3b997d74dc16f02f67ff3a044f863e71bd0830e3..3117b7a3077e8949f42758ccff503e82474a732f 100644 --- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java +++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java @@ -265,7 +265,8 @@ public class TestGCLogMessages { LogMessageWithLevel exhFailureMessages[] = new LogMessageWithLevel[] { new LogMessageWithLevel("Recalculate Used Memory", Level.DEBUG), new LogMessageWithLevel("Restore Preserved Marks", Level.DEBUG), - new LogMessageWithLevel("Remove Self Forwards", Level.DEBUG), + new LogMessageWithLevel("Restore Retained Regions", Level.DEBUG), + new LogMessageWithLevel("Evacuation Failure Regions", Level.DEBUG), }; private void testWithEvacuationFailureLogs() throws Exception { diff --git a/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData30.java b/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData27.java similarity index 86% rename from test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData30.java rename to test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData27.java index 960fce63afa849a2d370eff6b763dffaab18848b..7324cad9f3c13b6b929bac60d02878c3893a1a92 100644 --- a/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData30.java +++ b/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData27.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ package gc.g1; /** - * @test TestShrinkAuxiliaryData30 + * @test TestShrinkAuxiliaryData27 * @key randomness * @bug 8038423 8061715 8078405 * @summary Checks that decommitment occurs for JVM with different @@ -36,11 +36,11 @@ package gc.g1; * java.management * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData30 + * @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData27 */ -public class TestShrinkAuxiliaryData30 { +public class TestShrinkAuxiliaryData27 { public static void main(String[] args) throws Exception { - new TestShrinkAuxiliaryData(30).test(); + new TestShrinkAuxiliaryData(27).test(); } } diff --git a/test/hotspot/jtreg/gc/logging/TestPrintReferences.java b/test/hotspot/jtreg/gc/logging/TestPrintReferences.java index c3bf80a48a03c693b3dd9b1d7205c3f92d6adfce..6272f08e9943b86895e5fa044767f5930dcde38a 100644 --- a/test/hotspot/jtreg/gc/logging/TestPrintReferences.java +++ b/test/hotspot/jtreg/gc/logging/TestPrintReferences.java @@ -80,9 +80,11 @@ public class TestPrintReferences { private static String refRegex(String reftype) { String countRegex = "[0-9]+"; - return gcLogTimeRegex + indent(6) + reftype + ":\n" + - gcLogTimeRegex + indent(8) + "Discovered: " + countRegex + "\n" + - gcLogTimeRegex + indent(8) + "Cleared: " + countRegex + "\n"; + return gcLogTimeRegex + indent(6) + reftype + " " + + "Discovered: " + countRegex + ", " + + "Dropped: " + countRegex + ", " + + "Processed: " + countRegex + "\n" + ; } private static void checkRefsLogFormat(OutputAnalyzer output) { diff --git a/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnexpectedIUBarrierEA.java b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnexpectedIUBarrierEA.java new file mode 100644 index 0000000000000000000000000000000000000000..8662130c378770a5c179cdae52d83e4138d54be6 --- /dev/null +++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnexpectedIUBarrierEA.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8280885 + * @summary Shenandoah: Some tests failed with "EA: missing allocation reference path" + * @requires vm.gc.Shenandoah + * + * @run main/othervm -XX:-BackgroundCompilation -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=iu + * -XX:CompileCommand=dontinline,TestUnexpectedIUBarrierEA::notInlined TestUnexpectedIUBarrierEA + */ + +public class TestUnexpectedIUBarrierEA { + + private static Object field; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(false); + } + } + + private static void test(boolean flag) { + A a = new A(); + B b = new B(); + b.field = a; + notInlined(); + Object o = b.field; + if (!(o instanceof A)) { + + } + C c = new C(); + c.field = o; + if (flag) { + field = c.field; + } + } + + private static void notInlined() { + + } + + private static class A { + } + + private static class B { + public Object field; + } + + private static class C { + public Object field; + } +} diff --git a/test/hotspot/jtreg/gtest/NMTGtests.java b/test/hotspot/jtreg/gtest/NMTGtests.java index b79f46395fbecc53a450ac57d5db13ff559cde07..57666680b6ba54a66bf29af2813f2586df2503bb 100644 --- a/test/hotspot/jtreg/gtest/NMTGtests.java +++ b/test/hotspot/jtreg/gtest/NMTGtests.java @@ -24,10 +24,15 @@ */ /* - * This tests NMT by running gtests with NMT enabled. - * - * To save time, we just run them for debug builds (where we would catch assertions) and only a selection of tests - * (namely, NMT tests themselves, and - for the detail statistics - os tests, since those reserve a lot and stress NMT) + * This tests NMT by running gtests with NMT enabled (only those which are relevant for NMT) + */ + +/* @test id=nmt-off + * @summary Run NMT-related gtests with NMT switched off + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.xml + * @run main/native GTestWrapper --gtest_filter=NMT*:os* -XX:NativeMemoryTracking=off */ /* @test id=nmt-summary @@ -35,8 +40,7 @@ * @library /test/lib * @modules java.base/jdk.internal.misc * java.xml - * @requires vm.debug - * @run main/native GTestWrapper --gtest_filter=NMT* -XX:NativeMemoryTracking=summary + * @run main/native GTestWrapper --gtest_filter=NMT*:os* -XX:NativeMemoryTracking=summary */ /* @test id=nmt-detail @@ -44,6 +48,5 @@ * @library /test/lib * @modules java.base/jdk.internal.misc * java.xml - * @requires vm.debug * @run main/native GTestWrapper --gtest_filter=NMT*:os* -XX:NativeMemoryTracking=detail */ diff --git a/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java b/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java index 9e04c9ac89aca7d5164a78f3c792026e3da342a7..5694d0fb528fb1c4185bba2e9dce38dc5cc97fb0 100644 --- a/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java +++ b/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,6 @@ public class ClhsdbRegionDetailsScanOopsForG1 { expStrMap.put("g1regiondetails", List.of( "Region", "Eden", - "Survivor", "StartsHumongous", "ContinuesHumongous", "Free")); diff --git a/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeArray.java b/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeArray.java index 44929f05b15213be690d35bdf6c068ed4f66b0e2..244f41873340e9ee8adcce270407083dc0f4e7ab 100644 --- a/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeArray.java +++ b/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * 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,12 @@ import jdk.test.lib.apps.LingeredApp; +import java.lang.ref.Reference; + public class LingeredAppWithLargeArray extends LingeredApp { public static void main(String args[]) { int[] hugeArray = new int[Integer.MAX_VALUE/2]; LingeredApp.main(args); + Reference.reachabilityFence(hugeArray); } } diff --git a/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java b/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java index bc7aec91f99e6bab21fa2581df48c6b51e906d3b..adc81b1f46d52f91b014ce0e71918adb8f7daf13 100644 --- a/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java +++ b/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ import jdk.test.lib.apps.LingeredApp; +import java.lang.ref.Reference; + public class LingeredAppWithLargeStringArray extends LingeredApp { public static void main(String args[]) { String[] hugeArray = new String[Integer.MAX_VALUE/8]; @@ -31,5 +33,6 @@ public class LingeredAppWithLargeStringArray extends LingeredApp { hugeArray[i] = new String(smallArray[i%3]); } LingeredApp.main(args); + Reference.reachabilityFence(hugeArray); } } diff --git a/test/hotspot/jtreg/runtime/8176717/TestInheritFD.java b/test/hotspot/jtreg/runtime/8176717/TestInheritFD.java index 04a739079f9f8d5b204c94cb4e26019438c5601c..37c5280d2367fcf251daab9404e03deb3787293a 100644 --- a/test/hotspot/jtreg/runtime/8176717/TestInheritFD.java +++ b/test/hotspot/jtreg/runtime/8176717/TestInheritFD.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,6 +79,7 @@ public class TestInheritFD { public static final String RETAINS_FD = "VM RESULT => RETAINS FD"; public static final String EXIT = "VM RESULT => VM EXIT"; public static final String LOG_SUFFIX = ".strangelogsuffixthatcanbecheckedfor"; + public static final String USER_DIR = System.getProperty("user.dir"); // first VM public static void main(String[] args) throws Exception { @@ -187,10 +188,10 @@ public class TestInheritFD { static Collection<String> outputContainingFilenames() { long pid = ProcessHandle.current().pid(); - String[] command = lsofCommand().orElseThrow(() -> new RuntimeException("lsof like command not found")); - System.out.println("using command: " + command[0] + " " + command[1]); - return run(command[0], command[1], "" + pid).collect(toList()); + // Only search the directory in which the VM is running (user.dir property). + System.out.println("using command: " + command[0] + " -a +d " + USER_DIR + " " + command[1] + " " + pid); + return run(command[0], "-a", "+d", USER_DIR, command[1], "" + pid).collect(toList()); } static boolean findOpenLogFile(Collection<String> fileNames) { diff --git a/test/hotspot/jtreg/runtime/BootClassAppendProp/GetBootClassPathAppendProp.java b/test/hotspot/jtreg/runtime/BootClassAppendProp/GetBootClassPathAppendProp.java new file mode 100644 index 0000000000000000000000000000000000000000..59d62e5615b015d3dcf97dba55e6ee71b4b6e9b7 --- /dev/null +++ b/test/hotspot/jtreg/runtime/BootClassAppendProp/GetBootClassPathAppendProp.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8225093 + * @summary Check that JVMTI GetSystemProperty API returns the right values for + * property jdk.boot.class.path.append. + * @requires vm.jvmti + * @library /test/lib + * @run main/othervm/native -agentlib:GetBootClassPathAppendProp GetBootClassPathAppendProp + * @run main/othervm/native -Xbootclasspath/a:blah -agentlib:GetBootClassPathAppendProp GetBootClassPathAppendProp one_arg + * + */ + +public class GetBootClassPathAppendProp { + private static native String getSystemProperty(); + + public static void main(String[] args) throws Exception { + String path = getSystemProperty(); + if (args.length > 0) { + if (!path.equals("blah")) { + throw new RuntimeException("Wrong value returned for jdk.boot.class.path.append: " + + path); + } + } else { + if (path != null) { + throw new RuntimeException("Null value expected for jdk.boot.class.path.append: " + + path); + } + } + } +} diff --git a/test/hotspot/jtreg/runtime/BootClassAppendProp/libGetBootClassPathAppendProp.c b/test/hotspot/jtreg/runtime/BootClassAppendProp/libGetBootClassPathAppendProp.c new file mode 100644 index 0000000000000000000000000000000000000000..07f57cff267b4d2c24bae29e8e9bdaba4c88097a --- /dev/null +++ b/test/hotspot/jtreg/runtime/BootClassAppendProp/libGetBootClassPathAppendProp.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include <stdio.h> +#include <string.h> +#include <jvmti.h> + +#ifdef __cplusplus +extern "C" { +#endif + +static jvmtiEnv *jvmti = NULL; + +JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + int err = (*jvm)->GetEnv(jvm, (void**) &jvmti, JVMTI_VERSION_9); + if (err != JNI_OK) { + return JNI_ERR; + } + return JNI_OK; +} + +JNIEXPORT jstring JNICALL +Java_GetBootClassPathAppendProp_getSystemProperty(JNIEnv *env, jclass cls) { + jvmtiError err; + char* prop_value; + + err = (*jvmti)->GetSystemProperty(jvmti, "jdk.boot.class.path.append", &prop_value); + if (err == JVMTI_ERROR_NOT_AVAILABLE) { + return NULL; + } + if (err != JVMTI_ERROR_NONE) { + char err_msg[50]; + snprintf(err_msg, 50, "Wrong JVM TI error code: %d", err); + return (*env)->NewStringUTF(env, err_msg); + } + + return (*env)->NewStringUTF(env, prop_value); +} + +#ifdef __cplusplus +} +#endif diff --git a/test/hotspot/jtreg/runtime/BootstrapMethod/BSMCalledTwice.java b/test/hotspot/jtreg/runtime/BootstrapMethod/BSMCalledTwice.java index bad675a40ffcc4d7f4c98c8f9232a9c0b90bf6dd..a8a8aa060bf038295d045cc2b39778245e37224c 100644 --- a/test/hotspot/jtreg/runtime/BootstrapMethod/BSMCalledTwice.java +++ b/test/hotspot/jtreg/runtime/BootstrapMethod/BSMCalledTwice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,16 @@ * @run main BSMCalledTwice */ +/* + * @test + * @bug 8262134 + * @library /test/lib + * @requires vm.debug + * @modules java.base/jdk.internal.org.objectweb.asm + * @compile -XDignore.symbol.file BSMCalledTwice.java + * @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestC::* -XX:+DeoptimizeALot -XX:+VerifyStack BSMCalledTwice + */ + import java.io.File; import java.io.FileOutputStream; import java.util.*; diff --git a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java index b8e6c41c1ba00e152ad11319dead78f81d90d8c4..e9ccac0879314cdd8777824c7dcac8d320e8f0f3 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java +++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java @@ -21,6 +21,10 @@ * questions. */ +import java.util.Arrays; +import java.util.ArrayList; + +import jdk.test.lib.Platform; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.cli.*; @@ -39,22 +43,24 @@ public class VMDeprecatedOptions { * each entry is {[0]: option name, [1]: value to set * (true/false/n/string)}. */ - public static final String[][] DEPRECATED_OPTIONS = { - // deprecated non-alias flags: - {"MaxGCMinorPauseMillis", "1032"}, - {"MaxRAMFraction", "8"}, - {"MinRAMFraction", "2"}, - {"InitialRAMFraction", "64"}, - {"TLABStats", "false"}, - {"AllowRedefinitionToAddDeleteMethods", "true"}, - {"UseSharedSpaces", "false"}, - {"RequireSharedSpaces", "false"}, - {"DumpSharedSpaces", "false"}, - {"DynamicDumpSharedSpaces", "false"}, + public static final String[][] DEPRECATED_OPTIONS; + static { + ArrayList<String[]> deprecated = new ArrayList( + Arrays.asList(new String[][] { + // deprecated non-alias flags: + {"MaxGCMinorPauseMillis", "1032"}, + {"MaxRAMFraction", "8"}, + {"MinRAMFraction", "2"}, + {"InitialRAMFraction", "64"}, + {"TLABStats", "false"}, + {"AllowRedefinitionToAddDeleteMethods", "true"}, - // deprecated alias flags (see also aliased_jvm_flags): - {"DefaultMaxRAMFraction", "4"}, - {"CreateMinidumpOnCrash", "false"} + // deprecated alias flags (see also aliased_jvm_flags): + {"DefaultMaxRAMFraction", "4"}, + {"CreateMinidumpOnCrash", "false"} + } + )); + DEPRECATED_OPTIONS = deprecated.toArray(new String[][]{}); }; static String getDeprecationString(String optionName) { diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/GenOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/GenOutOfMemoryError.java new file mode 100644 index 0000000000000000000000000000000000000000..79c3c37969fe3a7bc7fd1730d7c75cde47bd4d24 --- /dev/null +++ b/test/hotspot/jtreg/runtime/ErrorHandling/GenOutOfMemoryError.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021, Alibaba Group Holding Limited. All rights reserved. + * 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 8278125 + * @summary Test if OOME has proper stacktrace + * @library /test/lib + * @run main/othervm -Xmx100m -Xms100m GenOutOfMemoryError + */ + +import jdk.test.lib.Asserts; + +public class GenOutOfMemoryError { + private static int OOME_HAS_STACK_CNT = 0; + + private void badMethod(int n){ + try { + System.out.format("bad method was invoked %n", n); + // Try to allocate an array the same size as the heap - it will throw OOME without + // actually consuming available memory. + Integer[] array = new Integer[1000 * 1000 * 100]; + array.hashCode(); + } catch (Throwable t){ + StackTraceElement[] traces = t.getStackTrace(); + if (traces.length != 0) { + OOME_HAS_STACK_CNT++; + } + t.printStackTrace(); + } + } + + public static void main(String[] args) { + GenOutOfMemoryError genOutOfMemoryError = new GenOutOfMemoryError(); + + for (int i = 0; i < 7; i++) { + genOutOfMemoryError.badMethod(i + 1); + } + Asserts.assertTrue(4/*PreallocatedOutOfMemoryErrorCount defaults to 4*/ == OOME_HAS_STACK_CNT, "Some OOMEs do not have stacktraces"); + } +} diff --git a/test/hotspot/jtreg/runtime/HiddenClasses/InstantiateHiddenClass.java b/test/hotspot/jtreg/runtime/HiddenClasses/InstantiateHiddenClass.java index 773588b11f94311fb98f9777d249e10feb0734f8..cb8d59af2f7d4360a95ac64088384e82efb05b23 100644 --- a/test/hotspot/jtreg/runtime/HiddenClasses/InstantiateHiddenClass.java +++ b/test/hotspot/jtreg/runtime/HiddenClasses/InstantiateHiddenClass.java @@ -32,6 +32,7 @@ import java.lang.invoke.MethodType; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodHandles.Lookup.ClassOption; import static java.lang.invoke.MethodHandles.Lookup.ClassOption.*; import jdk.test.lib.compiler.InMemoryJavaCompiler; @@ -44,12 +45,19 @@ public class InstantiateHiddenClass { " } } "); public static void main(String[] args) throws Throwable { + // This class is also used by the appcds/dynamicArchive/RegularHiddenClass.java + // test which will pass the "keep-alive" argument during dynamic CDS dump + // for preventing from being GC'ed prior to the dumping operation. + boolean keepAlive = false; + if (args.length == 1 && args[0].equals("keep-alive")) { + keepAlive = true; + } // Test that a hidden class cannot be found through its name. try { Lookup lookup = MethodHandles.lookup(); - Class<?> cl = lookup.defineHiddenClass(klassbuf, false, NESTMATE).lookupClass(); - Class.forName(cl.getName()).newInstance(); + Class<?> c0 = lookup.defineHiddenClass(klassbuf, false, NESTMATE).lookupClass(); + Class.forName(c0.getName()).newInstance(); throw new RuntimeException("Expected ClassNotFoundException not thrown"); } catch (ClassNotFoundException e ) { // Test passed @@ -60,8 +68,9 @@ public class InstantiateHiddenClass { // Verify that the references to these objects are different and references // to their classes are not equal either. Lookup lookup = MethodHandles.lookup(); - Class<?> c1 = lookup.defineHiddenClass(klassbuf, false, NESTMATE).lookupClass(); - Class<?> c2 = lookup.defineHiddenClass(klassbuf, false, NESTMATE).lookupClass(); + ClassOption classOption = keepAlive ? STRONG : NESTMATE; + Class<?> c1 = lookup.defineHiddenClass(klassbuf, false, classOption).lookupClass(); + Class<?> c2 = lookup.defineHiddenClass(klassbuf, false, classOption).lookupClass(); Object o1 = c1.newInstance(); Object o2 = c2.newInstance(); if (o1 == o2) { diff --git a/test/hotspot/jtreg/runtime/Metaspace/PrintMetaspaceDcmd.java b/test/hotspot/jtreg/runtime/Metaspace/PrintMetaspaceDcmd.java index 413a911e700b10088d9778b042d53e3c0b6f8551..d90a49a0adbcdea6038809f9854cb06d7764e2fc 100644 --- a/test/hotspot/jtreg/runtime/Metaspace/PrintMetaspaceDcmd.java +++ b/test/hotspot/jtreg/runtime/Metaspace/PrintMetaspaceDcmd.java @@ -168,6 +168,29 @@ public class PrintMetaspaceDcmd { output.shouldContain("Virtual space list"); output.shouldMatch("node.*reserved.*committed.*used.*"); + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "chunkfreelist"}); + // Output should look somewhat like this... + // vvvvvvvvvvvvvvvv + // Chunk freelist details: + // Non-Class: + // cm non-class-space: 5 chunks, total word size: 402944. + // -- List[lv00]: empty + // -- List[lv01]: - <Chunk @0x00007f925c124090, state f, base 0x00007f9208600000, level lv01 (262144 words), used 0 words, committed 0 words.> - total : 1 chunks. + // -- List[lv02]: - <Chunk @0x00007f925c1240d8, state f, base 0x00007f9208500000, level lv02 (131072 words), used 0 words, committed 0 words.> - total : 1 chunks. + // -- List[lv03]: empty + // ..... + // + // total chunks: 5, total word size: 402944. + // ^^^^^^^^^^^^^^^^^ + // .... but the actual number of chunks in the freelist is difficult to predict and may be low or zero since + // no class unloading happened yet. + output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + output.shouldContain("Chunk freelist details:"); + // ... but we should see at least one one chunk somewhere, the list should never be empty. + output.shouldMatch(".*-- List\\[lv00\\].*"); + output.shouldMatch(".*total chunks.*total word size.*"); + // Test with different scales pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "scale=G"}); output = new OutputAnalyzer(pb.start()); diff --git a/test/hotspot/jtreg/runtime/NMT/JcmdWithNMTDisabled.java b/test/hotspot/jtreg/runtime/NMT/JcmdWithNMTDisabled.java index 891f82be0bd9f6f7ae0f2c855c01a756c44cecb2..da1dd4979759b772b67f0d563242e10c0092f082 100644 --- a/test/hotspot/jtreg/runtime/NMT/JcmdWithNMTDisabled.java +++ b/test/hotspot/jtreg/runtime/NMT/JcmdWithNMTDisabled.java @@ -30,6 +30,7 @@ * @run driver JcmdWithNMTDisabled 1 */ +import jdk.test.lib.Platform; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.JDKToolFinder; @@ -47,10 +48,12 @@ public class JcmdWithNMTDisabled { OutputAnalyzer output; String testjdkPath = System.getProperty("test.jdk"); - // First run without enabling NMT - pb = ProcessTools.createJavaProcessBuilder("-Dtest.jdk=" + testjdkPath, "JcmdWithNMTDisabled"); - output = new OutputAnalyzer(pb.start()); - output.shouldHaveExitValue(0); + // First run without enabling NMT (not in debug, where NMT is by default on) + if (!Platform.isDebugBuild()) { + pb = ProcessTools.createJavaProcessBuilder("-Dtest.jdk=" + testjdkPath, "JcmdWithNMTDisabled"); + output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + } // Then run with explicitly disabling NMT, should not be any difference pb = ProcessTools.createJavaProcessBuilder("-Dtest.jdk=" + testjdkPath, "-XX:NativeMemoryTracking=off", "JcmdWithNMTDisabled"); diff --git a/test/hotspot/jtreg/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java b/test/hotspot/jtreg/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java index 7e45c3f16d74998ba91931618aa47aeef92055a8..31ab2537fe1e9864e7210c612278ed7b529c0027 100644 --- a/test/hotspot/jtreg/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java +++ b/test/hotspot/jtreg/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java @@ -38,7 +38,7 @@ public class PrintNMTStatisticsWithNMTDisabled { public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UnlockDiagnosticVMOptions", - "-XX:+PrintNMTStatistics", + "-XX:+PrintNMTStatistics", "-XX:NativeMemoryTracking=off", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("warning: PrintNMTStatistics is disabled, because native memory tracking is not enabled"); diff --git a/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java b/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java new file mode 100644 index 0000000000000000000000000000000000000000..7226c8ed05819acec0a97c5881d148f6f5e9132c --- /dev/null +++ b/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java @@ -0,0 +1,86 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * 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 TestSpinPause + * @summary JVM runtime can use SpinPause function for synchronized statements. + * Check different implementations of JVM SpinPause don't crash JVM. + * @bug 8278241 + * @library /test/lib + * + * @requires os.arch=="aarch64" + * + * @run main/othervm TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=none TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop -XX:OnSpinWaitInstCount=10 TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -Xint TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=none TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop -XX:OnSpinWaitInstCount=10 TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -Xcomp TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=none TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop -XX:OnSpinWaitInstCount=10 TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield -XX:OnSpinWaitInstCount=3 TestSpinPause + */ + +public class TestSpinPause { + private Integer[] valueHolder; + + private TestSpinPause () { + valueHolder = new Integer[] {Integer.valueOf(101)}; + } + + private void getSet() { + final int iterCount = 100; + for (int i = 0; i < iterCount; ++i) { + synchronized (valueHolder) { + Integer v = valueHolder[0]; + valueHolder[0] = Integer.reverse(v); + } + } + } + + public static void main(String[] args) throws Exception { + TestSpinPause test = new TestSpinPause(); + Thread t1 = new Thread(test::getSet); + Thread t2 = new Thread(test::getSet); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + System.out.println("Done: " + test.valueHolder[0]); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/SharedArchiveFile.java b/test/hotspot/jtreg/runtime/cds/SharedArchiveFile.java index d58bc0e888d0022605afb268311501b1f510ed91..83a1ce07bfcb1e7a669e5436f4ee5544d38c4add 100644 --- a/test/hotspot/jtreg/runtime/cds/SharedArchiveFile.java +++ b/test/hotspot/jtreg/runtime/cds/SharedArchiveFile.java @@ -45,12 +45,6 @@ public class SharedArchiveFile { .setArchiveName("./SharedArchiveFile.jsa"); CDSTestUtils.createArchiveAndCheck(opts); - // -XX:+DumpSharedSpaces should behave the same as -Xshare:dump - opts = (new CDSOptions()) - .addPrefix("-XX:+DumpSharedSpaces", "-Xlog:cds") - .setArchiveName("./SharedArchiveFile.jsa"); - CDSTestUtils.createArchiveAndCheck(opts); - opts = (new CDSOptions()) .setArchiveName("./SharedArchiveFile.jsa"); CDSTestUtils.run(opts) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/ClassListWithCustomClassNoSource.java b/test/hotspot/jtreg/runtime/cds/appcds/ClassListWithCustomClassNoSource.java new file mode 100644 index 0000000000000000000000000000000000000000..4e5c52402a0705cef38c98d3fcc6cdc680fd0076 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/ClassListWithCustomClassNoSource.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.ProtectionDomain; + + +public class ClassListWithCustomClassNoSource { + private static byte[] helloBytes; + private static final String HELLO = "Hello"; + static class CL extends ClassLoader { + private ProtectionDomain pd; + public CL(String name, ClassLoader parent, ProtectionDomain protD) { + super(name, parent); + pd = protD; + } + + @Override + protected Class<?> findClass(String name) throws ClassNotFoundException { + if (pd == null) { + pd = new ProtectionDomain(null, null); + } + return defineClass(name, helloBytes, 0, helloBytes.length, pd); + } + } + + public static void main(String[] args) throws Exception { + if (args.length != 1) { + throw new RuntimeException("Invalid arg, Use 1, 2, or 3"); + } + + ClassLoader thisLoader = ClassListWithCustomClassNoSource.class.getClassLoader(); + helloBytes = thisLoader.getResourceAsStream(HELLO + ".class").readAllBytes(); + + switch(args[0]) { + case "1": + Class<?> cls1 = (new CL("HelloLoader", null, null)).loadClass(HELLO); + System.out.println(HELLO + " was successfully loaded by " + cls1.getClassLoader().getName()); + break; + case "2": + ProtectionDomain p = ClassListWithCustomClassNoSource.class.getProtectionDomain(); + Class<?> cls2 = (new CL("HelloLoader", null, p)).loadClass(HELLO); + System.out.println(HELLO + " was successfully loaded by " + cls2.getClassLoader().getName()); + break; + case "3": + URL url = ClassListWithCustomClassNoSource.class.getProtectionDomain().getCodeSource().getLocation(); + URLClassLoader urlLoader = new URLClassLoader("HelloClassLoader", new URL[] {url}, null); + Class<?> cls = urlLoader.loadClass(HELLO); + if (cls != null) { + System.out.println(HELLO + " was loaded by " + cls.getClassLoader().getName()); + if (urlLoader != cls.getClassLoader()) { + System.out.println(HELLO + " was not loaded by " + urlLoader.getName()); + } + } else { + System.out.println(HELLO + " is not loaded"); + } + break; + default: + throw new RuntimeException("Should have one argument, 1, 2 or 3"); + } + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/ClassSpecializerTestApp.java b/test/hotspot/jtreg/runtime/cds/appcds/ClassSpecializerTestApp.java new file mode 100644 index 0000000000000000000000000000000000000000..7b9363e8c8f0f849719086ad5c13fb0d9a2f9039 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/ClassSpecializerTestApp.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +// When this class is executed, the following classes will be generated by +// java.lang.invoke.ClassSpecializer with the code source +// "_ClassSpecializer_generateConcreteSpeciesCode". +// +// - java.lang.invoke.BoundMethodHandle$Species_LFDIIL +// - java.lang.invoke.BoundMethodHandle$Species_LFDIILJ +// - java.lang.invoke.BoundMethodHandle$Species_LFDIILJD +// - ... +// +// The TestDumpClassListSource test case checks that these classes are not +// written into the classlist, as they cannot be handled by -Xshare:dump +public class ClassSpecializerTestApp { + public static void main(String args[]) throws Throwable { + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(void.class, float.class, double.class, int.class, + boolean.class, Object.class, long.class, double.class); + MethodHandle mh = lookup.findStatic(ClassSpecializerTestApp.class, "callme", mt); + invoke(mh, 4.0f, 5.0, 6, true, null, 7L, 8.0); + } + + private static Object invoke(MethodHandle mh, Object ... args) throws Throwable { + try { + for (Object o : args) { + mh = MethodHandles.insertArguments(mh, 0, o); + } + return mh.invoke(); + } catch (Throwable t) { + System.out.println("Failed to find, link and/or invoke " + mh.toString() + ": " + t.getMessage()); + throw t; + } + } + + private static void callme(float f, double d, int i, boolean b, Object o, long l, double d2) {} +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/CommandLineFlagCombo.java b/test/hotspot/jtreg/runtime/cds/appcds/CommandLineFlagCombo.java index 045d286115b80805a5a42c783ad72befd4f3aef7..b0f18cd453e0c56612f4aef6f8bcfc9ea24e9ad5 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/CommandLineFlagCombo.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/CommandLineFlagCombo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,11 @@ * @run main/othervm/timeout=240 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. CommandLineFlagCombo */ +import java.io.File; + import jdk.test.lib.BuildHelper; import jdk.test.lib.Platform; +import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import sun.hotspot.code.Compiler; @@ -47,6 +50,7 @@ import sun.hotspot.WhiteBox; public class CommandLineFlagCombo { + private static String HELLO_WORLD = "Hello World"; // shared base address test table private static final String[] testTable = { "-XX:+UseG1GC", "-XX:+UseSerialGC", "-XX:+UseParallelGC", @@ -83,7 +87,7 @@ public class CommandLineFlagCombo { if ((TestCommon.isDynamicArchive() && !testEntry.contains("ObjectAlignmentInBytes")) || !TestCommon.isDynamicArchive()) { OutputAnalyzer execOutput = TestCommon.exec(appJar, testEntry, "Hello"); - TestCommon.checkExec(execOutput, "Hello World"); + TestCommon.checkExec(execOutput, HELLO_WORLD); } } @@ -105,8 +109,10 @@ public class CommandLineFlagCombo { TestCommon.checkDump(dumpOutput, "Loading classes to share"); OutputAnalyzer execOutput = TestCommon.exec(appJar, run_g1Flag, run_serialFlag, "Hello"); - TestCommon.checkExec(execOutput, "Hello World"); + TestCommon.checkExec(execOutput, HELLO_WORLD); } + + testExtraCase(appJar, classList); } private static boolean skipTestCase(String testEntry) throws Exception { @@ -128,4 +134,41 @@ public class CommandLineFlagCombo { } return false; } + + // { -Xshare:dump, -XX:ArchiveClassesAtExit} x { -XX:DumpLoadedClassList } + private static void testExtraCase(String jarFile, String[] classList) throws Exception { + // 1. -Xshare:dump -XX:-XX:DumpLoadedClassFile + String dumpedListName = "tmpClassList.list"; + File listFile = new File(dumpedListName); + if (listFile.exists()) { + listFile.delete(); + } + OutputAnalyzer dumpOutput = TestCommon.dump(jarFile, classList, "-XX:DumpLoadedClassList=" + dumpedListName); + TestCommon.checkDump(dumpOutput, "Loading classes to share"); + if (!listFile.exists()) { + throw new RuntimeException("ClassList file " + dumpedListName + " should be created"); + } + + // 2. -XX:ArchiveClassesAtExit -XX:DumpLoadedClassFile + String dynName = "tmpDyn.jsa"; + File dynFile = new File(dynName); + if (dynFile.exists()) { + dynFile.delete(); + } + if (listFile.exists()) { + listFile.delete(); + } + String[] args = new String[] { + "-cp", jarFile, "-XX:ArchiveClassesAtExit=" + dynName, "-XX:DumpLoadedClassList=" + dumpedListName, "Hello"}; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); + OutputAnalyzer output = TestCommon.executeAndLog(pb, "combo"); + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD); + if (!dynFile.exists()) { + throw new RuntimeException("Dynamic archive file " + dynName + " should be created"); + } + if (!listFile.exists()) { + throw new RuntimeException("ClassList file " + dumpedListName + " should be created"); + } + } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java b/test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java index a0a898989e1aad32d97bff58532b87e70ee6c300..b0851f46e9cbfa1e3940c8e8cfb7bb278a8f2f4b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ */ public class DumpClassListWithLF extends ClassListFormatBase { - static final String REPLACE_OK = "Replaced class java/lang/invoke/DirectMethodHandle$Holder"; + static final String REPLACE_OK = "Regenerated class java/lang/invoke/DirectMethodHandle$Holder"; public static void main(String[] args) throws Throwable { String appJar = JarBuilder.getOrCreateHelloJar(); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/DumpingWithNoCoops.java b/test/hotspot/jtreg/runtime/cds/appcds/DumpingWithNoCoops.java new file mode 100644 index 0000000000000000000000000000000000000000..00fed755b7e1905556d845da9419be69a58bc5f5 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/DumpingWithNoCoops.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8255495 + * @summary Test CDS with UseCompressedOops disable with various heap sizes. + * @requires vm.cds.write.archived.java.heap + * @requires vm.gc.G1 + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @compile test-classes/Hello.java + * @run driver DumpingWithNoCoops + */ + +import java.util.ArrayList; +import java.util.List; + +import jdk.test.lib.process.OutputAnalyzer; + +public class DumpingWithNoCoops { + static class HeapArgs { + int initialSize, minSize, maxSize; + HeapArgs(int initial, int min, int max) { + initialSize = initial; + minSize = min; + maxSize = max; + } + String heapArgsString(HeapArgs ha) { + String heapArgs = ""; + if (ha.initialSize > 0) { + heapArgs += "-XX:InitialHeapSize=" + ha.initialSize + "g"; + } + if (ha.minSize > 0) { + if (heapArgs.length() > 0) { + heapArgs += " "; + } + heapArgs += "-XX:MinHeapSize=" + ha.minSize + "g"; + } + if (ha.maxSize > 0) { + if (heapArgs.length() > 0) { + heapArgs += " "; + } + heapArgs += "-XX:MaxHeapSize=" + ha.maxSize + "g"; + } + return heapArgs; + } + } + + static HeapArgs[] heapArgsCases = { + // InitialHeapSize, MinHeapSize, MaxHeapSize + // all sizes are in the unit of GB + // size of 0 means don't set the heap size + new HeapArgs( 0, 0, 0), + new HeapArgs( 8, 0, 0), + new HeapArgs( 0, 8, 0), + new HeapArgs( 0, 0, 8), + new HeapArgs( 8, 8, 0), + new HeapArgs( 0, 8, 8), + new HeapArgs( 8, 0, 8), + new HeapArgs( 8, 8, 8), + new HeapArgs( 2, 1, 33), + }; + + public static void main(String[] args) throws Exception { + final String noCoops = "-XX:-UseCompressedOops"; + final String logArg = "-Xlog:gc+heap=trace,cds=debug"; + JarBuilder.getOrCreateHelloJar(); + String appJar = TestCommon.getTestJar("hello.jar"); + String appClasses[] = TestCommon.list("Hello"); + + for (HeapArgs ha : heapArgsCases) { + String heapArg = ha.heapArgsString(ha); + List<String> dumptimeArgs = new ArrayList<String>(); + // UseCompressedOops is ergonomically disabled for MaxHeapSize > 32g. + if (ha.maxSize < 32) { + dumptimeArgs.add(noCoops); + } + dumptimeArgs.add(logArg); + OutputAnalyzer output; + if (heapArg.length() == 0) { + System.out.println("\n Test without heap args\n"); + output = TestCommon.dump(appJar, appClasses, dumptimeArgs.toArray(new String[0])); + } else { + System.out.println("\n Test with heap args: " + heapArg + "\n"); + String[] heapSizes = heapArg.split(" "); + for (String heapSize : heapSizes) { + dumptimeArgs.add(heapSize); + } + output = TestCommon.dump(appJar, appClasses, dumptimeArgs.toArray(new String[0])); + output.shouldContain("Setting MaxHeapSize to 4G for CDS dumping"); + } + TestCommon.checkDump(output); + + TestCommon.run("-cp", appJar, + logArg, "-Xlog:class+load", noCoops, "Hello") + .assertNormalExit("Hello source: shared objects file"); + } + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/MoveJDKTest.java b/test/hotspot/jtreg/runtime/cds/appcds/MoveJDKTest.java index c5ad8e53873a0e25c8f220b8c29e2b2136e00fb9..b127fec860461d7adb123b915cfe6b3faf62956b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/MoveJDKTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/MoveJDKTest.java @@ -47,37 +47,39 @@ public class MoveJDKTest { public static void main(String[] args) throws Exception { String java_home_src = System.getProperty("java.home"); String java_home_dst = CDSTestUtils.getOutputDir() + File.separator + "moved_jdk"; + String homeJava = java_home_src + File.separator + "bin" + File.separator + "java"; + String dstJava = java_home_dst + File.separator + "bin" + File.separator + "java"; TestCommon.startNewArchiveName(); String jsaFile = TestCommon.getCurrentArchiveName(); String jsaOpt = "-XX:SharedArchiveFile=" + jsaFile; { - ProcessBuilder pb = makeBuilder(java_home_src + "/bin/java", "-Xshare:dump", jsaOpt); + ProcessBuilder pb = CDSTestUtils.makeBuilder(homeJava, "-Xshare:dump", jsaOpt); TestCommon.executeAndLog(pb, "dump") .shouldHaveExitValue(0); } { - ProcessBuilder pb = makeBuilder(java_home_src + "/bin/java", - "-Xshare:auto", - jsaOpt, - "-Xlog:class+path=info", - "-version"); + ProcessBuilder pb = CDSTestUtils.makeBuilder(homeJava, + "-Xshare:auto", + jsaOpt, + "-Xlog:class+path=info", + "-version"); OutputAnalyzer out = TestCommon.executeAndLog(pb, "exec-src"); out.shouldHaveExitValue(0); out.shouldNotContain("shared class paths mismatch"); out.shouldNotContain("BOOT classpath mismatch"); } - clone(new File(java_home_src), new File(java_home_dst)); + CDSTestUtils.clone(new File(java_home_src), new File(java_home_dst)); System.out.println("============== Cloned JDK at " + java_home_dst); // Test runtime with cloned JDK { - ProcessBuilder pb = makeBuilder(java_home_dst + "/bin/java", - "-Xshare:auto", - jsaOpt, - "-Xlog:class+path=info", - "-version"); + ProcessBuilder pb = CDSTestUtils.makeBuilder(dstJava, + "-Xshare:auto", + jsaOpt, + "-Xlog:class+path=info", + "-version"); OutputAnalyzer out = TestCommon.executeAndLog(pb, "exec-dst"); out.shouldHaveExitValue(0); out.shouldNotContain("shared class paths mismatch"); @@ -89,21 +91,21 @@ public class MoveJDKTest { String fake_modules = copyFakeModulesFromHelloJar(); String dumptimeBootAppendOpt = "-Xbootclasspath/a:" + fake_modules; { - ProcessBuilder pb = makeBuilder(java_home_src + "/bin/java", - "-Xshare:dump", - dumptimeBootAppendOpt, - jsaOpt); + ProcessBuilder pb = CDSTestUtils.makeBuilder(homeJava, + "-Xshare:dump", + dumptimeBootAppendOpt, + jsaOpt); TestCommon.executeAndLog(pb, "dump") .shouldHaveExitValue(0); } { String runtimeBootAppendOpt = dumptimeBootAppendOpt + System.getProperty("path.separator") + helloJar; - ProcessBuilder pb = makeBuilder(java_home_dst + "/bin/java", - "-Xshare:auto", - runtimeBootAppendOpt, - jsaOpt, - "-Xlog:class+path=info", - "-version"); + ProcessBuilder pb = CDSTestUtils.makeBuilder(dstJava, + "-Xshare:auto", + runtimeBootAppendOpt, + jsaOpt, + "-Xlog:class+path=info", + "-version"); OutputAnalyzer out = TestCommon.executeAndLog(pb, "exec-dst"); out.shouldHaveExitValue(0); out.shouldNotContain("shared class paths mismatch"); @@ -111,78 +113,17 @@ public class MoveJDKTest { } // Test with no modules image in the <java home>/lib directory - renameModulesFile(java_home_dst); + String locDir = java_home_dst + File.separator + "lib"; + CDSTestUtils.rename(new File(locDir + File.separator + "modules"), + new File(locDir + File.separator + "orig-modules")); { - ProcessBuilder pb = makeBuilder(java_home_dst + "/bin/java", - "-version"); + ProcessBuilder pb = CDSTestUtils.makeBuilder(dstJava, "-version"); OutputAnalyzer out = TestCommon.executeAndLog(pb, "exec-missing-modules"); out.shouldHaveExitValue(1); out.shouldContain("Failed setting boot class path."); } } - // Do a cheap clone of the JDK. Most files can be sym-linked. However, $JAVA_HOME/bin/java and $JAVA_HOME/lib/.../libjvm.so" - // must be copied, because the java.home property is derived from the canonicalized paths of these 2 files. - static void clone(File src, File dst) throws Exception { - if (dst.exists()) { - if (!dst.isDirectory()) { - throw new RuntimeException("Not a directory :" + dst); - } - } else { - if (!dst.mkdir()) { - throw new RuntimeException("Cannot create directory: " + dst); - } - } - final String jvmLib = System.mapLibraryName("jvm"); - for (String child : src.list()) { - if (child.equals(".") || child.equals("..")) { - continue; - } - - File child_src = new File(src, child); - File child_dst = new File(dst, child); - if (child_dst.exists()) { - throw new RuntimeException("Already exists: " + child_dst); - } - if (child_src.isFile()) { - if (child.equals(jvmLib) || child.equals("java")) { - Files.copy(child_src.toPath(), /* copy data to -> */ child_dst.toPath()); - } else { - Files.createSymbolicLink(child_dst.toPath(), /* link to -> */ child_src.toPath()); - } - } else { - clone(child_src, child_dst); - } - } - } - - static void renameModulesFile(String javaHome) throws Exception { - String modulesDir = javaHome + File.separator + "lib"; - File origModules = new File(modulesDir, "modules"); - if (!origModules.exists()) { - throw new RuntimeException("modules file not found"); - } - - File renamedModules = new File(modulesDir, "orig_modules"); - if (renamedModules.exists()) { - throw new RuntimeException("found orig_modules unexpectedly"); - } - - boolean success = origModules.renameTo(renamedModules); - if (!success) { - throw new RuntimeException("rename modules file failed"); - } - } - - static ProcessBuilder makeBuilder(String... args) throws Exception { - System.out.print("["); - for (String s : args) { - System.out.print(" " + s); - } - System.out.println(" ]"); - return new ProcessBuilder(args); - } - private static String copyFakeModulesFromHelloJar() throws Exception { String outDir = CDSTestUtils.getOutputDir(); String newFile = "hello.modules"; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/NonExistClasspath.java b/test/hotspot/jtreg/runtime/cds/appcds/NonExistClasspath.java index a08f1c5ff150aebc791fb91b34eff5b88e7f8f33..7f2af4bdcab5e60ebc04239ef88bf647cb5cfeb9 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/NonExistClasspath.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/NonExistClasspath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,13 @@ import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.process.OutputAnalyzer; public class NonExistClasspath { + static final String outDir = CDSTestUtils.getOutputDir(); + static final String newFile = "non-exist.jar"; + static final String nonExistPath = outDir + File.separator + newFile; + static final String emptyJarPath = outDir + File.separator + "empty.jar"; + static final String errorMessage1 = "Unable to use shared archive"; + static final String errorMessage2 = "shared class paths mismatch"; + public static void main(String[] args) throws Exception { String appJar = JarBuilder.getOrCreateHelloJar(); doTest(appJar, false); @@ -47,13 +54,7 @@ public class NonExistClasspath { } static void doTest(String appJar, boolean bootcp) throws Exception { - String outDir = CDSTestUtils.getOutputDir(); - String newFile = "non-exist.jar"; - String nonExistPath = outDir + File.separator + newFile; - final String errorMessage1 = "Unable to use shared archive"; - final String errorMessage2 = "shared class paths mismatch"; final String errorMessage3 = (bootcp ? "BOOT" : "APP") + " classpath mismatch"; - (new File(nonExistPath)).delete(); String classPath = nonExistPath + File.pathSeparator + appJar; @@ -100,6 +101,81 @@ public class NonExistClasspath { "-Xlog:class+path=trace", "Hello")) .assertAbnormalExit(errorMessage1, errorMessage2, errorMessage3); + + if (bootcp) { + doMoreBCPTests(appJar, errorMessage3); + } + } + + static void doMoreBCPTests(String appJar, String errorMessage3) throws Exception { + + // Dump an archive with non-existent boot class path. + (new File(nonExistPath)).delete(); + TestCommon.testDump("foobar", TestCommon.list("Hello"), make_args(true, nonExistPath, "-cp", appJar)); + + // Run with non-existent boot class path, test should pass. + TestCommon.run(make_args(true, + nonExistPath, + "-cp", appJar, + "-Xlog:class+path=trace", + "Hello")) + .assertNormalExit(); + + // Run with existent boot class path, test should fail. + TestCommon.run(make_args(true, + appJar, + "-cp", appJar, + "-Xlog:class+path=trace", + "Hello")) + .assertAbnormalExit(errorMessage1, errorMessage2, errorMessage3); + + // Dump an archive with existent boot class path. + TestCommon.testDump("foobar", TestCommon.list("Hello"), make_args(true, appJar)); + + // Run with non-existent boot class path, test should fail. + TestCommon.run(make_args(true, + nonExistPath, + "-Xlog:class+path=trace", + "Hello")) + .assertAbnormalExit(errorMessage1, errorMessage2, errorMessage3); + + // Run with existent boot class path, test should pass. + TestCommon.run(make_args(true, + appJar, + "-Xlog:class+path=trace", + "Hello")) + .assertNormalExit(); + + // Test with empty jar file. + (new File(emptyJarPath)).delete(); + (new File(emptyJarPath)).createNewFile(); + + // Dump an archive with an empty jar in the boot class path. + TestCommon.testDump("foobar", TestCommon.list("Hello"), make_args(true, emptyJarPath, "-cp", appJar)); + + // Run with an empty jar in boot class path, test should pass. + TestCommon.run(make_args(true, + emptyJarPath, + "-cp", appJar, + "-Xlog:class+path=trace", + "Hello")) + .assertNormalExit(); + + // Run with non-existent boot class path, test should pass. + TestCommon.run(make_args(true, + nonExistPath, + "-cp", appJar, + "-Xlog:class+path=trace", + "Hello")) + .assertNormalExit(); + + // Run with existent boot class path, test should fail. + TestCommon.run(make_args(true, + appJar, + "-cp", appJar, + "-Xlog:class+path=trace", + "Hello")) + .assertAbnormalExit(errorMessage1, errorMessage2, errorMessage3); } static String[] make_args(boolean bootcp, String cp, String... suffix) { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/PrintSharedArchiveAndExit.java b/test/hotspot/jtreg/runtime/cds/appcds/PrintSharedArchiveAndExit.java index fc34e932dc450b50c2810b61c370cda806d83865..9a74dcb0d3b39c5469dedaf0eabf3cddbf1fc3c3 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/PrintSharedArchiveAndExit.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/PrintSharedArchiveAndExit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,16 +87,16 @@ public class PrintSharedArchiveAndExit { TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "Hello") .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg)); - log("Execution with simple errors -- with 'simple' errors like missing or modified\n" + - "JAR files, the VM should try to continue to print the remaining information.\n" + - "Use an invalid Boot CP -- all the JAR paths should be checked"); + log("Non-existent boot cp should be ignored, test should pass."); TestCommon.run( "-cp", cp, "-Xbootclasspath/a:foo.jar", "-XX:+PrintSharedArchiveAndExit") - .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[BOOT classpath mismatch, ")); + .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg)); - log("Use an App CP shorter than the one at dump time -- all the JAR paths should be checked"); + log("Execution with simple errors -- with 'simple' errors like missing or modified\n" + + "JAR files, the VM should try to continue to print the remaining information.\n" + + "Use an App CP shorter than the one at dump time -- all the JAR paths should be checked"); TestCommon.run( "-cp", ".", "-XX:+PrintSharedArchiveAndExit") diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java index 57086f343b375d14321bafde983d485c22060011..fd0291f06e01ca0dbba3a1cb9f5e9ca816f5a329 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,8 @@ public class SharedArchiveConsistency { public static boolean shareAuto; // true == -Xshare:auto // false == -Xshare:on + private static int genericHeaderMinVersion; // minimum supported CDS version + private static int currentCDSArchiveVersion; // current CDS version in java process // The following should be consistent with the enum in the C++ MetaspaceShared class public static String[] shared_region_name = { "rw", // ReadWrite @@ -104,6 +106,9 @@ public class SharedArchiveConsistency { throw new RuntimeException("Arg must be 'on' or 'auto'"); } shareAuto = args[0].equals("auto"); + genericHeaderMinVersion = CDSArchiveUtils.getGenericHeaderMinVersion(); + currentCDSArchiveVersion = CDSArchiveUtils.getCurrentCDSArchiveVersion(); + String jarFile = JarBuilder.getOrCreateHelloJar(); // dump (appcds.jsa created) @@ -112,7 +117,8 @@ public class SharedArchiveConsistency { // test, should pass System.out.println("1. Normal, should pass but may fail\n"); - String[] execArgs = {"-Xlog:cds=debug", "-cp", jarFile, "Hello"}; + // disable VerifySharedSpaces, it may be turned on by jtreg args + String[] execArgs = {"-Xlog:cds=debug", "-XX:-VerifySharedSpaces", "-cp", jarFile, "Hello"}; // tests that corrupt contents of the archive need to run with // VerifySharedSpaces enabled to detect inconsistencies String[] verifyExecArgs = {"-Xlog:cds", "-XX:+VerifySharedSpaces", "-cp", jarFile, "Hello"}; @@ -157,7 +163,7 @@ public class SharedArchiveConsistency { } // modify _magic, test should fail - System.out.println("\n2c. Corrupt _magic, should fail\n"); + System.out.println("\n2b. Corrupt _magic, should fail\n"); String modMagic = startNewArchive("modify-magic"); copiedJsa = CDSArchiveUtils.copyArchiveFile(orgJsaFile, modMagic); CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetMagic(), -1); @@ -169,12 +175,24 @@ public class SharedArchiveConsistency { } // modify _version, test should fail - System.out.println("\n2d. Corrupt _version, should fail\n"); + System.out.println("\n2c. Corrupt _version, should fail\n"); String modVersion = startNewArchive("modify-version"); + int version = currentCDSArchiveVersion + 1; copiedJsa = CDSArchiveUtils.copyArchiveFile(orgJsaFile, modVersion); - CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetVersion(), 0x00000000); + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetVersion(), version); + output = shareAuto ? TestCommon.execAuto(execArgs) : TestCommon.execCommon(execArgs); + output.shouldContain("The shared archive file version " + version + " does not match the required version " + currentCDSArchiveVersion); + if (shareAuto) { + output.shouldContain(HELLO_WORLD); + } + + System.out.println("\n2d. Corrupt _version, should fail\n"); + String modVersion2 = startNewArchive("modify-version2"); + copiedJsa = CDSArchiveUtils.copyArchiveFile(orgJsaFile, modVersion2); + version = genericHeaderMinVersion - 1; + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetVersion(), version); output = shareAuto ? TestCommon.execAuto(execArgs) : TestCommon.execCommon(execArgs); - output.shouldContain("The shared archive file has the wrong version"); + output.shouldContain("Cannot handle shared archive file version " + version + ". Must be at least " + genericHeaderMinVersion); output.shouldNotContain("Checksum verification failed"); if (shareAuto) { output.shouldContain(HELLO_WORLD); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestDumpClassListSource.java b/test/hotspot/jtreg/runtime/cds/appcds/TestDumpClassListSource.java new file mode 100644 index 0000000000000000000000000000000000000000..647e44bc455760eece80dbb057c61ff27555e823 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/TestDumpClassListSource.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 + * @key randomness + * @summary test dynamic dump meanwhile output loaded class list + * @bug 8279009 8275084 + * @requires vm.cds + * @requires vm.cds.custom.loaders + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @compile test-classes/Hello.java ClassSpecializerTestApp.java ClassListWithCustomClassNoSource.java + * @run main/othervm TestDumpClassListSource + */ + +/* Test two senarios: + * 1. ClassSpecializerTestApp.java: + * Test case for bug 8275084, make sure the filtering of source class to + * dumped class list. + * 2. ClassListWithCustomClassNoSource: test custom class loader + * 2.1 class loaded without source. + * 2.2 class loaded with ProtectionDomain set as same as main class. + * 2.3 class loaded by custom loader from shared space. + */ + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.File; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.cds.CDSTestUtils; + +public class TestDumpClassListSource { + private static final boolean EXPECT_MATCH = true; + private static final boolean EXPECT_NOMATCH = !EXPECT_MATCH; + + private static void checkMatch(String file, String regexp, boolean expectMatch, String exceptionMessage) throws Exception { + String listData = new String(Files.readAllBytes(Paths.get(file))); + Pattern pattern = Pattern.compile(regexp, Pattern.MULTILINE); + Matcher matcher = pattern.matcher(listData); + boolean found = matcher.find(); + if (expectMatch) { + if (!found) { + throw new RuntimeException(exceptionMessage); + } + } else { + if (found) { + throw new RuntimeException(exceptionMessage); + } + } + } + + static final String mainInvokeClass = "ClassSpecializerTestApp"; + static final String mainCutomClass = "ClassListWithCustomClassNoSource"; + static final String sourceTarget = "_ClassSpecializer_generateConcreteSpeciesCode"; + + private static void checkFileExistence(String type, File file) throws Exception { + if (!file.exists()) { + throw new RuntimeException(type + " file " + file.getName() + " should be created"); + } + } + + public static void main(String[] args) throws Exception { + String listFileName = "test-classlist.list"; + String archiveName = "test-dynamic.jsa"; + String jarFile = JarBuilder.build("test-hello", "ClassSpecializerTestApp", "ClassListWithCustomClassNoSource", + "ClassListWithCustomClassNoSource$CL", "Hello"); + // 1. Invoke lambda + File fileList = new File(listFileName); + if (fileList.exists()) { + fileList.delete(); + } + File fileArchive = new File(archiveName); + if (fileArchive.exists()) { + fileArchive.delete(); + } + String[] launchArgs = { + "-Xshare:auto", + "-XX:DumpLoadedClassList=" + listFileName, + "-XX:ArchiveClassesAtExit=" + archiveName, + "-Xlog:cds", + "-Xlog:cds+lambda", + "-cp", + jarFile, + mainInvokeClass}; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(launchArgs); + OutputAnalyzer output = TestCommon.executeAndLog(pb, "invoke-class"); + + checkFileExistence("Archive", fileArchive); + checkFileExistence("ClassList", fileList); + + output.shouldHaveExitValue(0); + checkMatch(listFileName, sourceTarget, EXPECT_NOMATCH, "Failed to filter " + sourceTarget + " in class list file"); + + fileArchive.delete(); + fileList.delete(); + + // 2. Custom loaded class + // 2.1 test in memory class generation without source + launchArgs = new String[] { + "-Xshare:auto", + "-XX:DumpLoadedClassList=" + listFileName, + "-XX:ArchiveClassesAtExit=" + archiveName, + "-Xlog:cds", + "-Xlog:cds+lambda", + "-Xlog:class+path=info", + "-cp", + jarFile, + mainCutomClass, + "1"}; + pb = ProcessTools.createJavaProcessBuilder(launchArgs); + output = TestCommon.executeAndLog(pb, "custom-nosource"); + + checkFileExistence("Archive", fileArchive); + checkFileExistence("ClassList", fileList); + + output.shouldHaveExitValue(0); + checkMatch(listFileName, sourceTarget, EXPECT_NOMATCH, "Failed to filter " + sourceTarget + " in class list file"); + checkMatch(listFileName, "Hello", EXPECT_NOMATCH, "Hello should not be logged in class list file"); + + fileArchive.delete(); + fileList.delete(); + + // 2.2 test in memory class with ProtectionDomain as main class. + // "Hello" will be printed in list file and its source set as main class. + launchArgs = new String[] { + "-Xshare:auto", + "-XX:DumpLoadedClassList=" + listFileName, + "-XX:ArchiveClassesAtExit=" + archiveName, + "-Xlog:cds", + "-Xlog:cds+lambda", + "-Xlog:class+path=info", + "-cp", + jarFile, + mainCutomClass, + "2"}; + pb = ProcessTools.createJavaProcessBuilder(launchArgs); + output = TestCommon.executeAndLog(pb, "custom-nosource"); + + checkFileExistence("Archive", fileArchive); + checkFileExistence("ClassList", fileList); + + output.shouldHaveExitValue(0); + checkMatch(listFileName, sourceTarget, EXPECT_NOMATCH, "Failed to filter " + sourceTarget + " in class list file"); + checkMatch(listFileName, "Hello", EXPECT_MATCH, "Hello should be logged in class list file"); + + fileArchive.delete(); + fileList.delete(); + + // 2.3 class loaded by custom loader from shared space. + // 2.3.1 dump class list + launchArgs = new String[] { + "-XX:DumpLoadedClassList=" + listFileName, + "-cp", + jarFile, + mainCutomClass, + "3"}; + pb = ProcessTools.createJavaProcessBuilder(launchArgs); + output = TestCommon.executeAndLog(pb, "custom-dump-classlist"); + + checkFileExistence("ClassList", fileList); + + checkMatch(listFileName, "Hello id: [0-9]+ super: [0-9]+ source: .*/test-hello.jar", EXPECT_MATCH, + "Class Hello should be printed in classlist"); + // 2.3.2 dump shared archive based on listFileName + String archive = "test-hello.jsa"; + File archiveFile = new File(archive); + if (archiveFile.exists()) { + archiveFile.delete(); + } + launchArgs = new String[] { + "-Xshare:dump", + "-XX:SharedClassListFile=" + listFileName, + "-XX:SharedArchiveFile=" + archive, + "-cp", + jarFile, + mainCutomClass, + "3"}; + pb = ProcessTools.createJavaProcessBuilder(launchArgs); + output = TestCommon.executeAndLog(pb, "custom-dump"); + + checkFileExistence("Archive", archiveFile); + + // 2.3.3 run with the shared archive and -XX:DumpLoadedClassList + // Hello should not be printed out in class list file. + String classList = "new-test-list.list"; + File newFile = new File(classList); + if (newFile.exists()) { + newFile.delete(); + } + launchArgs = new String[] { + "-Xshare:on", + "-XX:SharedArchiveFile=" + archive, + "-XX:DumpLoadedClassList=" + classList, + "-cp", + jarFile, + mainCutomClass, + "3"}; + pb = ProcessTools.createJavaProcessBuilder(launchArgs); + output = TestCommon.executeAndLog(pb, "custom-share"); + + checkFileExistence("ClassList", newFile); + checkMatch(classList, "Hello id: ?", EXPECT_NOMATCH, "Failed to filter custom loaded class Hello from class list"); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/DifferentHeapSizes.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/DifferentHeapSizes.java index 4afbb705c881bae6fc3462c6312d9f6f2037e675..fa9482abebd27b7d31fd3c609f6cfa1bc4d40cbf 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/DifferentHeapSizes.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/DifferentHeapSizes.java @@ -62,6 +62,8 @@ public class DifferentHeapSizes { JarBuilder.getOrCreateHelloJar(); String appJar = TestCommon.getTestJar("hello.jar"); String appClasses[] = TestCommon.list("Hello"); + WhiteBox wb = WhiteBox.getWhiteBox(); + boolean useCompressedOops = wb.getBooleanVMFlag("UseCompressedOops"); for (Scenario s : scenarios) { String dumpXmx = "-Xmx" + s.dumpSize + "m"; @@ -71,7 +73,7 @@ public class DifferentHeapSizes { String runXmx = "-Xmx" + runSize + "m"; CDSTestUtils.Result result = TestCommon.run("-cp", appJar, "-showversion", "-Xlog:cds", runXmx, DEDUP, "Hello"); - if (runSize < 32768) { + if (runSize < 32768 || !useCompressedOops) { result .assertNormalExit("Hello World") .assertNormalExit(out -> { @@ -88,7 +90,7 @@ public class DifferentHeapSizes { // Test various settings of -XX:HeapBaseMinAddress that would trigger // "CDS heap data need to be relocated because the desired range ... is outside of the heap" - long default_base = WhiteBox.getWhiteBox().getSizeTVMFlag("HeapBaseMinAddress").longValue(); + long default_base = wb.getSizeTVMFlag("HeapBaseMinAddress").longValue(); long M = 1024 * 1024; long bases[] = new long[] { /* dump xmx */ /* run xmx */ /* dump base */ /* run base */ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/HelloUnload.java b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/HelloUnload.java index 0a6be28b10d7f9e58c44dd87ab0edc3376279314..5df55982f145141b9b2694740f2e7d4750e16e2c 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/HelloUnload.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/HelloUnload.java @@ -30,10 +30,12 @@ import jdk.test.lib.classloader.ClassUnloadCommon; public class HelloUnload { private static String className = "CustomLoadee"; + // Prevent the following class from being GC'ed too soon. + private static Class keptC = null; public static void main(String args[]) throws Exception { - if (args.length != 3) { - throw new RuntimeException("Unexpected number of arguments: expected 3, actual " + args.length); + if (args.length < 3) { + throw new RuntimeException("Unexpected number of arguments: expected at least 3, actual " + args.length); } String path = args[0]; @@ -62,9 +64,20 @@ public class HelloUnload { throw new RuntimeException("args[2] can only be either \"true\" or \"false\", actual " + args[1]); } + // The HelloDynamicCustom.java and PrintSharedArchiveAndExit.java tests + // under appcds/dynamicArchive pass the keep-alive argument for preventing + // the class from being GC'ed prior to dumping of the dynamic CDS archive. + boolean keepAlive = false; + if (args[args.length - 1].equals("keep-alive")) { + keepAlive = true; + } + URLClassLoader urlClassLoader = new URLClassLoader("HelloClassLoader", urls, null); Class c = Class.forName(className, true, urlClassLoader); + if (keepAlive) { + keptC = c; + } System.out.println(c); System.out.println(c.getClassLoader()); Object o = c.newInstance(); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/OldClassApp.java b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/OldClassApp.java index a484018c90289d438fee19573d3dcf2c4d5fb100..51e21e1e82583f1df2aea13e7ff4ad22a58958fc 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/OldClassApp.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/OldClassApp.java @@ -25,9 +25,12 @@ import java.io.File; import java.net.URL; import java.net.URLClassLoader; +import java.util.HashMap; import sun.hotspot.WhiteBox; public class OldClassApp { + // Prevent the classes from being GC'ed too soon. + static HashMap<String, Class> clsMap = new HashMap<>(); public static void main(String args[]) throws Exception { String path = args[0]; URL url = new File(path).toURI().toURL(); @@ -44,13 +47,26 @@ public class OldClassApp { throw new RuntimeException("args[1] can only be either \"true\" or \"false\", actual " + args[1]); } + // The OldClassAndInf.java test under appcds/dynamicArchive passes the keep-alive + // argument for preventing the classes from being GC'ed prior to dumping of + // the dynamic CDS archive. + int startIdx = 2; + boolean keepAlive = false; + if (args[2].equals("keep-alive")) { + keepAlive = true; + startIdx = 3; + } + URLClassLoader urlClassLoader = new URLClassLoader("OldClassAppClassLoader", urls, null); - for (int i = 2; i < args.length; i++) { + for (int i = startIdx; i < args.length; i++) { Class c = urlClassLoader.loadClass(args[i]); System.out.println(c); System.out.println(c.getClassLoader()); + if (keepAlive) { + clsMap.put(args[i], c); + } // [1] Check that class is defined by the correct loader if (c.getClassLoader() != urlClassLoader) { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java index de723e6a13d37a0411b3b3fcd359b45ce0f9c36c..33bfc2ef99ebc4e38edeadb2bb229f1ed7a2504d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java @@ -30,7 +30,8 @@ * @build Hello sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ArchiveConsistency + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ArchiveConsistency on + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ArchiveConsistency auto */ import java.io.File; @@ -40,8 +41,15 @@ import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.helpers.ClassFileInstaller; public class ArchiveConsistency extends DynamicArchiveTestBase { + private static final String HELLO_WORLD = "Hello World"; + private static boolean isAuto; public static void main(String[] args) throws Exception { + if (args.length != 1 || (!args[0].equals("on") && !args[0].equals("auto"))) { + throw new RuntimeException("Must have one arg either of \"on\" or \"auto\""); + } + isAuto = args[0].equals("auto"); + setAutoMode(isAuto); runTest(ArchiveConsistency::testCustomBase); } @@ -53,31 +61,39 @@ public class ArchiveConsistency extends DynamicArchiveTestBase { doTest(baseArchiveName, topArchiveName); } + static boolean VERIFY_CRC = false; + static void runTwo(String base, String top, - String jarName, String mainClassName, int exitValue, + String jarName, String mainClassName, int expectedExitValue, String ... checkMessages) throws Exception { CDSTestUtils.Result result = run2(base, top, "-Xlog:cds", "-Xlog:cds+dynamic=debug", - "-XX:+VerifySharedSpaces", + VERIFY_CRC ? "-XX:+VerifySharedSpaces" : "-XX:-VerifySharedSpaces", "-cp", jarName, mainClassName); - if (exitValue == 0) { + if (expectedExitValue == 0) { result.assertNormalExit( output -> { for (String s : checkMessages) { output.shouldContain(s); } + output.shouldContain(HELLO_WORLD); }); } else { result.assertAbnormalExit( output -> { for (String s : checkMessages) { output.shouldContain(s); } + output.shouldContain("Unable to use shared archive"); }); } } + private static void startTest(String str) { + System.out.println("\n" + str); + } + private static void doTest(String baseArchiveName, String topArchiveName) throws Exception { String appJar = ClassFileInstaller.getJarPath("hello.jar"); String mainClass = "Hello"; @@ -94,42 +110,36 @@ public class ArchiveConsistency extends DynamicArchiveTestBase { throw new IOException(jsa + " does not exist!"); } - // 1. Modify the CRC values in the header of the top archive. - System.out.println("\n1. Modify the CRC values in the header of the top archive"); + startTest("1. Modify the CRC values in the header of the top archive"); String modTop = getNewArchiveName("modTopRegionsCrc"); File copiedJsa = CDSArchiveUtils.copyArchiveFile(jsa, modTop); CDSArchiveUtils.modifyAllRegionsCrc(copiedJsa); + VERIFY_CRC = true; runTwo(baseArchiveName, modTop, - appJar, mainClass, 1, - new String[] {"Header checksum verification failed", - "Unable to use shared archive"}); + appJar, mainClass, isAuto ? 0 : 1, + "Header checksum verification failed"); + VERIFY_CRC = false; - // 2. Make header size larger than the archive size - System.out.println("\n2. Make header size larger than the archive size"); + startTest("2. Make header size larger than the archive size"); String largerHeaderSize = getNewArchiveName("largerHeaderSize"); copiedJsa = CDSArchiveUtils.copyArchiveFile(jsa, largerHeaderSize); CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetHeaderSize(), (int)copiedJsa.length() + 1024); runTwo(baseArchiveName, largerHeaderSize, - appJar, mainClass, 1, - new String[] {"_header_size should be equal to _base_archive_name_offset plus _base_archive_name_size", - "Unable to use shared archive"}); + appJar, mainClass, isAuto ? 0 : 1, + "Archive file header larger than archive file"); - // 3. Make base archive path offset beyond of header size - System.out.println("\n3. Make base archive path offset beyond of header size."); + startTest("3. Make base archive name offset beyond of header size."); String wrongBaseArchiveNameOffset = getNewArchiveName("wrongBaseArchiveNameOffset"); copiedJsa = CDSArchiveUtils.copyArchiveFile(jsa, wrongBaseArchiveNameOffset); int fileHeaderSize = (int)CDSArchiveUtils.fileHeaderSize(copiedJsa); int baseArchiveNameOffset = CDSArchiveUtils.baseArchiveNameOffset(copiedJsa); CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetBaseArchiveNameOffset(), baseArchiveNameOffset + 1024); runTwo(baseArchiveName, wrongBaseArchiveNameOffset, - appJar, mainClass, 1, - new String[] {"_header_size should be equal to _base_archive_name_offset plus _base_archive_name_size", - "The shared archive file has an incorrect header size", - "Unable to use shared archive"}); + appJar, mainClass, isAuto ? 0 : 1, + "Invalid base_archive_name offset/size (out of range)"); - // 4. Make base archive path offset points to middle of name size - System.out.println("\n4. Make base archive path offset points to middle of name size"); + startTest("4. Make base archive name offset points to middle of the base archive name"); String wrongBaseNameOffset = getNewArchiveName("wrongBaseNameOffset"); copiedJsa = CDSArchiveUtils.copyArchiveFile(jsa, wrongBaseNameOffset); int baseArchiveNameSize = CDSArchiveUtils.baseArchiveNameSize(copiedJsa); @@ -137,13 +147,10 @@ public class ArchiveConsistency extends DynamicArchiveTestBase { CDSArchiveUtils.modifyHeaderIntField(copiedJsa, baseArchiveNameOffset, baseArchiveNameOffset + baseArchiveNameSize/2); runTwo(baseArchiveName, wrongBaseNameOffset, - appJar, mainClass, 1, - new String[] {"An error has occurred while processing the shared archive file.", - "Header checksum verification failed", - "Unable to use shared archive"}); + appJar, mainClass, isAuto ? 0 : 1, + "Base archive name is damaged"); - // 5. Make base archive name not terminated with '\0' - System.out.println("\n5. Make base archive name not terminated with '\0'"); + startTest("5. Make base archive name not terminated with '\0'"); String wrongBaseName = getNewArchiveName("wrongBaseName"); copiedJsa = CDSArchiveUtils.copyArchiveFile(jsa, wrongBaseName); baseArchiveNameOffset = CDSArchiveUtils.baseArchiveNameOffset(copiedJsa); @@ -152,12 +159,10 @@ public class ArchiveConsistency extends DynamicArchiveTestBase { CDSArchiveUtils.writeData(copiedJsa, offset, new byte[] {(byte)'X'}); runTwo(baseArchiveName, wrongBaseName, - appJar, mainClass, 1, - new String[] {"Base archive name is damaged", - "Header checksum verification failed"}); + appJar, mainClass, isAuto ? 0 : 1, + "Base archive name is damaged"); - // 6. Modify base archive name to a file that doesn't exist. - System.out.println("\n6. Modify base archive name to a file that doesn't exist"); + startTest("6. Modify base archive name to a file that doesn't exist"); String wrongBaseName2 = getNewArchiveName("wrongBaseName2"); copiedJsa = CDSArchiveUtils.copyArchiveFile(jsa, wrongBaseName2); baseArchiveNameOffset = CDSArchiveUtils.baseArchiveNameOffset(copiedJsa); @@ -170,8 +175,32 @@ public class ArchiveConsistency extends DynamicArchiveTestBase { (new File(badName)).delete(); runTwo(baseArchiveName, wrongBaseName2, - appJar, mainClass, 1, - new String[] {"Base archive " + badName + " does not exist", - "Header checksum verification failed"}); + appJar, mainClass, isAuto ? 0 : 1, + "Base archive " + badName + " does not exist"); + + // Following three tests: + // -XX:SharedArchiveFile=non-exist-base.jsa:top.jsa + // -XX:SharedArchiveFile=base.jsa:non-exist-top.jsa + // -XX:SharedArchiveFile=non-exist-base.jsa:non-exist-top.jsa + startTest("7. Non-exist base archive"); + String nonExistBase = "non-exist-base.jsa"; + File nonExistBaseFile = new File(nonExistBase); + nonExistBaseFile.delete(); + runTwo(nonExistBase, topArchiveName, + appJar, mainClass, isAuto ? 0 : 1, + "Specified shared archive not found (" + nonExistBase + ")"); + + startTest("8. Non-exist top archive"); + String nonExistTop = "non-exist-top.jsa"; + File nonExistTopFile = new File(nonExistTop); + nonExistTopFile.delete(); + runTwo(baseArchiveName, nonExistTop, + appJar, mainClass, isAuto ? 0 : 1, + "Specified shared archive not found (" + nonExistTop + ")"); + + startTest("9. nost-exist-base and non-exist-top"); + runTwo(nonExistBase, nonExistTop, + appJar, mainClass, isAuto ? 0 : 1, + "Specified shared archive not found (" + nonExistBase + ")"); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DumpToDefaultArchive.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DumpToDefaultArchive.java new file mode 100644 index 0000000000000000000000000000000000000000..88692d1f26a487c4181212a0e87b6c89f866cf68 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DumpToDefaultArchive.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277100 + * @summary VM should exit with an error message if the specified dynamic archive + * is the same as the default CDS archive. + * @requires vm.cds + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DumpToDefaultArchive + */ + +import jdk.test.lib.helpers.ClassFileInstaller; +import sun.hotspot.WhiteBox; + +public class DumpToDefaultArchive extends DynamicArchiveTestBase { + + public static void main(String[] args) throws Exception { + runTest(DumpToDefaultArchive::doTest); + } + + private static void doTest() throws Exception { + WhiteBox wb = WhiteBox.getWhiteBox(); + String topArchiveName = wb.getDefaultArchivePath(); + + dump(topArchiveName, + "-Xlog:cds", + "-version") + .assertAbnormalExit(output -> { + output.shouldContain("Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit: " + + topArchiveName); + }); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java index b61894c1b4bad2a422c67d38f6220b446e467fe8..6cbfec37175116a681ed0c8deb0b108822aff694 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicArchiveTestBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,8 +36,9 @@ import sun.hotspot.WhiteBox; */ class DynamicArchiveTestBase { private static boolean executedIn_run = false; - + private static boolean autoMode = false; // -Xshare:auto private static final WhiteBox WB = WhiteBox.getWhiteBox(); + private static String[] baseArchiveOptions = new String[] {}; public static interface DynamicArchiveTest { public void run() throws Exception; @@ -47,6 +48,7 @@ class DynamicArchiveTestBase { public void run(String args[]) throws Exception; } + public static void setAutoMode(boolean val) { autoMode = val; } /* * Tests for dynamic archives should be written using this pattern: @@ -94,6 +96,23 @@ class DynamicArchiveTestBase { return TestCommon.getNewArchiveName(stem); } + public static void setBaseArchiveOptions(String... opts) { + baseArchiveOptions = opts; + } + + /** + * Excute a JVM to dump a base archive by + * -Xshare:dump -XX:SharedArchiveFile=baseArchiveName + */ + public static Result dumpBaseArchive(String baseArchiveName, String... cmdLineSuffix) + throws Exception + { + OutputAnalyzer output = TestCommon.dumpBaseArchive(baseArchiveName, cmdLineSuffix); + CDSOptions opts = new CDSOptions(); + opts.setXShareMode("dump"); + return new Result(opts, output); + } + /** * Execute a JVM using the base archive (given by baseArchiveName) with the command line * (given by cmdLineSuffix). At JVM exit, dump all eligible classes into the top archive @@ -183,7 +202,7 @@ class DynamicArchiveTestBase { (topArchiveName == null) ? baseArchiveName : baseArchiveName + File.pathSeparator + topArchiveName; String[] cmdLine = TestCommon.concat( - "-Xshare:on", + autoMode ? "-Xshare:auto" : "-Xshare:on", "-XX:SharedArchiveFile=" + archiveFiles); cmdLine = TestCommon.concat(cmdLine, cmdLineSuffix); return execProcess("exec", null, cmdLine); @@ -202,7 +221,7 @@ class DynamicArchiveTestBase { (topArchiveName == null) ? baseArchiveName : baseArchiveName + File.pathSeparator + topArchiveName; String[] cmdLine = TestCommon.concat( - "-Xshare:on", + autoMode ? "-Xshare:auto" : "-Xshare:on", "-XX:SharedArchiveFile=" + archiveFiles); cmdLine = TestCommon.concat(cmdLine, cmdLineSuffix); return execProcess("exec", jarDir, cmdLine); @@ -272,16 +291,16 @@ class DynamicArchiveTestBase { private static String getTempBaseArchive() throws Exception { if (tempBaseArchive == null) { tempBaseArchive = getNewArchiveName("tempBaseArchive"); - TestCommon.dumpBaseArchive(tempBaseArchive); + TestCommon.dumpBaseArchive(tempBaseArchive, baseArchiveOptions); } return tempBaseArchive; } /** - * Return true if the UseSharedSpaces flag has been disabled. + * Return true if sharing has been disabled. * By default, the VM will be started with -Xshare:auto. - * The UseSharedSpaces flag will be disabled by the VM if there's some - * problem in using the default CDS archive. It could happen under some + * Sharing will be disabled by the VM if there's some problem + * in using the default CDS archive. It could happen under some * situations such as follows: * - the default CDS archive wasn't generated during build time because * the JDK was built via cross-compilation on a different platform; @@ -292,6 +311,6 @@ class DynamicArchiveTestBase { * enabled when the default CDS archive was built. */ public static boolean isUseSharedSpacesDisabled() { - return (WB.getBooleanVMFlag("UseSharedSpaces") == false); + return !WB.isSharingEnabled(); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustom.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustom.java index 2c2c745027cd5c2993e6549cacc5bcb53be075e1..097162a17c14697645662085f999a3d03e17d9b9 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustom.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamicCustom.java @@ -64,7 +64,7 @@ public class HelloDynamicCustom extends DynamicArchiveTestBase { "-Xlog:cds", "-Xlog:cds+dynamic=debug", "-cp", appJar, - mainAppClass, customJarPath, "false", "false") + mainAppClass, customJarPath, "false", "false", "keep-alive") .assertNormalExit(output -> { output.shouldContain("Written dynamic archive 0x") .shouldNotContain("klasses.*=.*CustomLoadee") diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaCustomLoader.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaCustomLoader.java index dc2c9f144d77379f1157fa38d6801a8191196ca1..df3122056e2299f48cfa98f2dfc1f9abb1510dec 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaCustomLoader.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaCustomLoader.java @@ -49,7 +49,7 @@ public class LambdaCustomLoader extends DynamicArchiveTestBase { // 1. Host class loaded by a custom loader is initialized during dump time. dump(topArchiveName, "-Xlog:class+load,cds=debug,cds+dynamic", - "-cp", appJar, mainClass, appJar, "init") + "-cp", appJar, mainClass, appJar, "init", "keep-alive") .assertNormalExit(output -> { output.shouldMatch("Skipping.LambHello[$][$]Lambda[$].*0x.*:.Hidden.class") .shouldHaveExitValue(0); @@ -67,7 +67,7 @@ public class LambdaCustomLoader extends DynamicArchiveTestBase { // 2. Host class loaded by a custom loader is NOT initialized during dump time. dump(topArchiveName, "-Xlog:class+load,cds=debug,cds+dynamic", - "-cp", appJar, mainClass, appJar) + "-cp", appJar, mainClass, appJar, "keep-alive") .assertNormalExit(output -> { output.shouldHaveExitValue(0); }); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LotsUnloadTest.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LotsUnloadTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7cde5683c22ef7b38103189294ed9ad9f82bc9a7 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LotsUnloadTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8278602 + * @summary Lots of classes being unloaded while we try to dump a dynamic archive + * @requires vm.cds + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes + * @build sun.hotspot.WhiteBox + * @build LotsUnloadApp + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar LotsUnloadApp.jar LotsUnloadApp DefinedAsHiddenKlass + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. LotsUnloadTest + */ + +// Note: for https://bugs.openjdk.java.net/browse/JDK-8278602, this test case does NOT +// reliably reproduce the problem. Reproduction requires patching ZGC. Please see +// the bug report for instructions. +// +// This test case is included so that it may find a similar bug under stress conditions +// in the CI runs. +import jdk.test.lib.helpers.ClassFileInstaller; + +public class LotsUnloadTest extends DynamicArchiveTestBase { + public static void main(String[] args) throws Exception { + runTest(LotsUnloadTest::test); + } + + static void test() throws Exception { + String topArchiveName = getNewArchiveName(); + String appJar = ClassFileInstaller.getJarPath("LotsUnloadApp.jar"); + String mainClass = "LotsUnloadApp"; + String logging; + + if (Boolean.getBoolean("verbose.LotsUnloadTest")) { + // class+unload logs may change GC timing and cause the bug to be + // less reproducible. + logging = "-Xlog:cds,class+unload"; + } else { + logging = "-Xlog:cds"; + } + + dump(topArchiveName, + logging, + "-Xmx64m", "-Xms32m", + "-cp", appJar, mainClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0); + }); + + run(topArchiveName, + logging, + "-Xmx64m", "-Xms32m", + "-cp", appJar, mainClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0); + }); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/OldClassAndInf.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/OldClassAndInf.java index 44b430eef6ab12e63f206541e57992e7035b883d..4508eefd82924e1c7adeb918e7600878ef775e55 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/OldClassAndInf.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/OldClassAndInf.java @@ -80,7 +80,7 @@ public class OldClassAndInf extends DynamicArchiveTestBase { "-Xlog:cds", "-Xlog:cds+dynamic=debug", "-cp", appJar, - mainAppClass, loadeesJar, inArchive), + mainAppClass, loadeesJar, inArchive, "keep-alive"), loadees)) .assertNormalExit(output -> { output.shouldContain("Written dynamic archive 0x") diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/PrintSharedArchiveAndExit.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/PrintSharedArchiveAndExit.java index 342aceff9372b9afa3357d8251613262e8b9f7fc..9ceb51c74b602db1aa3452e64ba147042b5f4c73 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/PrintSharedArchiveAndExit.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/PrintSharedArchiveAndExit.java @@ -64,7 +64,7 @@ public class PrintSharedArchiveAndExit extends DynamicArchiveTestBase { "-Xlog:cds", "-Xlog:cds+dynamic=debug", "-cp", appJar, - mainAppClass, customJarPath, "false", "false") + mainAppClass, customJarPath, "false", "false", "keep-alive") .assertNormalExit(output -> { output.shouldContain("Written dynamic archive 0x") .shouldNotContain("klasses.*=.*CustomLoadee") diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java index 3729813e8fac011c17976bf5487d4954f2e57947..17c496bc14d6f6ef46cd89aee4de93df24b61d99 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java @@ -54,7 +54,7 @@ public class RegularHiddenClass extends DynamicArchiveTestBase { dump(topArchiveName, "-Xlog:class+load=debug,cds+dynamic,cds=debug", - "-cp", appJar, mainClass) + "-cp", appJar, mainClass, "keep-alive") .assertNormalExit(output -> { output.shouldMatch("cds.*Skipping.TestClass.0x.*Hidden.class") .shouldNotMatch("cds.dynamic.*Archiving.hidden.TestClass.*") diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchive.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchive.java new file mode 100644 index 0000000000000000000000000000000000000000..e06a4c98c3789d6914c0ac68173a8023f4792ac7 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchive.java @@ -0,0 +1,697 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8261455 + * @summary test -XX:+AutoCreateSharedArchive feature + * @requires vm.cds + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @build Hello + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar TestAutoCreateSharedArchive verifySharedSpacesOff + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar TestAutoCreateSharedArchive verifySharedSpacesOn + */ + +/* + * -XX:SharedArchiveFile can be specified in two styles: + * + * (A) Test with default base archive -XX:+SharedArchiveFile=<archive> + * (B) Test with the base archive specified: -XX:SharedArchiveFile=<base>:<top> + * all the following if not explained explicitly, run with flag -XX:+AutoCreateSharedArchive + * + * Note VerifySharedSpaces will affect output so the tests run twice: one with -XX:+VerifySharedSpaces and the other with -XX:-VerifySharedSpaces + * + * 10 Case (A) + * + * 10.01 run with non-existing archive should automatically create dynamic archive. + * If the JDK's default CDS archive cannot be loaded, print out warning, run continue without shared archive and no shared archive created at exit. + * 10.02 run with the created dynamic archive should pass. + * 10.03 run with the created dynamic archive and -XX:+AutoCreateSharedArchive should pass and no shared archive created at exit. + * + * 11 run with static archive. + * run with static archive should printout warning and continue, share or no share depends on the archive validation at exit, + * no shared archive (top) will be generated. + * + * 12 run with damaged magic should not regenerate dynamic archive. + * if magic is not expected, no shared archive will be regenerated at exit. + * + * 13 run with a bad versioned archive. + * 13.01 run with a bad versioned (< CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION) archive should not create dynamic archive at exit. + * 13.02 run with a bad versioned (> CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION) archive should create dynamic archive at exit. + * + * 14 run with an archive whose base name is not matched, no shared archive at exit. + * + * 15 run with an archive whose jvm_ident is corrupted should + * create dynamic archive at exit with -XX:-VerifySharedSpaces + * not create dynamic archive at exit with -XX:+VerifySharedSpaces + * + * 16 run with an archive only containing magic in the file (size of 4 bytes) + * the archive will be created at exit. + * + * 20 (case B) + * + * 20.01 dump base archive which will be used for dumping top archive. + * 20.02 dump top archive based on base archive obtained in 20.1. + * 20.03 run -XX:SharedArchiveFile=<base>:<top> to verify the archives. + * 20.04 run with -XX:SharedArchveFile=base:top (reversed) + * + * 21 Mismatched versions + * 21.01 if version of top archive is higher than CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION, the archive cannot be shared and will be + * regenerated at exit. + * 21.02 if version of top archive is lower than CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION, the archive cannot be shared and will be + * created at exit. + * + * 22 create an archive with dynamic magic number only + * archive will be created at exit if base can be shared. + * + * 23 mismatched jvm_indent in base/top archive + * 23.01 mismatched jvm_indent in top archive + * 23.02 mismatched jvm_indent in base archive + * + * 24 run with non-existing shared archives + * 24.01 run -Xshare:auto -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=base.jsa:non-exist-top.jsa + * The top archive will be regenerated. + * 24.02 run -Xshare:auto -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=non-exist-base.jsa:top.jsa + * top archive will not be shared if base archive failed to load. + */ + +import java.io.IOException; +import java.io.File; +import java.nio.file.attribute.FileTime; +import java.nio.file.Files; +import java.nio.file.Paths; + +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.cds.CDSArchiveUtils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.helpers.ClassFileInstaller; + +import jtreg.SkippedException; + +public class TestAutoCreateSharedArchive extends DynamicArchiveTestBase { + private static final String BASE_NAME = CDSTestUtils.getOutputFileName("base.jsa"); + private static final String TOP_NAME = CDSTestUtils.getOutputFileName("top.jsa"); + private static final String mainAppClass = "Hello"; + private static final String HELLO_SOURCE = "Hello source: shared objects file (top)"; + private static final String HELLO_WORLD = "Hello World"; + private static boolean verifyOn = false; + + private static int genericHeaderMinVersion = CDSArchiveUtils.getGenericHeaderMinVersion(); + private static int currentCDSVersion = CDSArchiveUtils.getCurrentCDSArchiveVersion(); + + public static void main(String[] args) throws Exception { + if (isUseSharedSpacesDisabled()) { + throw new SkippedException("Skipped -- This test is not applicable when JTREG tests are executed with -Xshare:off, or if the JDK doesn't have a default archive."); + } + if (args.length != 1 || (!args[0].equals("verifySharedSpacesOff") && !args[0].equals("verifySharedSpacesOn"))) { + throw new RuntimeException("Must run with verifySharedSpacesOff or verifySharedSpacesOn"); + } + verifyOn = args[0].equals("verifySharedSpacesOn"); + runTest(TestAutoCreateSharedArchive::testAutoCreateSharedArchive); + } + + public static void checkFileExists(String fileName) throws Exception { + File file = new File(fileName); + if (!file.exists()) { + throw new IOException("Archive " + fileName + " is not automatically created"); + } + } + + public static String startNewArchive(String testName) { + String newArchiveName = TestCommon.getNewArchiveName(testName); + TestCommon.setCurrentArchiveName(newArchiveName); + return newArchiveName; + } + + public static void print(String message) { + System.out.println(message); + } + + private static void testAutoCreateSharedArchive() throws Exception { + String appJar = ClassFileInstaller.getJarPath("hello.jar"); + boolean fileModified = false; + + String verifySharedSpaces = verifyOn ? "-XX:+VerifySharedSpaces" : "-XX:-VerifySharedSpaces"; + File archiveFile = new File(TOP_NAME); + if (archiveFile.exists()) { + archiveFile.delete(); + } + + // dump a static archive, used later. + // 0. Dump a static archive + print("0. dump a static archive " + BASE_NAME); + dumpBaseArchive(BASE_NAME, + "-Xlog:cds", + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0); + }); + checkFileExists(BASE_NAME); + + // The list numbers try to match JDK-8272331 (CSR for JDK-8261455) test items but not exactly matched. + + // 10 non-existing archive should automatically create dynamic archive based on default shared archive + // if base archive loaded. + print("10 Test with default base shared archive"); + print(" 10.01 run with non-existing archive should automatically create dynamic archive"); + File fileTop = new File(TOP_NAME); + if (fileTop.exists()) { + fileTop.delete(); + } + run(TOP_NAME, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldContain("Dumping shared data to file:") + .shouldContain(TOP_NAME); + }); + checkFileExists(TOP_NAME); + + //10.02 run with the created dynamic archive should pass + print(" 10.02 run with the created dynamic archive should pass"); + run(TOP_NAME, + "-Xlog:cds", + "-Xlog:class+load", + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldContain(HELLO_SOURCE); + }); + // remember the FileTime + FileTime ft1 = Files.getLastModifiedTime(Paths.get(TOP_NAME)); + + // 10.03 run with the created dynamic archive with -XX:+AutoCreateSharedArchive should pass + // archive should not be created again. + print(" 10.03 run with the created dynamic archive with -XX:+AutoCreateSharedArchive should pass"); + run(TOP_NAME, + "-Xlog:cds", + "-Xlog:class+load", + "-Xlog:cds+dynamic=info", + "-XX:+AutoCreateSharedArchive", + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldContain(HELLO_SOURCE) + .shouldNotContain("Dumping shared data to file"); + }); + FileTime ft2 = Files.getLastModifiedTime(Paths.get(TOP_NAME)); + fileModified = !ft2.equals(ft1); + if (fileModified) { + throw new RuntimeException("Archive file " + TOP_NAME + " should not be updated"); + } + + // 11 run with static archive + print("11 run with static archive"); + ft1 = Files.getLastModifiedTime(Paths.get(BASE_NAME)); + run(BASE_NAME, + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldContain("AutoCreateSharedArchive is ignored because " + BASE_NAME + " is a static archive") + .shouldNotContain("Dumping shared data to file"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(BASE_NAME)); + fileModified = !ft1.equals(ft2); + if (fileModified) { + throw new RuntimeException("Run -XX:+AutoCreateSharedArchive on static archive create new archive"); + } + + // 12 run with damaged magic should not regenerate dynamic archive + print("12 run with damaged magic should not regenerate dynamic archive"); + String modMagic = startNewArchive("modify-magic"); + File copiedJsa = CDSArchiveUtils.copyArchiveFile(archiveFile, modMagic); + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetMagic(), 0x1234); + ft1 = Files.getLastModifiedTime(Paths.get(modMagic)); + + run(modMagic, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldNotContain("Dumping shared data to file"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(modMagic)); + fileModified = !ft1.equals(ft2); + if (fileModified) { + throw new RuntimeException("Shared archive " + modMagic + " should not automatically be generated"); + } + + // 13 run with a bad versioned (< genericHeaderMinVersion) archive + print("13 run with a bad versioned archive"); + print(" 13.01 run with a bad versioned (< genericHeaderMinVersion) archive should not create new archive"); + String modVersion = startNewArchive("modify-version-b"); + copiedJsa = CDSArchiveUtils.copyArchiveFile(archiveFile, modVersion); + final int version1 = genericHeaderMinVersion - 1; + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetVersion(), version1); + ft1 = Files.getLastModifiedTime(Paths.get(modVersion)); + + run(modVersion, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldContain("Cannot handle shared archive file version " + version1 + ". Must be at least " + genericHeaderMinVersion) + .shouldContain("Unable to use shared archive: invalid archive") + .shouldNotContain("Dumping shared data to file"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(modVersion)); + fileModified = !ft1.equals(ft2); + if (fileModified) { + throw new RuntimeException("Run -XX:+AutoCreateSharedArchive with lower version archive " + modVersion + " should not create new archive"); + } + // 13.02 run with a bad versioned (> currentCDSVersion) archive + print(" 13.02 run with a bad versioned (> currentCDSVersion) archive"); + modVersion = startNewArchive("modify-version-d"); + copiedJsa = CDSArchiveUtils.copyArchiveFile(archiveFile, modVersion); + final int version2 = currentCDSVersion + 1; + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetVersion(), version2); + ft1 = Files.getLastModifiedTime(Paths.get(modVersion)); + + run(modVersion, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldContain("The shared archive file version " + version2 + " does not match the required version " + currentCDSVersion) + .shouldContain("UseSharedSpaces: The shared archive file has the wrong version") + .shouldContain("UseSharedSpaces: Initialize dynamic archive failed") + .shouldContain("Dumping shared data to file"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(modVersion)); + fileModified = !ft1.equals(ft2); + if (!fileModified) { + throw new RuntimeException("Run -XX:+AutoCreateSharedArchive with higher version archive " + modVersion + " should create new archive"); + } + + // 14 run with an archive whose base name is not matched, no share + print("14 run with an archive whose base name is not matched, no share"); + String baseNameMismatch= startNewArchive("basename-mismatch"); + copiedJsa = CDSArchiveUtils.copyArchiveFile(archiveFile, baseNameMismatch); + int nameSize = CDSArchiveUtils.baseArchiveNameSize(copiedJsa); + int offset = CDSArchiveUtils.baseArchiveNameOffset(copiedJsa); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < nameSize - 4; i++) { + sb.append('Z'); + } + sb.append(".jsa"); + sb.append('\0'); + String newName = sb.toString(); + CDSArchiveUtils.writeData(copiedJsa, offset, newName.getBytes()); + + ft1 = Files.getLastModifiedTime(Paths.get(baseNameMismatch)); + run(baseNameMismatch, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldNotContain("Dumping shared data to file"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(baseNameMismatch)); + + fileModified = !ft1.equals(ft2); + if (fileModified) { + throw new RuntimeException("Shared archive " + baseNameMismatch+ " should not automatically be generated"); + } + + // 15 mismatched jvm_indent in archive, create (-VerifySharedSpaces) or not (-XX:+VerifySharedSpaces) create the new archive + print("15 mismatched jvm_indent in archive, " + (verifyOn ? "-XX:+VerifySharedSpaces not " : "-XX:-VerifySharedSpaces ") + "create new archive"); + String modJvmIdent = startNewArchive("modify-jvmident"); + copiedJsa = CDSArchiveUtils.copyArchiveFile(archiveFile, modJvmIdent); + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetJvmIdent(), 0x65656565); + ft1 = Files.getLastModifiedTime(Paths.get(modJvmIdent)); + + run(modJvmIdent, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0); + if (verifyOn) { + output.shouldContain("UseSharedSpaces: Header checksum verification failed") + .shouldContain("Unable to use shared archive: invalid archive") + .shouldNotContain("Dumping shared data to file"); + } else { + output.shouldContain(HELLO_WORLD) + .shouldContain("Dumping shared data to file"); + } + }); + ft2 = Files.getLastModifiedTime(Paths.get(modJvmIdent)); + fileModified = !ft1.equals(ft2); + if (verifyOn) { + if (fileModified) { + throw new RuntimeException("Shared archive " + modJvmIdent + " should not be generated"); + } + + } else { + if (!fileModified) { + throw new RuntimeException("Shared archive " + modJvmIdent + " should be generated"); + } + } + + // 16 run with an archive of only containing dynamic magic (size of 4) will not create new archive at exit + print("16 run with an archive of only containing dynamic magic (size of 4) will not create new archive at exit"); + String magicOnly = startNewArchive("magic-only"); + copiedJsa = CDSArchiveUtils.createMagicOnlyFile(magicOnly, false/*dynamic*/); + ft1 = Files.getLastModifiedTime(Paths.get(magicOnly)); + run(magicOnly, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldContain("Unable to read generic CDS file map header from shared archive") + .shouldNotContain("Dumping shared data to file:"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(magicOnly)); + fileModified = !ft1.equals(ft2); + if (fileModified) { + throw new RuntimeException("Shared archive " + magicOnly + " should not automatically be generated"); + } + + // Do some base tests for -XX:SharedArchiveFile=base:top, they should be same as default archive as base. + // delete top archive + if (archiveFile.exists()) { + archiveFile.delete(); + } + // delete base archive + File baseFile = new File(BASE_NAME); + if (baseFile.exists()) { + baseFile.delete(); + } + + // 20 Testing with -XX:SharedArchiveFile=base:top + print("20 Testing with -XX:SharedArchiveFile=base:top"); + // 20.01 dump base archive and top archive + print(" 20.01 dump base archive " + BASE_NAME); + dumpBaseArchive(BASE_NAME, "-Xlog:cds") + .assertNormalExit(output -> { + output.shouldHaveExitValue(0); + }); + checkFileExists(BASE_NAME); + + // 20.02 dump top based on base + print(" 20.02 dump top based on base"); + dump2(BASE_NAME, TOP_NAME, + "-Xlog:cds", + "-cp", appJar, mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain("Dumping shared data to file:") + .shouldContain(TOP_NAME); + }); + checkFileExists(TOP_NAME); + + // 20.03 run with -XX:SharedArchveFile=base:top + print(" 20.03 run with -XX:SharedArchveFile=base:top"); + run2(BASE_NAME, TOP_NAME, + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + "-Xlog:class+load", + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_SOURCE); + }); + + // 20.04 run with -XX:SharedArchveFile=top:base (reversed) + print(" 20.04 run with -XX:SharedArchveFile=top:base (reversed)"); + run2(TOP_NAME, BASE_NAME, + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + "-Xlog:class+load", + "-cp", appJar, + mainAppClass) + .assertAbnormalExit(output -> { + output.shouldHaveExitValue(1) + .shouldContain("Not a base shared archive: " + TOP_NAME) + .shouldContain("An error has occurred while processing the shared archive file") + .shouldNotContain(HELLO_WORLD); + }); + + // 21 Mismatched versions + print("21 Mismatched versions"); + // 21.01 top version is lower than CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION, regenerate top + print(" 21.01 top version is lower than CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION, regenerate top"); + String versionB = startNewArchive("modify-version-B"); + archiveFile = new File(TOP_NAME); + copiedJsa = CDSArchiveUtils.copyArchiveFile(archiveFile, versionB); + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetVersion(), version1); + ft1 = Files.getLastModifiedTime(Paths.get(versionB)); + + run2(BASE_NAME, versionB, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD) + .shouldContain("Cannot handle shared archive file version " + version1) + .shouldContain(versionB) + .shouldContain("Dumping shared data to file:"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(versionB)); + fileModified = !ft1.equals(ft2); + if (!fileModified) { + throw new RuntimeException("Shared archive " + versionB + " should automatically be generated"); + } + + // 21.02 top version is higher than CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION, no share for top, create archive at exit + print(" 21.02 top version is higher than CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION, no share for top, create archive at exit"); + String versionF = startNewArchive("versionF"); + copiedJsa = CDSArchiveUtils.copyArchiveFile(archiveFile, versionF); + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetVersion(), version2); + ft1 = Files.getLastModifiedTime(Paths.get(versionF)); + run2(BASE_NAME, versionF, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldContain("The shared archive file version " + version2 + " does not match the required version " + currentCDSVersion) + .shouldContain(HELLO_WORLD) + .shouldContain("Dumping shared data to file:"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(versionB)); + fileModified = !ft1.equals(ft2); + if (!fileModified) { + throw new RuntimeException("Shared archive " + versionB + " should be created at exit"); + } + + // 22 create an archive with dynamic magic number only + // archive will be created at exit if base can be shared. + print("22 create an archive with dynamic magic number only"); + copiedJsa = CDSArchiveUtils.createMagicOnlyFile(magicOnly, false /*dynamic*/); + ft1 = Files.getLastModifiedTime(Paths.get(magicOnly)); + run2(BASE_NAME, magicOnly, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldContain(HELLO_WORLD) + .shouldContain("Unable to read generic CDS file map header from shared archive") + .shouldContain("Dumping shared data to file:"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(magicOnly)); + fileModified = !ft1.equals(ft2); + if (!fileModified) { + throw new RuntimeException("Shared archive " + magicOnly + " should be created at exit"); + } + + // 23 mismatched jvm_indent in top or base archive + // 23.01 mismatched jvm_indent in top archive + print(" 23.01 mismatched jvm_indent in top archive"); + String modJvmIdentTop = startNewArchive("modify-jvmident-top"); + copiedJsa = CDSArchiveUtils.copyArchiveFile(archiveFile, modJvmIdentTop); + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetJvmIdent(), 0x65656565); + ft1 = Files.getLastModifiedTime(Paths.get(modJvmIdentTop)); + + run2(BASE_NAME, modJvmIdentTop, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0); + if (verifyOn) { + output.shouldContain("UseSharedSpaces: Header checksum verification failed"); + } + output.shouldContain(HELLO_WORLD) + .shouldContain("Dumping shared data to file"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(modJvmIdentTop)); + fileModified = !ft1.equals(ft2); + if (!fileModified) { + throw new RuntimeException("Shared archive " + modJvmIdentTop + " should be generated"); + } + // 23.02 mismatched jvm_indent in base archive + print(" 23.02 mismatched jvm_indent in base archive"); + String modJvmIdentBase = startNewArchive("modify-jvmident-base"); + copiedJsa = CDSArchiveUtils.copyArchiveFile(new File(BASE_NAME), modJvmIdentBase); + CDSArchiveUtils.modifyHeaderIntField(copiedJsa, CDSArchiveUtils.offsetJvmIdent(), 0x65656565); + ft1 = Files.getLastModifiedTime(Paths.get(TOP_NAME)); + + run2(modJvmIdentBase, TOP_NAME, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldHaveExitValue(0) + .shouldContain(HELLO_WORLD); + if (verifyOn) { + output.shouldContain("UseSharedSpaces: Header checksum verification failed"); + } + output.shouldContain("Unable to map shared spaces") + .shouldNotContain("Dumping shared data to file"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(TOP_NAME)); + fileModified = !ft1.equals(ft2); + if (fileModified) { + throw new RuntimeException("Shared archive " + TOP_NAME + " should not be generated"); + } + + // 24 run with non-existing shared archives + print("24 run with non-existing shared archives"); + // 24.01 run -Xshare:auto -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=base.jsa:non-exist-top.jsa + print(" 24.01 run -Xshare:auto -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=base.jsa:non-exist-top.jsa"); + String nonExistTop = "non-existing-top.jsa"; + File fileNonExist = new File(nonExistTop); + if (fileNonExist.exists()) { + fileNonExist.delete(); + } + run2(BASE_NAME, nonExistTop, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldContain("Specified shared archive not found (" + nonExistTop + ")") + .shouldContain(HELLO_WORLD) + .shouldContain("Dumping shared data to file:"); + }); + if (!fileNonExist.exists()) { + throw new RuntimeException("Shared archive " + nonExistTop + " should be created at exit"); + } + + // 24.02 run -Xshare:auto -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=non-exist-base.jsa:top.jsa + print(" 24.02 run -Xshare:auto -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=non-exist-base.jsa:top.jsa"); + String nonExistBase = "non-existing-base.jsa"; + fileNonExist = new File(nonExistBase); + if (fileNonExist.exists()) { + fileNonExist.delete(); + } + ft1 = Files.getLastModifiedTime(Paths.get(TOP_NAME)); + run2(nonExistBase, TOP_NAME, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-Xlog:cds", + "-Xlog:cds+dynamic=info", + verifySharedSpaces, + "-cp", appJar, + mainAppClass) + .assertNormalExit(output -> { + output.shouldContain("Specified shared archive not found (" + nonExistBase + ")") + .shouldContain(HELLO_WORLD) + .shouldNotContain("Dumping shared data to file:"); + }); + ft2 = Files.getLastModifiedTime(Paths.get(TOP_NAME)); + fileModified = !ft1.equals(ft2); + if (fileModified) { + throw new RuntimeException("Shared archive " + TOP_NAME + " should not be created at exit"); + } + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchiveNoDefaultArchive.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchiveNoDefaultArchive.java new file mode 100644 index 0000000000000000000000000000000000000000..d2db4a3b2ad76fabca96b92914a3eb9db4ef8962 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchiveNoDefaultArchive.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @summary Test -XX:+AutoCreateSharedArchive on a copied JDK without default shared archive + * @bug 8261455 + * @requires vm.cds + * @requires vm.flagless + * @comment This test doesn't work on Windows because it depends on symlinks + * @requires os.family != "windows" + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @compile ../test-classes/Hello.java + * @run driver TestAutoCreateSharedArchiveNoDefaultArchive + */ + +import java.io.File; +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestAutoCreateSharedArchiveNoDefaultArchive { + public static void main(String[] args) throws Exception { + String mainClass = "Hello"; + String java_home_src = System.getProperty("java.home"); + String java_home_dst = CDSTestUtils.getOutputDir() + File.separator + "moved_jdk"; + CDSTestUtils.clone(new File(java_home_src), new File(java_home_dst)); + System.out.println("======== Cloned JDK at " + java_home_dst); + + String homeJava = java_home_src + File.separator + "bin" + File.separator + "java"; + String dstJava = java_home_dst + File.separator + "bin" + File.separator + "java"; + + TestCommon.startNewArchiveName(); + String jsaFileName = TestCommon.getCurrentArchiveName(); + File jsaFile = new File(jsaFileName); + if (jsaFile.exists()) { + jsaFile.delete(); + } + + String jsaOpt = "-XX:SharedArchiveFile=" + jsaFileName; + String autoCreateArchive = "-XX:+AutoCreateSharedArchive"; + { + ProcessBuilder pb = CDSTestUtils.makeBuilder(homeJava, + "-Xshare:dump", + jsaOpt); + TestCommon.executeAndLog(pb, "dump") + .shouldHaveExitValue(0); + } + { + ProcessBuilder pb = CDSTestUtils.makeBuilder(homeJava, + "-Xshare:auto", + jsaOpt, + "-Xlog:class+path=info", + "-version"); + OutputAnalyzer out = TestCommon.executeAndLog(pb, "exec-src"); + out.shouldHaveExitValue(0); + out.shouldNotContain("shared class paths mismatch"); + out.shouldNotContain("BOOT classpath mismatch"); + } + + String helloJar = JarBuilder.getOrCreateHelloJar(); + + if (jsaFile.exists()) { + jsaFile.delete(); + } + // Test runtime with cloned JDK + System.out.println("======== run with cloned jdk to created dynamic shared archive at exit"); + { + ProcessBuilder pb = CDSTestUtils.makeBuilder(dstJava, + "-Xshare:auto", + autoCreateArchive, + jsaOpt, + "-Xlog:cds", + "-Xlog:class+path=info", + "-cp", helloJar, + mainClass); + OutputAnalyzer out = TestCommon.executeAndLog(pb, "exec-dst"); + out.shouldHaveExitValue(0); + out.shouldContain("Dumping shared data to file"); + if (!jsaFile.exists()) { + throw new RuntimeException("Shared archive " + jsaFileName + " should be created at exit"); + } + } + + // Now rename classes.jsa to old-classes.jsa + String dstDir = java_home_dst + File.separator + "lib" + File.separator + "server"; + CDSTestUtils.rename(new File(dstDir + File.separator + "classes.jsa"), + new File(dstDir + File.separator + "old-classes.jsa")); + System.out.println("======= renamed classes.jsa to old-classes.jsa"); + + { + ProcessBuilder pb = CDSTestUtils.makeBuilder(dstJava, + "-Xlog:cds", + "-version"); + TestCommon.executeAndLog(pb, "show-version") + .shouldHaveExitValue(0) + .shouldContain("UseSharedSpaces: Initialize static archive failed") + .shouldContain("UseSharedSpaces: Unable to map shared spaces") + .shouldContain("mixed mode") + .shouldNotContain("sharing"); + } + // delete existing jsa file + if (jsaFile.exists()) { + jsaFile.delete(); + } + System.out.println("======= run with no default shared archive should not create shared archive at exit"); + { + ProcessBuilder pb = CDSTestUtils.makeBuilder(dstJava, + "-Xshare:auto", + autoCreateArchive, + jsaOpt, + "-Xlog:cds", + "-Xlog:class+path=info", + "-cp", helloJar, + mainClass); + TestCommon.executeAndLog(pb, "no-default-archive") + .shouldHaveExitValue(0) + .shouldContain("UseSharedSpaces: Initialize static archive failed") + .shouldContain("UseSharedSpaces: Unable to map shared spaces") + .shouldNotContain("Dumping shared data to file"); + if (jsaFile.exists()) { + throw new RuntimeException("Archive file " + jsaFileName + " should not be created at exit"); + } + } + + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/CustomLoaderApp.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/CustomLoaderApp.java index ebc9350c57e8c3764bac3e245fec44ee48c6957f..37dcdbfdf1e31d41ccf55ce054dcf60148f871f9 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/CustomLoaderApp.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/CustomLoaderApp.java @@ -28,6 +28,8 @@ import java.net.URLClassLoader; public class CustomLoaderApp { private static String className = "LambHello"; + // Prevent the class from being GC'ed too soon. + private static Class keptC = null; public static void main(String args[]) throws Exception { String path = args[0]; @@ -37,13 +39,25 @@ public class CustomLoaderApp { System.out.println(url); boolean init = false; - if (args.length ==2 && args[1].equals("init")) { + if (args.length >= 2 && args[1].equals("init")) { init = true; } + // The dynamicArchive/LambdaCustomLoader.java test passes the keep-alive + // argument for preventing the class from being GC'ed prior to dumping of + // the dynamic CDS archive. + boolean keepAlive = false; + if (args[args.length - 1].equals("keep-alive")) { + keepAlive = true; + } + URLClassLoader urlClassLoader = new URLClassLoader("HelloClassLoader", urls, null); Class c = Class.forName(className, init, urlClassLoader); + if (keepAlive) { + keptC = c; + } + System.out.println(c); System.out.println(c.getClassLoader()); if (c.getClassLoader() != urlClassLoader) { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LotsUnloadApp.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LotsUnloadApp.java new file mode 100644 index 0000000000000000000000000000000000000000..8ac9275af2c0fa954448844f31ba0b3a047634a9 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LotsUnloadApp.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.lang.invoke.MethodType; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandles.Lookup.ClassOption.*; + +public class LotsUnloadApp implements Runnable { + static byte[] classdata; + static int exitAfterNumClasses = 1024; + + public static void main(String args[]) throws Throwable { + String resname = DefinedAsHiddenKlass.class.getName() + ".class"; + classdata = LotsUnloadApp.class.getClassLoader().getResourceAsStream(resname).readAllBytes(); + + int numThreads = 4; + try { + numThreads = Integer.parseInt(args[0]); + } catch (Throwable t) {} + + try { + exitAfterNumClasses = Integer.parseInt(args[1]); + } catch (Throwable t) {} + + for (int i = 0; i < numThreads; i++) { + Thread t = new Thread(new LotsUnloadApp()); + t.start(); + } + } + + public void run() { + while (true) { + try { + Lookup lookup = MethodHandles.lookup(); + Class<?> cl = lookup.defineHiddenClass(classdata, false, NESTMATE).lookupClass(); + cl.newInstance(); + add(); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + + static int n; + static synchronized void add() { + n++; + if (n >= exitAfterNumClasses) { + System.exit(0); + } + } +} + +class DefinedAsHiddenKlass { + // ZGC region size is always a multiple of 2MB on x64. + // Make this slightly smaller than that. + static byte[] array = new byte[2 * 1024 * 1024 - 8 * 1024]; + static String x; + public DefinedAsHiddenKlass() { + // This will generate some lambda forms hidden classes for string concat. + x = "array size is " + array.length + " bytes "; + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDumpBase.java b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDumpBase.java index 75103a50ed491a12c3b049491d3eb3597511d3a7..5e56d3a96e8d983fee61acda6b75603dc204fc7b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDumpBase.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDumpBase.java @@ -96,7 +96,7 @@ public abstract class JCmdTestDumpBase { } private static void checkCDSEnabled() throws Exception { - boolean cdsEnabled = WhiteBox.getWhiteBox().getBooleanVMFlag("UseSharedSpaces"); + boolean cdsEnabled = WhiteBox.getWhiteBox().isSharingEnabled(); if (!cdsEnabled) { throw new SkippedException("CDS is not available for this JDK."); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java index febc70aea0e6be81298522a7a57096cf6645a20e..61ec63258549b2be6511fba3d2089b5e422d2b80 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,20 +81,13 @@ public class JCmdTestDynamicDump extends JCmdTestDumpBase { test(null, pid, noBoot, EXPECT_PASS, DYNAMIC_MESSAGES); app.stopApp(); - // Test dynamic dump with flags -XX:+RecordDynamicDumpInfo -XX:-DynamicDumpSharedSpaces. - print2ln(test_count++ + " Test dynamic dump with flags -XX:+RecordDynamicDumpInfo -XX:-DynamicDumpSharedSpaces."); - app = createLingeredApp("-cp", allJars, "-XX:+RecordDynamicDumpInfo", "-XX:-DynamicDumpSharedSpaces"); + // Test dynamic dump with flag -XX:+RecordDynamicDumpInfo + print2ln(test_count++ + " Test dynamic dump with flag -XX:+RecordDynamicDumpInfo."); + app = createLingeredApp("-cp", allJars, "-XX:+RecordDynamicDumpInfo"); pid = app.getPid(); test(null, pid, noBoot, EXPECT_PASS, DYNAMIC_MESSAGES); app.stopApp(); - // Test dynamic dump with flags -XX:-DynamicDumpSharedSpaces -XX:+RecordDynamicDumpInfo. - print2ln(test_count++ + " Test dynamic dump with flags -XX:-DynamicDumpSharedSpaces -XX:+RecordDynamicDumpInfo."); - app = createLingeredApp("-cp", allJars, "-XX:-DynamicDumpSharedSpaces", "-XX:+RecordDynamicDumpInfo"); - pid = app.getPid(); - test(null, pid, noBoot, EXPECT_PASS, DYNAMIC_MESSAGES); - app.stopApp(); - // Test dynamic with -Xbootclasspath/a:boot.jar print2ln(test_count++ + " Test dynamic with -Xbootclasspath/a:boot.jar"); app = createLingeredApp("-cp", testJar, "-Xbootclasspath/a:" + bootJar, "-XX:+RecordDynamicDumpInfo"); @@ -124,6 +117,17 @@ public class JCmdTestDynamicDump extends JCmdTestDumpBase { throw new RuntimeException("The JCmdTestLingeredApp should not start up!"); } } + // Test dynamic dump with -Xlog:cds to check lambda invoker class regeneration + print2ln(test_count++ + " Test dynamic dump with -Xlog:cds to check lambda invoker class regeneration"); + app = createLingeredApp("-cp", allJars, "-XX:+RecordDynamicDumpInfo", "-Xlog:cds", + "-XX:SharedArchiveFile=" + archiveFile); + pid = app.getPid(); + test(null, pid, noBoot, EXPECT_PASS, DYNAMIC_MESSAGES); + String stdout = app.getProcessStdout(); + if (stdout.contains("Regenerate MethodHandle Holder classes...")) { + throw new RuntimeException("jcmd VM.cds dynamic_dump should not regenerate MethodHandle Holder classes"); + } + app.stopApp(); } // Dump a static archive, not using TestCommon.dump(...), we do not take jtreg args. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java index e6312521d157d313cbc47d0da8382af357000b83..e5e2c676947d0a281f85397940c5bccde76921c1 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestFileSafety.java @@ -38,6 +38,9 @@ import java.io.File; import java.io.IOException; +import java.nio.file.attribute.FileTime; +import java.nio.file.Files; +import java.nio.file.Paths; import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.apps.LingeredApp; import jdk.test.lib.Platform; @@ -61,6 +64,13 @@ public class JCmdTestFileSafety extends JCmdTestDumpBase { } } + private static void removeFile(String fileName) throws Exception { + File file = new File(fileName); + if (file.exists()) { + file.delete(); + } + } + static void test() throws Exception { buildJars(); @@ -75,6 +85,8 @@ public class JCmdTestFileSafety extends JCmdTestDumpBase { } outputDirFile.setWritable(true); String localFileName = subDir + File.separator + "MyStaticDump.jsa"; + removeFile(localFileName); + setIsStatic(true/*static*/); // Set target dir not writable, do static dump print2ln(test_count++ + " Set target dir not writable, do static dump"); @@ -82,10 +94,16 @@ public class JCmdTestFileSafety extends JCmdTestDumpBase { app = createLingeredApp("-cp", allJars); pid = app.getPid(); test(localFileName, pid, noBoot, EXPECT_PASS); + checkFileExistence(localFileName, true/*exist*/); + FileTime ft1 = Files.getLastModifiedTime(Paths.get(localFileName)); outputDirFile.setWritable(false); test(localFileName, pid, noBoot, EXPECT_FAIL); + FileTime ft2 = Files.getLastModifiedTime(Paths.get(localFileName)); + if (!ft2.equals(ft1)) { + throw new RuntimeException("Archive file " + localFileName + " should not be updated"); + } + removeFile(localFileName); outputDirFile.setWritable(true); - checkFileExistence(localFileName, true/*exist*/); // Illegal character in file name localFileName = "mystatic:.jsa"; @@ -103,18 +121,17 @@ public class JCmdTestFileSafety extends JCmdTestDumpBase { pid = app.getPid(); localFileName = subDir + File.separator + "MyDynamicDump.jsa"; test(localFileName, pid, noBoot, EXPECT_PASS); - app.stopApp(); - // cannot dynamically dump twice, restart - app = createLingeredApp("-cp", allJars, "-XX:+RecordDynamicDumpInfo"); - pid = app.getPid(); + checkFileExistence(localFileName, true/*exist*/); + ft1 = Files.getLastModifiedTime(Paths.get(localFileName)); outputDirFile.setWritable(false); test(localFileName, pid, noBoot, EXPECT_FAIL); - outputDirFile.setWritable(true); + ft2 = Files.getLastModifiedTime(Paths.get(localFileName)); + if (!ft2.equals(ft1)) { + throw new RuntimeException("Archive file " + localFileName + " should not be updated"); + } app.stopApp(); - // MyDynamicDump.jsa should exist - checkFileExistence(localFileName, true); - File rmFile = new File(localFileName); - rmFile.delete(); + removeFile(localFileName); + outputDirFile.setWritable(true); outputDirFile.delete(); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestStaticDump.java b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestStaticDump.java index 2ac55b824a9f48d21c47f8668c6f47b44c214fb1..d232f936a0cf9a8f0c20d081ab99907dfadb8259 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestStaticDump.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestStaticDump.java @@ -45,25 +45,19 @@ public class JCmdTestStaticDump extends JCmdTestDumpBase { "LingeredApp source: shared objects file", "Hello source: shared objects file"}; - // Those two flags will not create a successful LingeredApp. + // This flag will not create a successful LingeredApp. private static String[] noDumpFlags = - {"-XX:+DumpSharedSpaces", - "-Xshare:dump"}; + {"-Xshare:dump"}; // Those flags will be excluded in static dumping, // See src/java.base/share/classes/jdk/internal/misc/CDS.java private static String[] excludeFlags = { "-XX:DumpLoadedClassList=AnyFileName.classlist", - // this flag just dump archive, won't run app normally. - // "-XX:+DumpSharedSpaces", - "-XX:+DynamicDumpSharedSpaces", "-XX:+RecordDynamicDumpInfo", "-Xshare:on", "-Xshare:auto", "-XX:SharedClassListFile=non-exist.classlist", "-XX:SharedArchiveFile=non-exist.jsa", - "-XX:ArchiveClassesAtExit=tmp.jsa", - "-XX:+UseSharedSpaces", - "-XX:+RequireSharedSpaces"}; + "-XX:ArchiveClassesAtExit=tmp.jsa"}; // Times to dump cds against same process. private static final int ITERATION_TIMES = 2; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java index 189559a46618dd2b72bd672f88ef164a640549ab..eecc218a71aa305d270596a5b3a8c03f7c4ad040 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -219,6 +219,16 @@ public class OptimizeModuleHandlingTest { "-Xbootclasspath/a:", ".", "--module-path", libsDir.toString(), MAIN_CLASS) + .assertAbnormalExit(out -> { + out.shouldNotContain(CLASS_FOUND_MESSAGE) + .shouldContain(OPTIMIZE_DISABLED) // mapping info + .shouldContain("Error: Could not find or load main class ."); + }); + tty("11. run with CDS on, --module-path, with -Xbootclasspath/a:."); + TestCommon.run("-Xlog:cds", + "-Xbootclasspath/a:.", + "--module-path", libsDir.toString(), + MAIN_CLASS) .assertAbnormalExit(out -> { out.shouldNotContain(CLASS_FOUND_MESSAGE) .shouldContain(OPTIMIZE_DISABLED) // mapping info diff --git a/test/hotspot/jtreg/runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java index 9d194c288a34942acb13afdaf654150ce381b37d..67cc06e38ca03c7e73b079a56f06fe73257ad0d2 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,7 +130,7 @@ public class DynamicLoaderConstraintsTest extends DynamicArchiveTestBase { static void doTest(boolean errorInDump) throws Exception { for (int i = 1; i <= 3; i++) { System.out.println("========================================"); - System.out.println("errorInDump: " + errorInDump + ", useCustomLoader: " + useCustomLoader + ", case: " + i); + System.out.println("errorInDump: " + errorInDump + ", useCustomLoader: " + useCustomLoader + ", useZGC: " + useZGC + ", case: " + i); System.out.println("========================================"); String topArchiveName = getNewArchiveName(); String testCase = Integer.toString(i); @@ -139,7 +139,7 @@ public class DynamicLoaderConstraintsTest extends DynamicArchiveTestBase { "java.base,jdk.httpserver", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", - "-Xlog:class+load,class+loader+constraints", + "-Xlog:cds=debug,class+load,class+loader+constraints", }; if (useCustomLoader) { @@ -148,6 +148,7 @@ public class DynamicLoaderConstraintsTest extends DynamicArchiveTestBase { cmdLine = TestCommon.concat(cmdLine, "-cp", loaderJar, "-XX:+UseZGC", "-XX:ZCollectionInterval=0.01", loaderMainClass, appJar); + setBaseArchiveOptions("-XX:+UseZGC", "-Xlog:cds"); } else { cmdLine = TestCommon.concat(cmdLine, "-cp", loaderJar, loaderMainClass, appJar); diff --git a/test/hotspot/jtreg/runtime/classFileParserBug/TrailingSlashTest.java b/test/hotspot/jtreg/runtime/classFileParserBug/TrailingSlashTest.java new file mode 100644 index 0000000000000000000000000000000000000000..422b7357d2e6dadd5632ff1c2e7a320edeffbdf5 --- /dev/null +++ b/test/hotspot/jtreg/runtime/classFileParserBug/TrailingSlashTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8276241 + * @summary Throw ClassFormatError exception for an old class file whose name ends in a '/'. + * @run main/othervm -Xverify:remote TrailingSlashTest + */ + +public class TrailingSlashTest extends ClassLoader { + + @Override + public Class findClass(String fileName) throws ClassNotFoundException { + return defineClass(null, oldSlashClass, 0, oldSlashClass.length); + } + + public static void main(String args[]) throws Throwable { + try { + TrailingSlashTest cl = new TrailingSlashTest(); + cl.findClass("oldSlashClass"); + throw new RuntimeException("Expected exception not thrown"); + } catch (ClassFormatError e) { + if (!e.getMessage().contains("Illegal class name")) { + throw new RuntimeException("Wrong ClassFormatError exception: " + e.getMessage()); + } + } + } + + + // This byte array comprises the compiled bytes of the following class. Note that the class's + // name ends in a '/' and has a class file version of 45.3. + /* + package has; + public class slashe/ { } + */ + public static byte[] oldSlashClass = { + (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe, (byte) 0x0, (byte) 0x3, (byte) 0x0, (byte) 0x2d, + (byte) 0x0, (byte) 0xd, (byte) 0xa, (byte) 0x0, (byte) 0x2, (byte) 0x0, (byte) 0x3, (byte) 0x7, + (byte) 0x0, (byte) 0x4, (byte) 0xc, (byte) 0x0, (byte) 0x5, (byte) 0x0, (byte) 0x6, (byte) 0x1, + (byte) 0x0, (byte) 0x10, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x6c, + (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x4f, (byte) 0x62, (byte) 0x6a, (byte) 0x65, + (byte) 0x63, (byte) 0x74, (byte) 0x1, (byte) 0x0, (byte) 0x6, (byte) 0x3c, (byte) 0x69, (byte) 0x6e, + (byte) 0x69, (byte) 0x74, (byte) 0x3e, (byte) 0x1, (byte) 0x0, (byte) 0x3, (byte) 0x28, (byte) 0x29, + (byte) 0x56, (byte) 0x7, (byte) 0x0, (byte) 0x8, (byte) 0x1, (byte) 0x0, (byte) 0xb, (byte) 0x68, + (byte) 0x61, (byte) 0x73, (byte) 0x2f, (byte) 0x73, (byte) 0x6c, (byte) 0x61, (byte) 0x73, (byte) 0x68, + (byte) 0x65, (byte) 0x2f, (byte) 0x1, (byte) 0x0, (byte) 0x4, (byte) 0x43, (byte) 0x6f, (byte) 0x64, + (byte) 0x65, (byte) 0x1, (byte) 0x0, (byte) 0xf, (byte) 0x4c, (byte) 0x69, (byte) 0x6e, (byte) 0x65, + (byte) 0x4e, (byte) 0x75, (byte) 0x6d, (byte) 0x62, (byte) 0x65, (byte) 0x72, (byte) 0x54, (byte) 0x61, + (byte) 0x62, (byte) 0x6c, (byte) 0x65, (byte) 0x1, (byte) 0x0, (byte) 0xa, (byte) 0x53, (byte) 0x6f, + (byte) 0x75, (byte) 0x72, (byte) 0x63, (byte) 0x65, (byte) 0x46, (byte) 0x69, (byte) 0x6c, (byte) 0x65, + (byte) 0x1, (byte) 0x0, (byte) 0xc, (byte) 0x73, (byte) 0x6c, (byte) 0x61, (byte) 0x73, (byte) 0x68, + (byte) 0x65, (byte) 0x73, (byte) 0x2e, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x0, + (byte) 0x21, (byte) 0x0, (byte) 0x7, (byte) 0x0, (byte) 0x2, (byte) 0x0, (byte) 0x0, (byte) 0x0, + (byte) 0x0, (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x5, (byte) 0x0, + (byte) 0x6, (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x9, (byte) 0x0, (byte) 0x0, (byte) 0x0, + (byte) 0x1d, (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x0, (byte) 0x0, + (byte) 0x5, (byte) 0x2a, (byte) 0xb7, (byte) 0x0, (byte) 0x1, (byte) 0xb1, (byte) 0x0, (byte) 0x0, + (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0xa, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x6, + (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x3, (byte) 0x0, (byte) 0x1, + (byte) 0x0, (byte) 0xb, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x2, (byte) 0x0, (byte) 0xc, + }; + +} diff --git a/test/hotspot/jtreg/runtime/logging/ThreadLoggingTest.java b/test/hotspot/jtreg/runtime/logging/ThreadLoggingTest.java index 82a189a92cbe2abc1e05015af6dbbde1ff5fdd59..d98fc455319386c806d9722ed4d361b689d55d40 100644 --- a/test/hotspot/jtreg/runtime/logging/ThreadLoggingTest.java +++ b/test/hotspot/jtreg/runtime/logging/ThreadLoggingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,7 +24,7 @@ /* * @test - * @bug 8149036 8150619 + * @bug 8149036 8150619 8277531 * @summary os+thread output should contain logging calls for thread start stop attaches detaches * @requires vm.flagless * @library /test/lib @@ -36,6 +36,7 @@ import java.io.File; import java.util.Map; +import jdk.test.lib.Platform; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -43,7 +44,11 @@ public class ThreadLoggingTest { static void analyzeOutputForInfoLevel(OutputAnalyzer output) throws Exception { output.shouldMatch("Thread .* started"); - output.shouldContain("Thread is alive"); + if (Platform.isWindows()) { + output.shouldMatch("Thread is alive \\(tid: [0-9]+, stacksize: [0-9]+k\\)"); + } else { + output.shouldContain("Thread is alive"); + } output.shouldContain("Thread finished"); output.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/modules/AccessCheck/MethodAccessReadTwice.java b/test/hotspot/jtreg/runtime/modules/AccessCheck/MethodAccessReadTwice.java index 29bbe7f39b0f0f29b3d5bb59d4fd639b76518692..d6b85ced2576be3fb576d7b804c27613cc72de04 100644 --- a/test/hotspot/jtreg/runtime/modules/AccessCheck/MethodAccessReadTwice.java +++ b/test/hotspot/jtreg/runtime/modules/AccessCheck/MethodAccessReadTwice.java @@ -29,8 +29,8 @@ * after the module read edge is added. * @compile ModuleLibrary.java * p2/c2.java - * p5/c5.java - * p7/c7.java + * p5/c5.jasm + * p7/c7.jasm * @run main/othervm MethodAccessReadTwice */ diff --git a/test/hotspot/jtreg/runtime/modules/AccessCheck/p5/c5.jasm b/test/hotspot/jtreg/runtime/modules/AccessCheck/p5/c5.jasm new file mode 100644 index 0000000000000000000000000000000000000000..b1178eaab6c1f2b50346695519ba46846983b0df --- /dev/null +++ b/test/hotspot/jtreg/runtime/modules/AccessCheck/p5/c5.jasm @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021, Google LLC. All rights reserved. + * 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 input for the fix for JDK-8174954, which checks for an expected + * IllegalAccessError when the parameter type of an invokedynamic is + * inaccessible. + * + * The test assumes that given the string concatenation expression "" + param, + * javac generates an invokedynamic that uses the specific type of param. The + * fix for JDK-8273914 make javac eagerly convert param to a String before + * passing it to the invokedynamic call, which avoids the accessibility issue + * the test is trying to exercise. + * + * This jasm file contains the bytecode javac generated before the fix for + * JDK-8273914, to continue to exercise the invokedynamic behaviour that + * JDK-8174954 is testing. + */ + +package p5; + +super public class c5 + version 61:0 +{ + public Method "<init>":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."<init>":"()V"; + return; + } + public Method method5:"(Lp2/c2;)V" + stack 2 locals 2 + { + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + aload_1; + invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;":makeConcatWithConstants:"(Lp2/c2;)Ljava/lang/String;" { + String "In c5\'s method5 with param = " + }; + invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V"; + return; + } + public Method methodAddReadEdge:"(Ljava/lang/Module;)V" + stack 2 locals 2 + { + ldc class c5; + invokevirtual Method java/lang/Class.getModule:"()Ljava/lang/Module;"; + aload_1; + invokevirtual Method java/lang/Module.addReads:"(Ljava/lang/Module;)Ljava/lang/Module;"; + pop; + return; + } + + public static final InnerClass Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles; + +} // end Class c5 diff --git a/test/hotspot/jtreg/runtime/modules/AccessCheck/p7/c7.jasm b/test/hotspot/jtreg/runtime/modules/AccessCheck/p7/c7.jasm new file mode 100644 index 0000000000000000000000000000000000000000..6ca4e6850e3e031f8bcce0ea7e75c7f3034c2dea --- /dev/null +++ b/test/hotspot/jtreg/runtime/modules/AccessCheck/p7/c7.jasm @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021, Google LLC. All rights reserved. + * 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 input for the fix for JDK-8174954, which checks for an expected + * IllegalAccessError when the parameter type of an invokedynamic is + * inaccessible. + * + * The test assumes that given the string concatenation expression "" + param, + * javac generates an invokedynamic that uses the specific type of param. The + * fix for JDK-8273914 make javac eagerly convert param to a String before + * passing it to the invokedynamic call, which avoids the accessibility issue + * the test is trying to exercise. + * + * This jasm file contains the bytecode javac generated before the fix for + * JDK-8273914, to continue to exercise the invokedynamic behaviour that + * JDK-8174954 is testing. + */ + +package p7; + +super public class c7 + version 61:0 +{ + public Method "<init>":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."<init>":"()V"; + return; + } + public Method method7:"(Lp2/c2;Ljava/lang/Module;)V" + stack 3 locals 4 + { + try t0; + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + aload_1; + invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;":makeConcatWithConstants:"(Lp2/c2;)Ljava/lang/String;" { + String "In c7\'s method7 with param = " + }; + invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V"; + new class java/lang/RuntimeException; + dup; + ldc String "c7 failed to throw expected IllegalAccessError"; + invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V"; + athrow; + endtry t0; + catch t0 java/lang/IllegalAccessError; + stack_frame_type stack1; + stack_map class java/lang/IllegalAccessError; + astore_3; + aload_0; + aload_2; + invokevirtual Method methodAddReadEdge:"(Ljava/lang/Module;)V"; + try t1; + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + aload_1; + invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;":makeConcatWithConstants:"(Lp2/c2;)Ljava/lang/String;" { + String "In c7\'s method7 with param = " + }; + invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V"; + endtry t1; + goto L61; + catch t1 java/lang/IllegalAccessError; + stack_frame_type stack1; + stack_map class java/lang/IllegalAccessError; + astore_3; + new class java/lang/RuntimeException; + dup; + aload_3; + invokevirtual Method java/lang/IllegalAccessError.getMessage:"()Ljava/lang/String;"; + invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;":makeConcatWithConstants:"(Ljava/lang/String;)Ljava/lang/String;" { + String "Unexpected IllegalAccessError: " + }; + invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V"; + athrow; + L61: stack_frame_type same; + return; + } + public Method methodAddReadEdge:"(Ljava/lang/Module;)V" + stack 2 locals 2 + { + ldc class c7; + invokevirtual Method java/lang/Class.getModule:"()Ljava/lang/Module;"; + aload_1; + invokevirtual Method java/lang/Module.addReads:"(Ljava/lang/Module;)Ljava/lang/Module;"; + pop; + return; + } + + public static final InnerClass Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles; + +} // end Class c7 diff --git a/test/hotspot/jtreg/serviceability/dcmd/compiler/CodeHeapAnalyticsMethodNames.java b/test/hotspot/jtreg/serviceability/dcmd/compiler/CodeHeapAnalyticsMethodNames.java index da10be193b94b84a209535a970fd765d8f09506c..8733b3f9d12d4fb6261c4831cfa9f674a369f258 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/compiler/CodeHeapAnalyticsMethodNames.java +++ b/test/hotspot/jtreg/serviceability/dcmd/compiler/CodeHeapAnalyticsMethodNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon.com Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/hotspot/jtreg/serviceability/jvmti/FieldAccessWatch/FieldAccessWatch.java b/test/hotspot/jtreg/serviceability/jvmti/FieldAccessWatch/FieldAccessWatch.java index c3be30a014841dcbe5e333dc99838c0e6ddc318c..d4345af258638e5968262230a554aefc10e2f7e2 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/FieldAccessWatch/FieldAccessWatch.java +++ b/test/hotspot/jtreg/serviceability/jvmti/FieldAccessWatch/FieldAccessWatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ public class FieldAccessWatch { throw ex; } - if (!initWatchers(MyList.class, MyList.class.getDeclaredField("items"))) { + if (!initWatchers(MyList.class, MyList.class.getDeclaredField("items"), Thread.currentThread())) { throw new RuntimeException("Watchers initializations error"); } @@ -131,7 +131,7 @@ public class FieldAccessWatch { log(descr + ": OK"); } - private static native boolean initWatchers(Class cls, Field field); + private static native boolean initWatchers(Class cls, Field field, Thread testThread); private static native boolean startTest(TestResult results); private static native void stopTest(); diff --git a/test/hotspot/jtreg/serviceability/jvmti/FieldAccessWatch/libFieldAccessWatch.c b/test/hotspot/jtreg/serviceability/jvmti/FieldAccessWatch/libFieldAccessWatch.c index fdc28961e894e71ecc76b2e0056a3bb75faa9fcf..9973f5eef759c63ac46efbf662fcab55dd22f79e 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/FieldAccessWatch/libFieldAccessWatch.c +++ b/test/hotspot/jtreg/serviceability/jvmti/FieldAccessWatch/libFieldAccessWatch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ static jvmtiEnv *jvmti = NULL; // valid while a test is executed static jobject testResultObject = NULL; static jclass testResultClass = NULL; +static jthread testThread = NULL; static void reportError(const char *msg, int err) { @@ -46,6 +47,7 @@ static void reportError(const char *msg, int err) { // logs the notification and updates currentTestResult static void handleNotification(JNIEnv *jni_env, + jthread thread, jmethodID method, jfieldID field, jclass field_klass, @@ -64,6 +66,10 @@ static void handleNotification(JNIEnv *jni_env, return; } + if (!(*jni_env)->IsSameObject(jni_env, thread, testThread)) { + return; // skip events from unexpected threads + } + err = (*jvmti)->GetFieldName(jvmti, field_klass, field, &name, NULL, NULL); if (err != JVMTI_ERROR_NONE) { reportError("GetFieldName failed", err); @@ -179,7 +185,7 @@ onFieldAccess(jvmtiEnv *jvmti_env, jobject object, jfieldID field) { - handleNotification(jni_env, method, field, field_klass, 0, location); + handleNotification(jni_env, thread, method, field, field_klass, 0, location); } @@ -195,7 +201,7 @@ onFieldModification(jvmtiEnv *jvmti_env, char signature_type, jvalue new_value) { - handleNotification(jni_env, method, field, field_klass, 1, location); + handleNotification(jni_env, thread, method, field, field_klass, 1, location); if (signature_type == 'L') { jobject newObject = new_value.l; @@ -251,7 +257,7 @@ Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) JNIEXPORT jboolean JNICALL -Java_FieldAccessWatch_initWatchers(JNIEnv *env, jclass thisClass, jclass cls, jobject field) +Java_FieldAccessWatch_initWatchers(JNIEnv *env, jclass thisClass, jclass cls, jobject field, jthread thread) { jfieldID fieldId; jvmtiError err; @@ -275,6 +281,8 @@ Java_FieldAccessWatch_initWatchers(JNIEnv *env, jclass thisClass, jclass cls, jo return JNI_FALSE; } + testThread = (jthread)(*env)->NewGlobalRef(env, thread); + return JNI_TRUE; } diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java index 9990cca9a8158e8531993fde7fea609fc028aa32..bc1dd5a896361658791eb3dc2cd2577be903ed11 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java @@ -182,6 +182,28 @@ public class ClhsdbFindPC { methodAddr)); runTest(withCore, cmds, expStrMap); + // Rerun above findpc command, but this time using "whatis", which is an alias for "findpc". + cmdStr = "whatis " + methodAddr; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + expStrMap.put(cmdStr, List.of("Method ", + "LingeredApp.steadyState", + methodAddr)); + runTest(withCore, cmds, expStrMap); + + // Run "mem -v <addr>/30" on a Method*. The first line will look like: + // Address 0x0000152e30403530: Method jdk/test/lib/apps/LingeredApp.steadyState(Ljava/lang/Object;)V@0x0000152e30403530 + // Followed by lines displaying the memory contents, including interpretation + // of any contents that are addresses. + cmdStr = "mem -v " + methodAddr + "/30"; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + expStrMap.put(cmdStr, List.of("Method jdk/test/lib/apps/LingeredApp.steadyState", + methodAddr, + /* The following is from a field in the Method object. */ + "In interpreter codelet: method entry point")); + runTest(withCore, cmds, expStrMap); + // Run findpc on a JavaThread*. We can find one in the jstack output. // The tid for a thread is it's JavaThread*. For example: // "main" #1 prio=5 tid=0x00000080263398f0 nid=0x277e0 ... diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java index c390fc61dca391f0682e48c2aa86e5ff64bd0cb7..c032b71a000f3746ead6bc8d412145034d3ea885 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ import java.util.Map; import java.util.ArrayList; import jdk.test.lib.Utils; import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.process.OutputAnalyzer; import jtreg.SkippedException; public class ClhsdbScanOops { @@ -71,35 +72,54 @@ public class ClhsdbScanOops { Map<String, List<String>> expStrMap = new HashMap<>(); Map<String, List<String>> unExpStrMap = new HashMap<>(); - String startAddress = null; - String endAddress = null; - String[] snippets = null; + String startAddress; + String endAddress; + String[] snippets; + String[] words; + String cmd; + // Run scanoops on the old gen + if (gc.contains("UseParallelGC")) { + snippets = universeOutput.split("PSOldGen \\[ "); + } else { + snippets = universeOutput.split("old \\["); + } + words = snippets[1].split(","); + // Get the addresses for Old gen + startAddress = words[0].replace("[", ""); + endAddress = words[1]; + cmd = "scanoops " + startAddress + " " + endAddress; + String output1 = test.run(theApp.getPid(), List.of(cmd), null, null); + + // Run scanoops on the eden gen if (gc.contains("UseParallelGC")) { snippets = universeOutput.split("eden = "); } else { snippets = universeOutput.split("eden \\["); } - String[] words = snippets[1].split(","); - // Get the addresses from Eden + words = snippets[1].split(","); + // Get the addresses for Eden gen startAddress = words[0].replace("[", ""); endAddress = words[1]; - String cmd = "scanoops " + startAddress + " " + endAddress; - cmds.add(cmd); - - expStrMap.put(cmd, List.of - ("java/lang/Object", "java/lang/Class", "java/lang/Thread", - "java/lang/String", "\\[B", "\\[I")); + cmd = "scanoops " + startAddress + " " + endAddress; + String output2 = test.run(theApp.getPid(), List.of(cmd), null, null); + + // Look for expected types in the combined eden and old gens + OutputAnalyzer out = new OutputAnalyzer(output1 + output2); + List<String> expectStrs = List.of( + "java/lang/Object", "java/lang/Class", "java/lang/Thread", + "java/lang/String", "\\[B", "\\[I"); + for (String expectStr : expectStrs) { + out.shouldMatch(expectStr); + } - // Test the 'type' option also - // scanoops <start addr> <end addr> java/lang/String + // Test the 'type' option also: + // scanoops <start addr> <end addr> java/lang/String // Ensure that only the java/lang/String oops are printed. cmd = cmd + " java/lang/String"; - cmds.add(cmd); expStrMap.put(cmd, List.of("java/lang/String")); - unExpStrMap.put(cmd, List.of("java/lang/Thread")); - - test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap); + unExpStrMap.put(cmd, List.of("java/lang/Thread", "java/lang/Class", "java/lang/Object")); + test.run(theApp.getPid(), List.of(cmd), expStrMap, unExpStrMap); } catch (SkippedException e) { throw e; } catch (Exception ex) { diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java new file mode 100644 index 0000000000000000000000000000000000000000..e84ae52e92056aa8b787daa6738f692f96cc6c7f --- /dev/null +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.Platform; +import jtreg.SkippedException; + +/** + * @test + * @summary Test clhsdb where command + * @requires vm.hasSA + * @library /test/lib + * @run main/othervm ClhsdbThreadContext + */ + +public class ClhsdbThreadContext { + public static void main(String[] args) throws Exception { + System.out.println("Starting ClhsdbThreadContext test"); + + LingeredApp theApp = null; + try { + ClhsdbLauncher test = new ClhsdbLauncher(); + theApp = LingeredApp.startApp(); + System.out.println("Started LingeredApp with pid " + theApp.getPid()); + + // Run threadcontext on all threads + String cmdStr = "threadcontext -a"; + List<String> cmds = List.of(cmdStr); + Map<String, List<String>> expStrMap = new HashMap<>(); + expStrMap.put(cmdStr, List.of( + "Thread \"Common-Cleaner\"", + "Thread \"Service Thread\"", + "Thread \"Finalizer\"", + "Thread \"SteadyStateThread\"", + "In java stack for thread \"SteadyStateThread\"")); + String cmdOutput = test.run(theApp.getPid(), cmds, expStrMap, null); + + // Run threadcontext on all threads in verbose mode + cmdStr = "threadcontext -v -a"; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + expStrMap.put(cmdStr, List.of( + "Thread \"Common-Cleaner\"", + "Thread \"Service Thread\"", + "Thread \"Finalizer\"", + "Thread \"SteadyStateThread\"")); + Map<String, List<String>> unexpStrMap = new HashMap<>(); + unexpStrMap.put(cmdStr, List.of( + "In java stack for thread \"SteadyStateThread\"")); + test.run(theApp.getPid(), cmds, expStrMap, unexpStrMap); + + // Look for a line like the following and parse the threadID out of it. + // Thread "SteadyStateThread" id=18010 Address=0x000014bf103eaf50 + String[] parts = cmdOutput.split("Thread \"SteadyStateThread\" id="); + String[] tokens = parts[1].split(" "); + String threadID = tokens[0]; + + // Run threadcontext on the SteadyStateThread in verbose mode + cmdStr = "threadcontext -v " + threadID; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + unexpStrMap = new HashMap<>(); + if (Platform.isWindows()) { + // On windows thread IDs are not guaranteed to be the same each time you attach, + // so the ID we gleaned above for SteadyStateThread may not actually be for + // SteadyStateThread when we attach for the next threadcontext command, so we + // choose not to check the result on Windows. + } else { + expStrMap.put(cmdStr, List.of( + "Thread \"SteadyStateThread\"", + "java.lang.Thread.State: BLOCKED", + "In java stack \\[0x\\p{XDigit}+,0x\\p{XDigit}+,0x\\p{XDigit}+\\] for thread")); + unexpStrMap.put(cmdStr, List.of( + "Thread \"Common-Cleaner\"", + "Thread \"Service Thread\"", + "Thread \"Finalizer\"")); + } + test.run(theApp.getPid(), cmds, expStrMap, unexpStrMap); + + // Run threadcontext on all threads in verbose mode + + } catch (SkippedException se) { + throw se; + } catch (Exception ex) { + throw new RuntimeException("Test ERROR " + ex, ex); + } finally { + LingeredApp.stopApp(theApp); + } + + System.out.println("Test PASSED"); + } +} diff --git a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java index 9acf9d3bbb90c5c2e9f99db42300a7380a445417..4140a3e3381047ec954c970a25742acb8655c586 100644 --- a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java +++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,19 @@ public class LingeredAppWithLock extends LingeredApp { objectLock.start(); primitiveLock.start(); + // Wait until all threads have reached their blocked or timed wait state + while ((classLock1.getState() != Thread.State.BLOCKED && + classLock1.getState() != Thread.State.TIMED_WAITING) || + (classLock2.getState() != Thread.State.BLOCKED && + classLock2.getState() != Thread.State.TIMED_WAITING) || + (objectLock.getState() != Thread.State.TIMED_WAITING) || + (primitiveLock.getState() != Thread.State.TIMED_WAITING)) { + try { + Thread.sleep(100); + } catch (InterruptedException ex) { + } + } + LingeredApp.main(args); } } diff --git a/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java b/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java index 5f1e6c48f5f98e2bed92b705b9636eb939d90529..e2d79b1ce9df751fd5592f343067e977b95e4eda 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java +++ b/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, NTT DATA. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -59,8 +59,12 @@ public class TestObjectMonitorIterate { while (itr.hasNext()) { ObjectMonitor mon = (ObjectMonitor)itr.next(); - Oop oop = heap.newOop(mon.object()); - System.out.println("Monitor found: " + oop.getKlass().getName().asString()); + if (mon.object() == null) { + System.out.println("Monitor found: object is null"); + } else { + Oop oop = heap.newOop(mon.object()); + System.out.println("Monitor found: " + oop.getKlass().getName().asString()); + } } } finally { agent.detach(); diff --git a/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java b/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java index a0bbdbc809b0c4c5fc8f6fd8dfe4ffff122ed70e..49f90f7f9fd155515c6773dc6b4f3c840f01c7b2 100644 --- a/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java +++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/SADebugDTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * 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 8163805 8224252 8196751 + * @bug 8163805 8224252 8196751 8279351 * @summary Checks that the jshdb debugd utility successfully starts * and tries to attach to a running process * @requires vm.hasSA @@ -71,6 +71,16 @@ public class SADebugDTest { } } + private static boolean checkOutput(final String line, final boolean useRmiPort, final int rmiPort) { + if (!useRmiPort && line.contains(GOLDEN)) { + testResult = true; + } else if (useRmiPort && line.contains(RMI_CONNECTOR_IS_BOUND + rmiPort)) { + testResult = true; + } else if (line.contains(ADDRESS_ALREADY_IN_USE)) { + portInUse = true; + } + return (line.contains(GOLDEN) || portInUse); + } private static void testWithPid(final boolean useRmiPort, final boolean useRegistryPort, final boolean useHostName) throws Exception { LingeredApp app = null; @@ -95,9 +105,8 @@ public class SADebugDTest { jhsdbLauncher.addToolArg(Integer.toString(registryPort)); } - int rmiPort = -1; + final int rmiPort = useRmiPort ? Utils.findUnreservedFreePort(REGISTRY_DEFAULT_PORT, registryPort) : -1; if (useRmiPort) { - rmiPort = Utils.findUnreservedFreePort(REGISTRY_DEFAULT_PORT, registryPort); jhsdbLauncher.addToolArg("--rmiport"); jhsdbLauncher.addToolArg(Integer.toString(rmiPort)); } @@ -107,28 +116,16 @@ public class SADebugDTest { } ProcessBuilder pb = SATestUtils.createProcessBuilder(jhsdbLauncher); - final int finalRmiPort = rmiPort; - // The startProcess will block until the 'golden' string appears in either process' stdout or stderr // In case of timeout startProcess kills the debugd process - Process debugd = startProcess("debugd", pb, null, - l -> { - if (!useRmiPort && l.contains(GOLDEN)) { - testResult = true; - } else if (useRmiPort && l.contains(RMI_CONNECTOR_IS_BOUND + finalRmiPort)) { - testResult = true; - } else if (l.contains(ADDRESS_ALREADY_IN_USE)) { - portInUse = true; - } - return (l.contains(GOLDEN) || portInUse); - }, 20, TimeUnit.SECONDS); + Process debugd = startProcess("debugd", pb, null, l -> checkOutput(l, useRmiPort, rmiPort), 20, TimeUnit.SECONDS); // If we are here, this means we have received the golden line and the test has passed // The debugd remains running, we have to kill it debugd.destroy(); debugd.waitFor(); - if (!testResult) { + if (!testResult && !portInUse) { throw new RuntimeException("Expected message \"" + RMI_CONNECTOR_IS_BOUND + rmiPort + "\" is not found in the output."); } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat002/thrstat002.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat002/thrstat002.cpp index 4840af81f3838f6dd59fd89f9d4ff67318320fc8..2b10a77c56caa8c3a616076733f7f9ce0f3b2623 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat002/thrstat002.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat002/thrstat002.cpp @@ -48,6 +48,107 @@ static jint state[] = { JVMTI_THREAD_STATE_IN_OBJECT_WAIT }; + +#if 1 // support for debug tracing + +#define LOG(...) \ + { \ + printf(__VA_ARGS__); \ + fflush(stdout); \ + } + +#define MAX_FRAME_COUNT_PRINT_STACK_TRACE 200 + +static void +check_jvmti_status(JNIEnv* jni, jvmtiError err, const char* msg) { + if (err != JVMTI_ERROR_NONE) { + LOG("check_jvmti_status: JVMTI function returned error: %s (%d)\n", TranslateError(err), err); + jni->FatalError(msg); + } +} + +static void +deallocate(jvmtiEnv *jvmti, JNIEnv* jni, void* ptr) { + jvmtiError err; + + err = jvmti->Deallocate((unsigned char*)ptr); + check_jvmti_status(jni, err, "deallocate: error in JVMTI Deallocate call"); +} + +static char* +get_method_class_name(jvmtiEnv *jvmti, JNIEnv* jni, jmethodID method) { + jclass klass = NULL; + char* cname = NULL; + char* result = NULL; + jvmtiError err; + + err = jvmti->GetMethodDeclaringClass(method, &klass); + check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI GetMethodDeclaringClass"); + + err = jvmti->GetClassSignature(klass, &cname, NULL); + check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI GetClassSignature"); + + size_t len = strlen(cname) - 2; // get rid of leading 'L' and trailing ';' + + err = jvmti->Allocate((jlong)(len + 1), (unsigned char**)&result); + check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI Allocate"); + + strncpy(result, cname + 1, len); // skip leading 'L' + result[len] = '\0'; + deallocate(jvmti, jni, (void*)cname); + return result; +} + +static void +print_method(jvmtiEnv *jvmti, JNIEnv* jni, jmethodID method, jint depth) { + char* cname = NULL; + char* mname = NULL; + char* msign = NULL; + jvmtiError err; + + cname = get_method_class_name(jvmti, jni, method); + + err = jvmti->GetMethodName(method, &mname, &msign, NULL); + check_jvmti_status(jni, err, "print_method: error in JVMTI GetMethodName"); + + LOG("%2d: %s: %s%s\n", depth, cname, mname, msign); + fflush(0); + deallocate(jvmti, jni, (void*)cname); + deallocate(jvmti, jni, (void*)mname); + deallocate(jvmti, jni, (void*)msign); +} + +static char* +get_thread_name(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) { + jvmtiThreadInfo thr_info; + jvmtiError err; + + memset(&thr_info, 0, sizeof(thr_info)); + err = jvmti->GetThreadInfo(thread, &thr_info); + check_jvmti_status(jni, err, "get_thread_name: error in JVMTI GetThreadInfo call"); + + return thr_info.name == NULL ? (char*)"<Unnamed thread>" : thr_info.name; +} + +static void +print_stack_trace(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) { + jvmtiFrameInfo frames[MAX_FRAME_COUNT_PRINT_STACK_TRACE]; + char* tname = get_thread_name(jvmti, jni, thread); + jint count = 0; + jvmtiError err; + + err = jvmti->GetStackTrace(thread, 0, MAX_FRAME_COUNT_PRINT_STACK_TRACE, frames, &count); + check_jvmti_status(jni, err, "print_stack_trace: error in JVMTI GetStackTrace"); + + LOG("JVMTI Stack Trace for thread %s: frame count: %d\n", tname, count); + for (int depth = 0; depth < count; depth++) { + print_method(jvmti, jni, frames[depth].method, depth); + } + deallocate(jvmti, jni, (void*)tname); + LOG("\n"); +} +#endif // support for debug tracing + void printStateFlags(jint flags) { if (flags & JVMTI_THREAD_STATE_SUSPENDED) printf(" JVMTI_THREAD_STATE_SUSPENDED"); @@ -337,6 +438,9 @@ Java_nsk_jvmti_GetThreadState_thrstat002_checkStatus(JNIEnv *env, jclass cls, TranslateState(state[statInd]), state[statInd]); printf(" actual: %s (%d)\n", TranslateState(thrState), thrState); +#ifdef DBG + print_stack_trace(jvmti, env, thr_ptr); +#endif result = STATUS_FAILED; } if (suspState != JVMTI_THREAD_STATE_SUSPENDED) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack018.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack018.java index 48fe41a67faa5b6efc6b702e1e94e9ca9d99258f..b60309cc98f94e44dd88e98ba617399c381c5fc2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack018.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack018.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * invocations until stack overflow, and then tries to reproduce similar * stack overflows 10 times in each of 10 threads -- each time by trying * to invoke the same recursive method for the given fixed depth - * of invocations (which is 10 times that crucial depth just measured). + * of invocations (which is 100 times that crucial depth just measured). * The test is deemed passed, if VM have not crashed, and * if exception other than due to stack overflow was not * thrown. @@ -103,7 +103,7 @@ public class stack018 extends Thread { // Measure maximal recursion depth until stack overflow: // int maxDepth = 0; - for (depthToTry = 0; ; depthToTry += STEP) + for (depthToTry = 0; ; depthToTry += STEP) { try { invokeRecurse(depthToTry); maxDepth = depthToTry; @@ -117,6 +117,12 @@ public class stack018 extends Thread { throw (ThreadDeath) target; return 2; } + } + + if (maxDepth == 0) { + // The depth STEP was enough to cause StackOverflowError or OutOfMemoryError. + maxDepth = STEP; + } out.println("Maximal recursion depth: " + maxDepth); // diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 24519795f9ad884f5c1e249f461a8c1b70976a3b..6b54c726277cfa24685bd9f2be20ce08da22adb5 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -242,7 +242,6 @@ sun/awt/shell/ShellFolderMemoryLeak.java 8197794 windows-all sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java 8022403 generic-all sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java 8196102 generic-all sun/java2d/DirectX/RenderingToCachedGraphicsTest/RenderingToCachedGraphicsTest.java 8196180 windows-all,macosx-all -java/awt/Graphics2D/CopyAreaOOB.java 7001973 windows-all,macosx-all sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java 8144029 macosx-all,linux-all sun/java2d/SunGraphics2D/DrawImageBilinear.java 8191406 generic-all sun/java2d/SunGraphics2D/PolyVertTest.java 6986565 generic-all @@ -517,6 +516,7 @@ java/awt/KeyboardFocusmanager/TypeAhead/ButtonActionKeyTest/ButtonActionKeyTest. java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 java/awt/dnd/BadSerializationTest/BadSerializationTest.java 8277817 linux-x64,windows-x64 +java/awt/GraphicsDevice/CheckDisplayModes.java 8266242 macosx-aarch64 ############################################################################ @@ -606,6 +606,8 @@ java/nio/channels/DatagramChannel/Unref.java 8233519 generic- java/nio/channels/AsynchronousSocketChannel/StressLoopback.java 8211851 aix-ppc64 +java/nio/channels/DatagramChannel/ManySourcesAndTargets.java 8264385 macosx-aarch64 + ############################################################################ # jdk_rmi @@ -646,8 +648,6 @@ javax/net/ssl/DTLS/CipherSuite.java 8202059 macosx-x sun/security/provider/KeyStore/DKSTest.sh 8180266 windows-all -sun/security/pkcs11/KeyStore/SecretKeysBasic.java 8209398 generic-all - security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 8224768 generic-all sun/security/smartcardio/TestChannel.java 8039280 generic-all @@ -671,6 +671,7 @@ javax/security/auth/kerberos/KerberosTixDateTest.java 8039280 generic- sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.java 8039280 generic-all sun/security/provider/PolicyParser/ExtDirsChange.java 8039280 generic-all sun/security/provider/PolicyParser/PrincipalExpansionError.java 8039280 generic-all +sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java 8277970 linux-all,macosx-x64 ############################################################################ @@ -748,6 +749,7 @@ javax/swing/JMenu/4515762/bug4515762.java 8276074 macosx-all sanity/client/SwingSet/src/ToolTipDemoTest.java 8225012 windows-all,macosx-all sanity/client/SwingSet/src/ScrollPaneDemoTest.java 8225013 linux-all sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java 8265770 macosx-all +javax/swing/JTree/4908142/bug4908142.java 8278348 macosx-all ############################################################################ @@ -823,7 +825,8 @@ jdk/jfr/event/compiler/TestCodeSweeper.java 8225209 generic- jdk/jfr/event/os/TestThreadContextSwitches.java 8247776 windows-all jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64 jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64 -jdk/jfr/api/consumer/streaming/TestLatestEvent.java 8268297 windows-x64 +jdk/jfr/event/oldobject/TestLargeRootSet.java 8276333 generic-x64 +jdk/jfr/api/consumer/recordingstream/TestOnEvent.java 8255404 linux-x64 ############################################################################ diff --git a/test/jdk/TEST.ROOT b/test/jdk/TEST.ROOT index 03552d41c15eef5725e907fe865c692ab716be5b..608facdf4b787c9dd03fa59e51e5f829041480cd 100644 --- a/test/jdk/TEST.ROOT +++ b/test/jdk/TEST.ROOT @@ -25,9 +25,7 @@ javax/management sun/awt sun/java2d javax/xml/jaxp/testng/validation java/lang/P # Tests that cannot run concurrently exclusiveAccess.dirs=java/math/BigInteger/largeMemory \ java/rmi/Naming java/util/prefs sun/management/jmxremote \ -sun/tools/jstatd sun/tools/jcmd \ -sun/tools/jinfo sun/tools/jmap sun/tools/jps sun/tools/jstack sun/tools/jstat \ -com/sun/tools/attach sun/security/mscapi java/util/Arrays/largeMemory \ +sun/tools/jstatd sun/security/mscapi java/util/Arrays/largeMemory \ java/util/BitSet/stream javax/rmi java/net/httpclient/websocket \ com/sun/net/httpserver/simpleserver diff --git a/test/jdk/TEST.groups b/test/jdk/TEST.groups index 37dafa2e73a27b50b0a57f39510770e7cf398ada..6092f604640b346318f9aeb42706b6c03d9fd7a9 100644 --- a/test/jdk/TEST.groups +++ b/test/jdk/TEST.groups @@ -74,7 +74,9 @@ tier3 = \ :build \ :jdk_vector \ :jdk_rmi \ - :jdk_jfr_tier3 + :jdk_svc \ + -:jdk_svc_sanity \ + -:svc_tools # Everything not in other tiers tier4 = \ @@ -283,9 +285,6 @@ jdk_tools = \ jdk_jfr = \ jdk/jfr -jdk_jfr_tier3 = \ - jdk/jfr/event/metadata/TestLookForUntestedEvents.java - # # Catch-all for other areas with a small number of tests # @@ -386,16 +385,33 @@ jdk_editpad = \ jdk/editpad jdk_desktop = \ - :jdk_awt \ - :jdk_2d \ - :jdk_beans \ + :jdk_desktop_part1 \ + :jdk_desktop_part2 \ + :jdk_desktop_part3 + +jdk_desktop_part1 = \ + :jdk_client_sanity \ :jdk_swing \ + :jdk_2d \ :jdk_sound \ :jdk_imageio \ - :jdk_accessibility \ + :jdk_editpad \ :jfc_demo \ - :jdk_client_sanity \ - :jdk_editpad + :jdk_accessibility \ + :jdk_beans + +jdk_desktop_part2 = \ + :jdk_awt \ + -java/awt/Component \ + -java/awt/Modal \ + -java/awt/datatransfer \ + -java/awt/Window + +jdk_desktop_part3 = \ + java/awt/Component \ + java/awt/Modal \ + java/awt/datatransfer \ + java/awt/Window # SwingSet3 tests. jdk_client_sanity = \ @@ -518,7 +534,23 @@ needs_g1gc = \ jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java \ jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java \ jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventG1.java - + +# This set of tests will be executed in an ipv6 only environment + +jdk_ipv6_only = \ + :jdk_net \ + :jdk_nio_networkchannel + +jdk_nio_networkchannel = \ + java/nio/channels/AsyncCloseAndInterrupt.java \ + java/nio/channels/AsynchronousServerSocketChannel \ + java/nio/channels/AsynchronousSocketChannel \ + java/nio/channels/DatagramChannel \ + java/nio/channels/ServerSocketChannel \ + java/nio/channels/SocketChannel \ + java/nio/channels/Selector \ + java/nio/channels/etc + jdk_core_manual = \ :jdk_core_manual_no_input \ :jdk_core_manual_no_input_security \ @@ -567,3 +599,8 @@ jdk_core_manual_requires_human_input = \ java/util/TimeZone/DefaultTimeZoneTest.java +# Test sets for running inside container environment +jdk_containers_extended = \ + :jdk_io \ + :jdk_nio \ + :jdk_svc diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java index 2c0dcae280798a532ed42cfd16e57cb3c4980aea..dd414ad06daba3d0cd5692744eac34f3ead8c892 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java @@ -258,7 +258,7 @@ public class GCMBufferTest implements Cloneable { // If incrementalSegments is enabled, run through that test only if (incremental) { if (ops.size() < 2) { - throw new Exception("To do incrementalSegments you must" + + throw new Exception("To do incrementalSegments you must " + "have more that 1 dtype in the list"); } sizes = new int[ops.size()]; diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java index 3cfaed9bd9d2e24d2dec1f3c7532403e2cf90941..73140c5a6682d947fc03cb923923f38ce9041f31 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java @@ -57,7 +57,7 @@ public class GCMShortBuffer { int r = c.doFinal(cipherText, 1, len, pt, 0); if (r != pt.length) { System.out.println( - "doFinal() return ( " + r + ") is not the same" + + "doFinal() return ( " + r + ") is not the same " + "as getOutputSize returned" + pt.length); error = true; } diff --git a/test/jdk/com/sun/jdi/TestScaffold.java b/test/jdk/com/sun/jdi/TestScaffold.java index 18da0b4e9c75d26cb38577285b31eb94f61b0d8a..2d4885c90e7764315e29a8e59030630ef1bde2b9 100644 --- a/test/jdk/com/sun/jdi/TestScaffold.java +++ b/test/jdk/com/sun/jdi/TestScaffold.java @@ -535,16 +535,15 @@ abstract public class TestScaffold extends TargetAdapter { Location loc = ((Locatable)event).location(); ReferenceType rt = loc.declaringType(); String name = rt.name(); - if (name.startsWith("java.") && - !name.startsWith("sun.") && - !name.startsWith("com.")) { + if (name.startsWith("java.") + || name.startsWith("sun.") + || name.startsWith("com.") + || name.startsWith("jdk.")) { if (mainStartClass != null) { redefine(mainStartClass); } } else { - if (!name.startsWith("jdk.")) { - redefine(rt); - } + redefine(rt); } } } diff --git a/test/jdk/com/sun/jndi/ldap/LdapCBPropertiesTest.java b/test/jdk/com/sun/jndi/ldap/LdapCBPropertiesTest.java index 16b4400310a2d213a7433ec8442f214d5447c434..2f2ce50e8d6654d229c0ea56e44f8b31a80a9cc6 100644 --- a/test/jdk/com/sun/jndi/ldap/LdapCBPropertiesTest.java +++ b/test/jdk/com/sun/jndi/ldap/LdapCBPropertiesTest.java @@ -25,6 +25,7 @@ * @test * @bug 8245527 * @library lib/ /test/lib + * @modules java.base/sun.security.util * @run main/othervm LdapCBPropertiesTest true true com.sun.jndi.ldap.tls.cbtype tls-server-end-point * @run main/othervm LdapCBPropertiesTest false false com.sun.jndi.ldap.tls.cbtype tls-server-end-point * @run main/othervm LdapCBPropertiesTest true true com.sun.jndi.ldap.tls.cbtype tls-server-end-point com.sun.jndi.ldap.connect.timeout 2000 @@ -53,6 +54,8 @@ import javax.security.sasl.SaslException; import jdk.test.lib.net.URIBuilder; +import sun.security.util.ChannelBindingException; + public class LdapCBPropertiesTest { /* * Where do we find the keystores? @@ -187,7 +190,8 @@ public class LdapCBPropertiesTest { } } } - if (!shouldPass && ne.getRootCause() == null) { + Throwable rc = ne.getRootCause(); + if (!shouldPass && (rc == null || rc instanceof ChannelBindingException)) { // Expected exception caused by Channel Binding parameter inconsistency return true; } diff --git a/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7a5df545655b5b06588fd73de7f0238f0597be3b --- /dev/null +++ b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277795 + * @summary Multi-threaded client timeout tests for ldap pool + * @library /test/lib + * lib/ + * @run testng/othervm LdapPoolTimeoutTest + */ + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.IOException; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.InitialDirContext; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.TimeUnit; + +import static jdk.test.lib.Utils.adjustTimeout; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.expectThrows; + +public class LdapPoolTimeoutTest { + /* + * Practical representation of an infinite timeout. + */ + private static final long INFINITY_MILLIS = adjustTimeout(20_000); + /* + * The acceptable variation in timeout measurements. + */ + private static final long TOLERANCE = adjustTimeout( 3_500); + + private static final long CONNECT_MILLIS = adjustTimeout( 3_000); + private static final long READ_MILLIS = adjustTimeout(10_000); + + static { + // a series of checks to make sure this timeouts configuration is + // consistent and the timeouts do not overlap + + assert (TOLERANCE >= 0); + // context creation + assert (2 * CONNECT_MILLIS + TOLERANCE < READ_MILLIS); + // context creation immediately followed by search + assert (2 * CONNECT_MILLIS + READ_MILLIS + TOLERANCE < INFINITY_MILLIS); + } + + @Test + public void test() throws Exception { + List<Future<?>> futures = new ArrayList<>(); + ExecutorService executorService = Executors.newCachedThreadPool(); + + Hashtable<Object, Object> env = new Hashtable<>(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put("com.sun.jndi.ldap.read.timeout", String.valueOf(READ_MILLIS)); + env.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(CONNECT_MILLIS)); + env.put("com.sun.jndi.ldap.connect.pool", "true"); + env.put(Context.PROVIDER_URL, "ldap://example.com:1234"); + + try { + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + } finally { + executorService.shutdown(); + } + int failedCount = 0; + for (var f : futures) { + try { + f.get(); + } catch (ExecutionException e) { + failedCount++; + e.getCause().printStackTrace(System.out); + } + } + if (failedCount > 0) + throw new RuntimeException(failedCount + " (sub)tests failed"); + } + + private static void attemptConnect(Hashtable<Object, Object> env) throws Exception { + try { + LdapTimeoutTest.assertCompletion(CONNECT_MILLIS - 1000, + 2 * CONNECT_MILLIS + TOLERANCE, + () -> new InitialDirContext(env)); + } catch (RuntimeException e) { + String msg = e.getCause() == null ? e.getMessage() : e.getCause().getMessage(); + System.err.println("MSG RTE: " + msg); + // assertCompletion may wrap a CommunicationException in an RTE + assertTrue(msg != null && msg.contains("Network is unreachable")); + } catch (NamingException ex) { + String msg = ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage(); + System.err.println("MSG: " + msg); + assertTrue(msg != null && + (msg.contains("Network is unreachable") + || msg.contains("Timed out waiting for lock") + || msg.contains("Connect timed out") + || msg.contains("Timeout exceeded while waiting for a connection"))); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + +} + diff --git a/test/jdk/com/sun/net/httpserver/SANTest.java b/test/jdk/com/sun/net/httpserver/SANTest.java new file mode 100644 index 0000000000000000000000000000000000000000..db0fc0542d6f55758a164343a24faa60e18ac569 --- /dev/null +++ b/test/jdk/com/sun/net/httpserver/SANTest.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8278312 + * @library /test/lib /test/jdk/java/net/httpclient /test/jdk/java/net/httpclient/http2/server + * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters Http2Handler + * jdk.test.lib.net.IPSupport + * Http2TestExchange + * + * @modules java.net.http/jdk.internal.net.http.common + * java.net.http/jdk.internal.net.http.frame + * java.net.http/jdk.internal.net.http.hpack + * java.logging + * java.base/sun.net.www.http + * java.base/sun.net.www + * java.base/sun.net + * + * @run main/othervm SANTest + * @summary Update SimpleSSLContext keystore to use SANs for localhost IP addresses + */ + +import com.sun.net.httpserver.*; + +import java.util.concurrent.*; +import java.io.*; +import java.net.*; +import java.net.http.*; +import java.nio.charset.StandardCharsets; +import javax.net.ssl.*; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; +import jdk.test.lib.net.IPSupport; + +/* + * Will fail if the testkeys file belonging to SimpleSSLContext + * does not have SAN entries for 127.0.0.1 or ::1 + */ +public class SANTest implements HttpServerAdapters { + + static SSLContext ctx; + + static HttpServer getHttpsServer(InetSocketAddress addr, Executor exec, SSLContext ctx) throws Exception { + HttpsServer server = HttpsServer.create(addr, 0); + server.setExecutor(exec); + server.setHttpsConfigurator(new HttpsConfigurator (ctx)); + return server; + } + + static final boolean hasIPv4 = IPSupport.hasIPv4(); + static final boolean hasIPv6 = IPSupport.hasIPv6(); + + static HttpTestServer initServer(boolean h2, InetAddress addr, SSLContext ctx, + String sni, ExecutorService e) throws Exception { + HttpTestServer s = null; + InetSocketAddress ia = new InetSocketAddress (addr, 0); + if ((addr instanceof Inet4Address) && !hasIPv4) + return null; + if ((addr instanceof Inet6Address) && !hasIPv6) + return null; + + if (!h2) { + s = HttpTestServer.of(getHttpsServer(ia, e, ctx)); + HttpTestHandler h = new HttpTestEchoHandler(); + s.addHandler(h, "/test1"); + s.start(); + return s; + } else { + s = HttpTestServer.of(new Http2TestServer(addr, sni, true, 0, e, + 10, null, ctx, false)); + HttpTestHandler h = new HttpTestEchoHandler(); + s.addHandler(h, "/test1"); + s.start(); + return s; + } + } + + public static void main (String[] args) throws Exception { + // Http/1.1 servers + HttpTestServer h1s1 = null; + HttpTestServer h1s2 = null; + + // Http/2 servers + HttpTestServer h2s1 = null; + HttpTestServer h2s2 = null; + + ExecutorService executor=null; + try { + System.out.print ("SANTest: "); + ctx = new SimpleSSLContext().get(); + executor = Executors.newCachedThreadPool(); + + InetAddress l1 = InetAddress.getByName("::1"); + InetAddress l2 = InetAddress.getByName("127.0.0.1"); + + h1s1 = initServer(false, l1, ctx, "::1", executor); + h1s2 = initServer(false, l2, ctx, "127.0.0.1", executor); + + h2s1 = initServer(true, l1, ctx, "::1", executor); + h2s2 = initServer(true, l2, ctx, "127.0.0.1", executor); + + test("127.0.0.1", h1s2); + test("::1", h1s1); + testNew("127.0.0.1", h2s2, executor); + testNew("::1", h2s1, executor); + System.out.println ("OK"); + } finally { + if (h1s1 != null) + h1s1.stop(); + if (h1s2 != null) + h1s2.stop(); + if (h2s1 != null) + h2s1.stop(); + if (h2s2 != null) + h2s2.stop(); + if (executor != null) + executor.shutdown (); + } + } + + static void test (String host, HttpTestServer server) throws Exception { + if (server == null) + return; + int port = server.getAddress().getPort(); + String body = "Yellow world"; + URL url = URIBuilder.newBuilder() + .scheme("https") + .host(host) + .port(port) + .path("/test1/foo.txt") + .toURL(); + System.out.println("URL = " + url); + HttpURLConnection urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); + System.out.println("urlc = " + urlc); + if (urlc instanceof HttpsURLConnection) { + HttpsURLConnection urlcs = (HttpsURLConnection) urlc; + urlcs.setSSLSocketFactory (ctx.getSocketFactory()); + } + + urlc.setRequestMethod("POST"); + urlc.setDoOutput(true); + + OutputStream os = urlc.getOutputStream(); + os.write(body.getBytes(StandardCharsets.ISO_8859_1)); + os.close(); + InputStream is = urlc.getInputStream(); + byte[] vv = is.readAllBytes(); + String ff = new String(vv, StandardCharsets.ISO_8859_1); + System.out.println("resp = " + ff); + if (!ff.equals(body)) + throw new RuntimeException(); + is.close(); + } + + static void testNew (String host, HttpTestServer server, Executor exec) throws Exception { + if (server == null) + return; + int port = server.getAddress().getPort(); + String body = "Red and Yellow world"; + URI uri = URIBuilder.newBuilder() + .scheme("https") + .host(host) + .port(port) + .path("/test1/foo.txt") + .build(); + + HttpClient client = HttpClient.newBuilder() + .sslContext(ctx) + .executor(exec) + .build(); + HttpRequest req = HttpRequest.newBuilder(uri) + .version(HttpClient.Version.HTTP_2) + .POST(HttpRequest.BodyPublishers.ofString(body)) + .build(); + + HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString()); + System.out.println("resp = " + resp.body()); + if (!resp.body().equals(body)) + throw new RuntimeException(); + } +} diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/jwebserver/MaxRequestTimeTest.java b/test/jdk/com/sun/net/httpserver/simpleserver/jwebserver/MaxRequestTimeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e530c9805657ce54fdd855b1dd95e8c8491c4103 --- /dev/null +++ b/test/jdk/com/sun/net/httpserver/simpleserver/jwebserver/MaxRequestTimeTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8278398 + * @summary Tests the jwebserver's maximum request time + * @modules jdk.httpserver + * @library /test/lib + * @run testng/othervm MaxRequestTimeTest + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import jdk.test.lib.Platform; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.FileUtils; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; +import static java.lang.System.out; +import static java.net.http.HttpClient.Builder.NO_PROXY; +import static org.testng.Assert.*; + +/** + * This test confirms that the jwebserver does not wait indefinitely for + * a request to arrive. + * + * The jwebserver has a maximum request time of 5 seconds, which is set with the + * "sun.net.httpserver.maxReqTime" system property. If this threshold is + * reached, for example in the case of an HTTPS request where the server keeps + * waiting for a plaintext request, the server closes the connection. Subsequent + * requests are expected to be handled as normal. + * + * The test checks in the following order that: + * 1. an HTTP request is handled successfully, + * 2. an HTTPS request fails due to the server closing the connection + * 3. another HTTP request is handled successfully. + */ +public class MaxRequestTimeTest { + static final Path JAVA_HOME = Path.of(System.getProperty("java.home")); + static final String JWEBSERVER = getJwebserver(JAVA_HOME); + static final Path CWD = Path.of(".").toAbsolutePath().normalize(); + static final Path TEST_DIR = CWD.resolve("MaxRequestTimeTest"); + static final String LOOPBACK_ADDR = InetAddress.getLoopbackAddress().getHostAddress(); + static final AtomicInteger PORT = new AtomicInteger(); + + static SSLContext sslContext; + + @BeforeTest + public void setup() throws IOException { + if (Files.exists(TEST_DIR)) { + FileUtils.deleteFileTreeWithRetry(TEST_DIR); + } + Files.createDirectories(TEST_DIR); + + sslContext = new SimpleSSLContext().get(); + if (sslContext == null) + throw new AssertionError("Unexpected null sslContext"); + } + + @Test + public void testMaxRequestTime() throws Throwable { + final var sb = new StringBuffer(); // stdout & stderr + final var p = startProcess("jwebserver", sb); + try { + sendHTTPSRequest(); // server expected to terminate connection + sendHTTPRequest(); // server expected to respond successfully + sendHTTPSRequest(); // server expected to terminate connection + sendHTTPRequest(); // server expected to respond successfully + } finally { + p.destroy(); + int exitCode = p.waitFor(); + checkOutput(sb, exitCode); + } + } + + static String expectedBody = """ + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"/> + </head> + <body> + <h1>Directory listing for /</h1> + <ul> + </ul> + </body> + </html> + """; + + void sendHTTPRequest() throws IOException, InterruptedException { + out.println("\n--- sendHTTPRequest"); + var client = HttpClient.newBuilder() + .proxy(NO_PROXY) + .build(); + var request = HttpRequest.newBuilder(URI.create("http://localhost:" + PORT.get() + "/")).build(); + var response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assertEquals(response.body(), expectedBody); + } + + void sendHTTPSRequest() throws IOException, InterruptedException { + out.println("\n--- sendHTTPSRequest"); + var client = HttpClient.newBuilder() + .sslContext(sslContext) + .proxy(NO_PROXY) + .build(); + var request = HttpRequest.newBuilder(URI.create("https://localhost:" + PORT.get() + "/")).build(); + try { + client.send(request, HttpResponse.BodyHandlers.ofString()); + throw new RuntimeException("Expected SSLException not thrown"); + } catch (SSLException expected) { // server closes connection when max request time is reached + expected.printStackTrace(System.out); + } + } + + @AfterTest + public void teardown() throws IOException { + if (Files.exists(TEST_DIR)) { + FileUtils.deleteFileTreeWithRetry(TEST_DIR); + } + } + + // --- infra --- + + static String getJwebserver(Path image) { + boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + Path jwebserver = image.resolve("bin").resolve(isWindows ? "jwebserver.exe" : "jwebserver"); + if (Files.notExists(jwebserver)) + throw new RuntimeException(jwebserver + " not found"); + return jwebserver.toAbsolutePath().toString(); + } + + // The stdout/stderr output line to wait for when starting the jwebserver + static final String REGULAR_STARTUP_LINE_STRING_1 = "URL http://"; + static final String REGULAR_STARTUP_LINE_STRING_2 = "Serving "; + + static void parseAndSetPort(String line) { + PORT.set(Integer.parseInt(line.split(" port ")[1])); + } + + static Process startProcess(String name, StringBuffer sb) throws Throwable { + // starts the process, parses the port and awaits startup line before sending requests + return ProcessTools.startProcess(name, + new ProcessBuilder(JWEBSERVER, "-p", "0").directory(TEST_DIR.toFile()), + line -> { + if (line.startsWith(REGULAR_STARTUP_LINE_STRING_2)) { parseAndSetPort(line); } + sb.append(line + "\n"); + }, + line -> line.startsWith(REGULAR_STARTUP_LINE_STRING_1), + 30, // suitably high default timeout, not expected to timeout + TimeUnit.SECONDS); + } + + static final int SIGTERM = 15; + static final int NORMAL_EXIT_CODE = normalExitCode(); + + static int normalExitCode() { + if (Platform.isWindows()) { + return 1; // expected process destroy exit code + } else { + // signal terminated exit code on Unix is 128 + signal value + return 128 + SIGTERM; + } + } + + static void checkOutput(StringBuffer sb, int exitCode) { + out.println("\n--- server output: \n" + sb); + var outputAnalyser = new OutputAnalyzer(sb.toString(), "", exitCode); + outputAnalyser.shouldHaveExitValue(NORMAL_EXIT_CODE) + .shouldContain("Binding to loopback by default. For all interfaces use \"-b 0.0.0.0\" or \"-b ::\".") + .shouldContain("Serving " + TEST_DIR + " and subdirectories on " + LOOPBACK_ADDR + " port " + PORT) + .shouldContain("URL http://" + LOOPBACK_ADDR); + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java b/test/jdk/java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java index 4b835b11063e59b34247d43c9588cf0651460c07..84e5b4d62e45b639da2d97db179a9ba90b8ba935 100644 --- a/test/jdk/java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java +++ b/test/jdk/java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,7 +131,7 @@ public class ChoiceKeyEventReaction if (toolkit.equals("sun.awt.X11.XToolkit") && keyTypedOnTextField) { - throw new RuntimeException("Test failed. (XToolkit/MToolkit). KeyEvent was addressed to TextField."); + throw new RuntimeException("Test failed. (XToolkit). KeyEvent was addressed to TextField."); } System.out.println("Test passed. Unfocusable Choice doesn't react on keys."); diff --git a/test/jdk/java/awt/ColorClass/AlphaColorTest.java b/test/jdk/java/awt/ColorClass/AlphaColorTest.java index e3478c961fc02fca6d2a65e864cebe443c14d3ee..62d5ca4da327e4d01876e829bd40a092e60e6f0c 100644 --- a/test/jdk/java/awt/ColorClass/AlphaColorTest.java +++ b/test/jdk/java/awt/ColorClass/AlphaColorTest.java @@ -24,7 +24,7 @@ /** * @test * @key headful - * @bug 8204931 8227392 8224825 8233910 + * @bug 8204931 8227392 8224825 8233910 8275843 * @summary test alpha colors are blended with background. */ diff --git a/test/jdk/java/awt/ColorClass/XRenderTranslucentColorDrawTest.java b/test/jdk/java/awt/ColorClass/XRenderTranslucentColorDrawTest.java index 7754c4125cb71b3e12ea042f03b87df920643277..eab4a91308d5568a5ad716febfecdfa3f8fcb069 100644 --- a/test/jdk/java/awt/ColorClass/XRenderTranslucentColorDrawTest.java +++ b/test/jdk/java/awt/ColorClass/XRenderTranslucentColorDrawTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,14 +21,15 @@ * questions. */ + /* * @test * @key headful - * @bug 8176795 + * @bug 8176795 8275843 * @summary Test verifies that we get proper color when we draw translucent * color over an opaque color using X Render extension in Linux. - * @requires (os.family == "linux") - * @run main XRenderTranslucentColorDrawTest -Dsun.java2d.xrender=true + * @run main/othervm XRenderTranslucentColorDrawTest + * @run main/othervm -Dsun.java2d.xrender=true XRenderTranslucentColorDrawTest */ import java.awt.Color; @@ -36,30 +37,28 @@ import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Transparency; import java.awt.image.BufferedImage; import java.awt.image.VolatileImage; public class XRenderTranslucentColorDrawTest { - public static void main(String[] args) throws Exception { - GraphicsEnvironment env = GraphicsEnvironment. - getLocalGraphicsEnvironment(); - GraphicsConfiguration translucentGC = null; - SCREENS: for (GraphicsDevice screen : env.getScreenDevices()) { + public static void main(String[] args) { + var env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + for (GraphicsDevice screen : env.getScreenDevices()) { for (GraphicsConfiguration gc : screen.getConfigurations()) { - if (gc.isTranslucencyCapable()) { - translucentGC = gc; - break SCREENS; - } + test(gc, Transparency.OPAQUE); + test(gc, Transparency.BITMASK); + test(gc, Transparency.TRANSLUCENT); } } - if (translucentGC == null) { - throw new RuntimeException("No suitable gc found."); - } + } + + private static void test(GraphicsConfiguration gc, int transparency) { int width = 10; int height = 10; - VolatileImage image = translucentGC. - createCompatibleVolatileImage(width, height); + VolatileImage image = gc.createCompatibleVolatileImage(width, height, + transparency); Graphics2D g = image.createGraphics(); // draw opaque black color g.setColor(new Color(0xff000000, true)); @@ -72,10 +71,10 @@ public class XRenderTranslucentColorDrawTest { BufferedImage snapshot = image.getSnapshot(); int argb = snapshot.getRGB(width / 2, height / 2); // we expect the resultant rgb hex value to be ff808080 - if (!(Integer.toHexString(argb).equals("ff808080"))) { - throw new RuntimeException("Using X Render extension for drawing" - + " translucent color is not giving expected results."); + String actual = Integer.toHexString(argb); + if (!(actual.equals("ff808080"))) { + throw new RuntimeException("Drawing translucent color is not " + + "giving expected results: " + actual); } } -} - +} \ No newline at end of file diff --git a/test/jdk/java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.java b/test/jdk/java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.java index a87b59a9388faa644adf15d2fd3f8550e7d0523a..1e5b27892087c9268e7440b7997365c08c9c0d63 100644 --- a/test/jdk/java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.java +++ b/test/jdk/java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,11 +69,6 @@ public class ActualFocusedWindowBlockingTest { } public void start() { - if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { - System.out.println("No testing on Motif. Test passed."); - return; - } - System.out.println("\nTest started:\n"); // Test 1. diff --git a/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java b/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java index 0a7a1afff619d3e7e952bb025faeb57f879531b3..45914e0670bba2e3c3977aaafc2489fb913daf6c 100644 --- a/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java +++ b/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -293,43 +293,39 @@ public class AutoRequestFocusSetVisibleTest { // 6. Show unblocking modal Dialog. /////////////////////////////////// - if ("sun.awt.motif.MToolkit".equals(toolkitClassName)) { - System.out.println("Stage 6 - Skiping."); - } else { - System.out.println("Stage 6 in progress..."); + System.out.println("Stage 6 in progress..."); - // --- - // Testing the bug of activating invisible modal Dialog (awt_Window::SetAndActivateModalBlocker). - // Having some window not excluded from modality, so that it would be blocked. - Frame f = new Frame("Aux. Frame"); - f.setSize(100, 100); - setVisible(f, true); - // --- + // --- + // Testing the bug of activating invisible modal Dialog (awt_Window::SetAndActivateModalBlocker). + // Having some window not excluded from modality, so that it would be blocked. + Frame f = new Frame("Aux. Frame"); + f.setSize(100, 100); + setVisible(f, true); + // --- - setVisible(focusedFrame, true); + setVisible(focusedFrame, true); + if (!focusOwner.hasFocus()) { + Util.clickOnComp(focusOwner, robot); + Util.waitForIdle(robot); if (!focusOwner.hasFocus()) { - Util.clickOnComp(focusOwner, robot); - Util.waitForIdle(robot); - if (!focusOwner.hasFocus()) { - throw new Error("Test error: the frame couldn't be focused."); - } + throw new Error("Test error: the frame couldn't be focused."); } + } - dialog.setModal(true); - dialog.setAutoRequestFocus(false); - focusedFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); + dialog.setModal(true); + dialog.setAutoRequestFocus(false); + focusedFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); - TestHelper.invokeLaterAndWait(new Runnable() { - public void run() { - dialog.setVisible(true); - } - }, robot); + TestHelper.invokeLaterAndWait(new Runnable() { + public void run() { + dialog.setVisible(true); + } + }, robot); - if (dialog.isFocused()) { - throw new TestFailedException("the unblocking dialog shouldn't gain focus but it did!"); - } - setVisible(dialog, false); + if (dialog.isFocused()) { + throw new TestFailedException("the unblocking dialog shouldn't gain focus but it did!"); } + setVisible(dialog, false); System.out.println("Test passed."); } diff --git a/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java b/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java index 8ca4d4d6f7b1112d794331a646a548e83189ba2c..b1b8b8458ff0885db76bd56df844e86a87453cd5 100644 --- a/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java +++ b/test/jdk/java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -202,26 +202,22 @@ public class AutoRequestFocusToFrontTest { // Focused frame is excluded from modality. //////////////////////////////////////////////// - if (!"sun.awt.motif.MToolkit".equals(toolkitClassName)) { - recreateGUI(); - auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); + recreateGUI(); + auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); - Test.setWindows(modalDialog, modalDialog, new Window[] {modalDialog, frame3}); - Test.test("Test stage 6.1 in progress", modalDlgButton); - } + Test.setWindows(modalDialog, modalDialog, new Window[] {modalDialog, frame3}); + Test.test("Test stage 6.1 in progress", modalDlgButton); // 6.2. Owner Frame (with owned modal Dialog). // Focused frame is excluded from modality. //////////////////////////////////////////////// - if (!"sun.awt.motif.MToolkit".equals(toolkitClassName)) { - recreateGUI(); - auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); + recreateGUI(); + auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); - Test.setWindows(frame3, modalDialog, new Window[] {modalDialog, frame3}); - Test.test("Test stage 6.2 in progress", modalDlgButton, true); - } + Test.setWindows(frame3, modalDialog, new Window[] {modalDialog, frame3}); + Test.test("Test stage 6.2 in progress", modalDlgButton, true); /////////////////////////////////////////////////// // 7. Calling setVisible(true) for the shown Frame. @@ -422,4 +418,3 @@ class TestFailedException extends RuntimeException { super("Test failed: " + msg); } } - diff --git a/test/jdk/java/awt/Focus/ModalBlockedStealsFocusTest/ModalBlockedStealsFocusTest.java b/test/jdk/java/awt/Focus/ModalBlockedStealsFocusTest/ModalBlockedStealsFocusTest.java index 9a0d476133badf25515c8a9056fd1a615e5f9914..27be25773f2b382e688a0174b31ee8ec26979b69 100644 --- a/test/jdk/java/awt/Focus/ModalBlockedStealsFocusTest/ModalBlockedStealsFocusTest.java +++ b/test/jdk/java/awt/Focus/ModalBlockedStealsFocusTest/ModalBlockedStealsFocusTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,11 +47,6 @@ public class ModalBlockedStealsFocusTest { } public void start() { - if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { - System.out.println("The test is not for MToolkit."); - return; - } - dialog.setBounds(800, 0, 200, 100); frame.setBounds(800, 150, 200, 100); diff --git a/test/jdk/java/awt/Focus/ModalExcludedWindowClickTest/ModalExcludedWindowClickTest.java b/test/jdk/java/awt/Focus/ModalExcludedWindowClickTest/ModalExcludedWindowClickTest.java index 0ee37cbce69f10abd136156af4c7f7ffc3c6236a..7cfe66834bc4a826deef50935c8be22fbe4f2eb0 100644 --- a/test/jdk/java/awt/Focus/ModalExcludedWindowClickTest/ModalExcludedWindowClickTest.java +++ b/test/jdk/java/awt/Focus/ModalExcludedWindowClickTest/ModalExcludedWindowClickTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,12 +57,6 @@ public class ModalExcludedWindowClickTest { } public void start() { - - if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { - System.out.println("No testing on MToolkit."); - return; - } - button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { actionPerformed = true; diff --git a/test/jdk/java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java b/test/jdk/java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java index b6d4c962efa4d32f42cc44bafb4ec995f3d70f09..abf8d57cecdbcebaf745fe952b9d0df0ee5ad186 100644 --- a/test/jdk/java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java +++ b/test/jdk/java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,12 +56,6 @@ public class NonFocusableBlockedOwnerTest { } public void start() { - - if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { - System.out.println("No testing on MToolkit."); - return; - } - try { EventQueue.invokeLater(new Runnable() { public void run() { diff --git a/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java b/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java index a63d8194714fa46040d93741ddfa55a802382940..212d5274a8910ee51cf7f118156abb09029d0568 100644 --- a/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java +++ b/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,12 +47,6 @@ public class SimpleWindowActivationTest { private static Robot robot; public static void main(String[] args) throws Exception { - - if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { - System.out.println("No testing on Motif. Test passed."); - return; - } - robot = new Robot(); robot.setAutoDelay(50); diff --git a/test/jdk/java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java b/test/jdk/java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java index 962f6b4665cdf55f4f8709c0ba6f3fdf567d3551..6a6cfc9393926aff6934a7b43c06d13bac1e29aa 100644 --- a/test/jdk/java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java +++ b/test/jdk/java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,11 +63,6 @@ public class WindowUpdateFocusabilityTest { } public void start() { - if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { - System.out.println("No testing on Motif."); - return; - } - test(new Frame("Frame owner")); Frame dialog_owner = new Frame("dialog's owner"); test(new Dialog(dialog_owner)); diff --git a/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java b/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java index d4f9533f09680af0411f14119c4cc5242926313f..8d218d9f18919d8e3f812b63ff79261b85056f9a 100644 --- a/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java +++ b/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,15 +36,9 @@ import java.awt.image.*; public class CopyAreaOOB extends Canvas { - private static boolean done; + private static Robot robot = null; public void paint(Graphics g) { - synchronized (this) { - if (done) { - return; - } - } - int w = getWidth(); int h = getHeight(); @@ -64,10 +58,23 @@ public class CopyAreaOOB extends Canvas { Toolkit.getDefaultToolkit().sync(); - synchronized (this) { - done = true; - notifyAll(); + BufferedImage capture = null; + try { + Thread.sleep(500); + if (robot == null) robot = new Robot(); + Point pt1 = getLocationOnScreen(); + Rectangle rect = new Rectangle(pt1.x, pt1.y, 400, 400); + capture = robot.createScreenCapture(rect); + } catch (Exception e) { + throw new RuntimeException("Problems handling Robot"); } + // Test pixels + testRegion(capture, "green", 0, 0, 400, 10, 0xff00ff00); + testRegion(capture, "original red", 0, 10, 50, 400, 0xffff0000); + testRegion(capture, "background", 50, 10, 60, 400, 0xff000000); + testRegion(capture, "in-between", 60, 10, 110, 20, 0xff000000); + testRegion(capture, "copied red", 60, 20, 110, 400, 0xffff0000); + testRegion(capture, "background", 110, 10, 400, 400, 0xff000000); } public Dimension getPreferredSize() { @@ -105,42 +112,11 @@ public class CopyAreaOOB extends Canvas { frame.setLocationRelativeTo(null); frame.setVisible(true); - // Wait until the component's been painted - synchronized (test) { - while (!done) { - try { - test.wait(); - } catch (InterruptedException e) { - throw new RuntimeException("Failed: Interrupted"); - } - } - } - try { - Thread.sleep(2000); + Thread.sleep(3000); } catch (InterruptedException ex) {} - - // Grab the screen region - BufferedImage capture = null; - try { - Robot robot = new Robot(); - Point pt1 = test.getLocationOnScreen(); - Rectangle rect = new Rectangle(pt1.x, pt1.y, 400, 400); - capture = robot.createScreenCapture(rect); - } catch (Exception e) { - throw new RuntimeException("Problems creating Robot"); - } finally { - if (!show) { - frame.dispose(); - } + if (!show) { + frame.dispose(); } - - // Test pixels - testRegion(capture, "green", 0, 0, 400, 10, 0xff00ff00); - testRegion(capture, "original red", 0, 10, 50, 400, 0xffff0000); - testRegion(capture, "background", 50, 10, 60, 400, 0xff000000); - testRegion(capture, "in-between", 60, 10, 110, 20, 0xff000000); - testRegion(capture, "copied red", 60, 20, 110, 400, 0xffff0000); - testRegion(capture, "background", 110, 10, 400, 400, 0xff000000); } } diff --git a/test/jdk/java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java b/test/jdk/java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java index 29b90c9d4302dd2d22c57c2637b3c0efbe881cd2..3f8eeb17b38f68c9cdc1673019a2487993c9af6e 100644 --- a/test/jdk/java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java +++ b/test/jdk/java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,7 +105,7 @@ public class ExtraButtonDrag extends Frame { //XToolkit: extra buttons should report MOVED events only //WToolkit: extra buttons should report DRAGGED events only if (i > 2){ //extra buttons only - if (tk.equals("sun.awt.X11.XToolkit") || tk.equals("sun.awt.motif.MToolkit")) { + if (tk.equals("sun.awt.X11.XToolkit")) { if (!moved || dragged) { throw new RuntimeException("Test failed."+ tk +" Button = " +(i+1) + " moved = "+moved +" : dragged = " +dragged); } @@ -152,4 +152,3 @@ public class ExtraButtonDrag extends Frame { } } - diff --git a/test/jdk/java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java b/test/jdk/java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java index 3ab3ba3ff877ec30044fbb9bc74a83261772ba8e..ee83a328f0fc2aad8ec5aaa46dc16736517e2846 100644 --- a/test/jdk/java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java +++ b/test/jdk/java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ public class AcceptExtraMouseButtons extends Frame { //MouseInfo.getNumberOfButtons() reports two more buttons on XToolkit //as they reserved for wheel (both directions). - if (tk.equals("sun.awt.X11.XToolkit") || tk.equals("sun.awt.motif.MToolkit")) { + if (tk.equals("sun.awt.X11.XToolkit")) { buttonsNum = buttonsNum - 2; } System.out.println("Number Of Buttons = "+ buttonsNum); diff --git a/test/jdk/java/awt/Scrollbar/AquaLFScrollbarTest/ScrollBarBorderTest.java b/test/jdk/java/awt/Scrollbar/AquaLFScrollbarTest/ScrollBarBorderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9fbea551b832fee9758ff768bc1ec8df52724f02 --- /dev/null +++ b/test/jdk/java/awt/Scrollbar/AquaLFScrollbarTest/ScrollBarBorderTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.JScrollBar; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.border.Border; + +import static java.awt.image.BufferedImage.TYPE_INT_ARGB; + +/* + * @test + * @bug 8190264 + * @summary JScrollBar ignores its border when using macOS Mac OS X Aqua look and feel + * @run main ScrollBarBorderTest + */ +public class ScrollBarBorderTest { + private static JScrollBar scrollBar; + public static final int BORDER_WIDTH = 150; + public static final int WIDTH = BORDER_WIDTH + 200; + public static final int HEIGHT = 20; + + public static void main(String[] args) throws Exception { + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf)); + SwingUtilities.invokeAndWait(ScrollBarBorderTest::testHorizontal); + SwingUtilities.invokeAndWait(ScrollBarBorderTest::testVertical); + } + } + + public static void testHorizontal() { + // create scroll bar + scrollBar = new JScrollBar(JScrollBar.HORIZONTAL); + scrollBar.setSize(WIDTH, HEIGHT); + scrollBar.setBorder(new HorizontalCustomBorder()); + + // paint image with thumb set to default value + BufferedImage image1 = new BufferedImage(WIDTH, HEIGHT, TYPE_INT_ARGB); + Graphics2D graphics2D = image1.createGraphics(); + scrollBar.paint(graphics2D); + graphics2D.dispose(); + + // paint image with thumb set to max value + scrollBar.setValue(Integer.MAX_VALUE); + BufferedImage image2 = new BufferedImage(WIDTH, HEIGHT, TYPE_INT_ARGB); + Graphics2D graphics2D2 = image2.createGraphics(); + scrollBar.paint(graphics2D2); + graphics2D2.dispose(); + + // check border for thumb + for (int x = WIDTH - BORDER_WIDTH; x < WIDTH; x++) { + for (int y = 0; y < HEIGHT; y++) { + int c1 = image1.getRGB(x, y); + int c2 = image2.getRGB(x, y); + if (c1 != c2) { + System.out.println(x + " " + y + " " + "Color1: " + + Integer.toHexString(c1)); + System.out.println(x + " " + y + " " + "Color2: " + + Integer.toHexString(c2)); + saveImage(image1, "himage1.png"); + saveImage(image2, "himage2.png"); + throw new RuntimeException("Horizontal border has a thumb in it"); + } + } + } + } + + public static void testVertical() { + // create scroll bar + scrollBar = new JScrollBar(JScrollBar.VERTICAL); + scrollBar.setSize(HEIGHT, WIDTH); + scrollBar.setBorder(new VerticalCustomBorder()); + + // paint image with thumb set to 0 + scrollBar.setValue(0); + BufferedImage image1 = new BufferedImage(HEIGHT, WIDTH, TYPE_INT_ARGB); + Graphics2D graphics2D = image1.createGraphics(); + scrollBar.paint(graphics2D); + graphics2D.dispose(); + + // paint image with thumb set to max value + scrollBar.setValue(Integer.MAX_VALUE); + BufferedImage image2 = new BufferedImage(HEIGHT, WIDTH, TYPE_INT_ARGB); + Graphics2D graphics2D2 = image2.createGraphics(); + scrollBar.paint(graphics2D2); + graphics2D2.dispose(); + + // check border for thumb + for (int y = WIDTH - BORDER_WIDTH; y < WIDTH; y++) { + for (int x = 0; x < HEIGHT; x++) { + int c1 = image1.getRGB(x, y); + int c2 = image2.getRGB(x, y); + if (c1 != c2) { + System.out.println(x + " " + y + " " + "Color1: " + + Integer.toHexString(c1)); + System.out.println(x + " " + y + " " + "Color2: " + + Integer.toHexString(c2)); + saveImage(image1, "vimage1.png"); + saveImage(image2, "vimage2.png"); + throw new RuntimeException("Vertical border has a thumb in it"); + } + } + } + } + + private static void setLookAndFeel(UIManager.LookAndFeelInfo laf) { + try { + UIManager.setLookAndFeel(laf.getClassName()); + System.out.println(laf.getName()); + } catch (UnsupportedLookAndFeelException ignored){ + System.out.println("Unsupported LookAndFeel: " + laf.getClassName()); + } catch (ClassNotFoundException | InstantiationException | + IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static void saveImage(BufferedImage image, String filename) { + try { + ImageIO.write(image, "png", new File(filename)); + } catch (IOException e) { + // Don't propagate the exception + e.printStackTrace(); + } + } + + // custom border + private static class HorizontalCustomBorder implements Border { + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + g.setColor(new Color(255, 0, 0, 100)); + g.fillRect(width - BORDER_WIDTH, y, width, height); + } + + @Override + public Insets getBorderInsets(Component c) { + return new Insets(0, 0, 0, BORDER_WIDTH); + } + + @Override + public boolean isBorderOpaque() { + return true; + } + } + + // custom border + private static class VerticalCustomBorder implements Border { + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + g.setColor(new Color(255, 0, 0, 100)); + g.fillRect(x, height - BORDER_WIDTH, width, height); + } + + @Override + public Insets getBorderInsets(Component c) { + return new Insets(0, 0, BORDER_WIDTH, 0); + } + + @Override + public boolean isBorderOpaque() { + return true; + } + } +} diff --git a/test/jdk/java/awt/Window/GrabSequence/GrabSequence.java b/test/jdk/java/awt/Window/GrabSequence/GrabSequence.java index 686cae28010639243386695df2aa55136f25bc36..da419e10ef1d5c7ab2ba4cf6a54cc5ccffcc2170 100644 --- a/test/jdk/java/awt/Window/GrabSequence/GrabSequence.java +++ b/test/jdk/java/awt/Window/GrabSequence/GrabSequence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,11 +40,6 @@ public class GrabSequence { private static void init() { - String toolkit = Toolkit.getDefaultToolkit().getClass().getName(); - if ( toolkit.equals("sun.awt.motif.MToolkit")){ - System.out.println("This test is for XToolkit and WToolkit only. Now using " + toolkit + ". Automatically passed."); - return; - } Frame frame = new Frame("Frame"); frame.setBackground(Color.green); frame.setForeground(Color.green); diff --git a/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.form b/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.form index 4291e0eeaac0f55d3bc8da1c10531ab47e5c8c6b..6735391ad3810cd16aaaa7ef4323929416f86545 100644 --- a/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.form +++ b/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.form @@ -158,7 +158,7 @@ <Properties> <Property name="columns" type="int" value="20"/> <Property name="rows" type="int" value="5"/> - <Property name="text" type="java.lang.String" value="Create translucent and/or shaped, or non-opaque frame. Make sure it behaves correctly (no artifacts left on the screen when dragging - if dragging is possible). Click "Passed" if the test behaves correctly, "Falied" otherwise."/> + <Property name="text" type="java.lang.String" value="Create translucent and/or shaped, or non-opaque frame. Make sure it behaves correctly (no artifacts left on the screen when dragging - if dragging is possible). Click "Passed" if the test behaves correctly, "Failed" otherwise."/> </Properties> </Component> </SubComponents> diff --git a/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java b/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java index bdcf99c3a3c0dcd26927284bd676c3bd16a8a555..b87c44d907859dc8fea727ea7f2ef06c1b9c0118 100644 --- a/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java +++ b/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,7 +122,7 @@ public class TranslucentShapedFrameTest extends javax.swing.JFrame { jTextArea1.setColumns(20); jTextArea1.setRows(5); - jTextArea1.setText("Create translucent and/or shaped, or\nnon-opaque frame. Make sure it behaves\ncorrectly (no artifacts left on the screen\nwhen dragging - if dragging is possible).\nClick \"Passed\" if the test behaves correctly,\n\"Falied\" otherwise."); + jTextArea1.setText("Create translucent and/or shaped, or\nnon-opaque frame. Make sure it behaves\ncorrectly (no artifacts left on the screen\nwhen dragging - if dragging is possible).\nClick \"Passed\" if the test behaves correctly,\n\"Failed\" otherwise."); jScrollPane1.setViewportView(jTextArea1); jLabel2.setText("Instructions:"); diff --git a/test/jdk/java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java b/test/jdk/java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java index 3a7ea0c59951ca01a5f1cf6a2ad2692c3a873abb..7dba15b5a1f56469604725e2227ff29ea1e048e2 100644 --- a/test/jdk/java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java +++ b/test/jdk/java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java @@ -25,7 +25,7 @@ /* @test @key headful - @bug 4718897 + @bug 4718897 8278908 @summary tests that a Unicode string can be transferred between JVMs. @author das@sparc.spb.su area=datatransfer @library ../../regtesthelpers/process @@ -35,7 +35,6 @@ import java.awt.datatransfer.*; import java.awt.*; -import java.text.Normalizer; import test.java.awt.regtesthelpers.process.ProcessResults; import test.java.awt.regtesthelpers.process.ProcessCommunicator; @@ -77,10 +76,7 @@ class Util { buf.append(0x20); } } - // On OS X the unicode string is normalized but the clipboard, - // so we need to use normalized strings as well to be able to - // check the result - testString = Normalizer.normalize(buf.toString(), Normalizer.Form.NFC); + testString = buf.toString(); } public static String getTestString() { diff --git a/test/jdk/java/awt/event/HierarchyEvent/AncestorResized/AncestorResized.java b/test/jdk/java/awt/event/HierarchyEvent/AncestorResized/AncestorResized.java index dafa0ead939f69d5d27b254f1d81d1c9be207d8c..156f3f75db5ed74e83b08b0cc51b40230d920859 100644 --- a/test/jdk/java/awt/event/HierarchyEvent/AncestorResized/AncestorResized.java +++ b/test/jdk/java/awt/event/HierarchyEvent/AncestorResized/AncestorResized.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,37 +21,30 @@ * questions. */ -/* - @test - @key headful - @bug 6533330 - @summary ANCESTOR_RESIZED is not sent while resizing a frame. Regression caused by 6500477. - @author anthony.petrov: area=awt.toplevel - @library ../../../regtesthelpers - @build Util - @run main AncestorResized -*/ - +import java.awt.Button; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.HierarchyBoundsListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.InputEvent; /** - * AncestorResized.java - * - * summary: After fixing the 6500477, the ANCESTOR_RESIZED event stoped - * firing while resizing a frame. This was a regression. - * The test checks whether the event starts dispatching as it - * was before fixing the 6500477. + * @test + * @key headful + * @bug 6533330 + * @summary ANCESTOR_RESIZED is not sent while resizing a frame. Regression + * caused by 6500477. */ +public class AncestorResized { -import java.awt.*; -import java.awt.event.*; -import test.java.awt.regtesthelpers.Util; - - -public class AncestorResized -{ public static volatile int ancestorResizedCounter = 0; - static class HierarchyBoundsListenerImpl implements HierarchyBoundsListener { public void ancestorMoved(HierarchyEvent ce) { // ANCESTOR_MOVED seems to work OK. @@ -61,8 +54,7 @@ public class AncestorResized } } - private static void init() - { + public static void main(String[] args) throws Exception { Frame frame; Panel panel; Button button; @@ -83,17 +75,17 @@ public class AncestorResized frame.setSize(300, 300); frame.setVisible(true); - Robot robot = Util.createRobot(); - robot.setAutoDelay(20); + Robot robot = new Robot(); + robot.setAutoDelay(50); // To ensure the window is shown and packed - Util.waitForIdle(robot); + robot.waitForIdle(); Insets insets = frame.getInsets(); if (insets.right == 0 || insets.bottom == 0) { + frame.dispose(); // Because we want to catch the "size-grip" of the frame. System.out.println("The test environment must have non-zero right & bottom insets! The current insets are: " + insets); - pass(); return; } @@ -112,177 +104,12 @@ public class AncestorResized // ... and start resizing robot.mousePress( InputEvent.BUTTON1_MASK ); robot.mouseMove(bounds.x + bounds.width + 20, bounds.y + bounds.height + 15); - Util.waitForIdle(robot); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + frame.dispose(); if (ancestorResizedCounter == 0) { - robot.mouseRelease( InputEvent.BUTTON1_MASK ); - AncestorResized.fail("No ANCESTOR_RESIZED events received."); - return; - } - - robot.mouseRelease( InputEvent.BUTTON1_MASK ); - - AncestorResized.pass(); - }//End init() - - - - /***************************************************** - * Standard Test Machinery Section - * DO NOT modify anything in this section -- it's a - * standard chunk of code which has all of the - * synchronisation necessary for the test harness. - * By keeping it the same in all tests, it is easier - * to read and understand someone else's test, as - * well as insuring that all tests behave correctly - * with the test harness. - * There is a section following this for test- - * classes - ******************************************************/ - private static boolean theTestPassed = false; - private static boolean testGeneratedInterrupt = false; - private static String failureMessage = ""; - - private static Thread mainThread = null; - - private static int sleepTime = 300000; - - // Not sure about what happens if multiple of this test are - // instantiated in the same VM. Being static (and using - // static vars), it aint gonna work. Not worrying about - // it for now. - public static void main( String args[] ) throws InterruptedException - { - mainThread = Thread.currentThread(); - try - { - init(); - } - catch( TestPassedException e ) - { - //The test passed, so just return from main and harness will - // interepret this return as a pass - return; + throw new RuntimeException("No ANCESTOR_RESIZED events received."); } - //At this point, neither test pass nor test fail has been - // called -- either would have thrown an exception and ended the - // test, so we know we have multiple threads. - - //Test involves other threads, so sleep and wait for them to - // called pass() or fail() - try - { - Thread.sleep( sleepTime ); - //Timed out, so fail the test - throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); - } - catch (InterruptedException e) - { - //The test harness may have interrupted the test. If so, rethrow the exception - // so that the harness gets it and deals with it. - if( ! testGeneratedInterrupt ) throw e; - - //reset flag in case hit this code more than once for some reason (just safety) - testGeneratedInterrupt = false; - - if ( theTestPassed == false ) - { - throw new RuntimeException( failureMessage ); - } - } - - }//main - - public static synchronized void setTimeoutTo( int seconds ) - { - sleepTime = seconds * 1000; - } - - public static synchronized void pass() - { - System.out.println( "The test passed." ); - System.out.println( "The test is over, hit Ctl-C to stop Java VM" ); - //first check if this is executing in main thread - if ( mainThread == Thread.currentThread() ) - { - //Still in the main thread, so set the flag just for kicks, - // and throw a test passed exception which will be caught - // and end the test. - theTestPassed = true; - throw new TestPassedException(); - } - theTestPassed = true; - testGeneratedInterrupt = true; - mainThread.interrupt(); - }//pass() - - public static synchronized void fail() - { - //test writer didn't specify why test failed, so give generic - fail( "it just plain failed! :-)" ); } - - public static synchronized void fail( String whyFailed ) - { - System.out.println( "The test failed: " + whyFailed ); - System.out.println( "The test is over, hit Ctl-C to stop Java VM" ); - //check if this called from main thread - if ( mainThread == Thread.currentThread() ) - { - //If main thread, fail now 'cause not sleeping - throw new RuntimeException( whyFailed ); - } - theTestPassed = false; - testGeneratedInterrupt = true; - failureMessage = whyFailed; - mainThread.interrupt(); - }//fail() - -}// class AncestorResized - -//This exception is used to exit from any level of call nesting -// when it's determined that the test has passed, and immediately -// end the test. -class TestPassedException extends RuntimeException -{ } - -//*********** End Standard Test Machinery Section ********** - - -//************ Begin classes defined for the test **************** - -// if want to make listeners, here is the recommended place for them, then instantiate -// them in init() - -/* Example of a class which may be written as part of a test -class NewClass implements anInterface - { - static int newVar = 0; - - public void eventDispatched(AWTEvent e) - { - //Counting events to see if we get enough - eventCount++; - - if( eventCount == 20 ) - { - //got enough events, so pass - - AncestorResized.pass(); - } - else if( tries == 20 ) - { - //tried too many times without getting enough events so fail - - AncestorResized.fail(); - } - - }// eventDispatched() - - }// NewClass class - -*/ - - -//************** End classes defined for the test ******************* diff --git a/test/jdk/java/awt/image/ColorModel/DrawCustomColorModel.java b/test/jdk/java/awt/image/ColorModel/DrawCustomColorModel.java new file mode 100644 index 0000000000000000000000000000000000000000..a438048f1cee46b6ed052ceea39a4c6bdbd1b329 --- /dev/null +++ b/test/jdk/java/awt/image/ColorModel/DrawCustomColorModel.java @@ -0,0 +1,79 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AlphaComposite; +import java.awt.Frame; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBufferInt; +import java.awt.image.DirectColorModel; +import java.awt.image.WritableRaster; +import java.util.Arrays; + +/** + * @test + * @bug 8275843 + * @key headful + * @summary No exception or errors should occur. + */ +public final class DrawCustomColorModel { + + public static void main(String[] args) { + var ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + for (GraphicsDevice gd : ge.getScreenDevices()) { + GraphicsConfiguration[] gcs = gd.getConfigurations(); + for (GraphicsConfiguration gc : gcs) { + test(gc); + } + } + } + + private static void test(GraphicsConfiguration gc) { + Frame frame = new Frame(gc); + frame.setUndecorated(true); + frame.pack(); + frame.setSize(15, 15); + ColorModel cm = new DirectColorModel(32, + 0xff000000, // Red + 0x00ff0000, // Green + 0x0000ff00, // Blue + 0x000000FF // Alpha + ); + WritableRaster wr = cm.createCompatibleWritableRaster(16, 16); + DataBufferInt buff = (DataBufferInt) wr.getDataBuffer(); + int[] data = buff.getData(); + Arrays.fill(data, -1); // more chance to reproduce + Image image = new BufferedImage(cm, wr, false, null); + + Graphics2D graphics = (Graphics2D) frame.getGraphics(); + graphics.setComposite(AlphaComposite.Src); + graphics.drawImage(image, 0, 0, null); + graphics.dispose(); + frame.dispose(); + } +} diff --git a/test/jdk/java/awt/regtesthelpers/Util.java b/test/jdk/java/awt/regtesthelpers/Util.java index dde65574460417b75558d4488b6545989063456e..af1cafe42974970b1eb143ebf0d88e2532588dcc 100644 --- a/test/jdk/java/awt/regtesthelpers/Util.java +++ b/test/jdk/java/awt/regtesthelpers/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -405,8 +405,7 @@ public final class Util { } /* - * The values directly map to the ones of - * sun.awt.X11.XWM & sun.awt.motif.MToolkit classes. + * The values directly map to the ones of sun.awt.X11.XWM class. */ public final static int UNDETERMINED_WM = 1, @@ -433,8 +432,6 @@ public final class Util { try { if ("sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { clazz = Class.forName("sun.awt.X11.XWM"); - } else if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { - clazz = Class.forName("sun.awt.motif.MToolkit"); } } catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); @@ -446,7 +443,6 @@ public final class Util { try { final Class _clazz = clazz; Method m_addExports = Class.forName("java.awt.Helper").getDeclaredMethod("addExports", String.class, java.lang.Module.class); - // No MToolkit anymore: nothing to do about it. // We may be called from non-X11 system, and this permission cannot be delegated to a test. m_addExports.invoke(null, "sun.awt.X11", Util.class.getModule()); Method m_getWMID = (Method)AccessController.doPrivileged(new PrivilegedAction() { diff --git a/test/jdk/java/foreign/TestArrayCopy.java b/test/jdk/java/foreign/TestArrayCopy.java index b8a36307fdeec1040cc3b56690c791409cd6874f..e45fcf395f7c4712f0e130c413d27585484422fc 100644 --- a/test/jdk/java/foreign/TestArrayCopy.java +++ b/test/jdk/java/foreign/TestArrayCopy.java @@ -253,6 +253,18 @@ public class TestArrayCopy { MemorySegment.copy(new byte[] { 1, 2, 3, 4 }, 0, segment, JAVA_INT, 0, 4); } + @Test(expectedExceptions = IllegalArgumentException.class) + public void testHyperAlignedSrc() { + MemorySegment segment = MemorySegment.ofArray(new byte[] {1, 2, 3, 4}); + MemorySegment.copy(new byte[] { 1, 2, 3, 4 }, 0, segment, JAVA_BYTE.withBitAlignment(16), 0, 4); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testHyperAlignedDst() { + MemorySegment segment = MemorySegment.ofArray(new byte[] {1, 2, 3, 4}); + MemorySegment.copy(segment, JAVA_BYTE.withBitAlignment(16), 0, new byte[] { 1, 2, 3, 4 }, 0, 4); + } + /***** Utilities *****/ public static MemorySegment srcSegment(int bytesLength) { diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java index 57d953f771d9acc525258a9e5f6199c90f8a289f..ce5f55efb0d6344743524ef59c670678454611a9 100644 --- a/test/jdk/java/foreign/TestByteBuffer.java +++ b/test/jdk/java/foreign/TestByteBuffer.java @@ -369,7 +369,7 @@ public class TestByteBuffer { Throwable cause = ex.getCause(); if (cause instanceof IllegalStateException) { //all get/set buffer operation should fail because of the scope check - assertTrue(ex.getCause().getMessage().contains("Already closed")); + assertTrue(ex.getCause().getMessage().contains("already closed")); } else { //all other exceptions were unexpected - fail fail("Unexpected exception", cause); @@ -406,7 +406,7 @@ public class TestByteBuffer { handle.invoke(e.getValue()); fail(); } catch (IllegalStateException ex) { - assertTrue(ex.getMessage().contains("Already closed")); + assertTrue(ex.getMessage().contains("already closed")); } catch (UnsupportedOperationException ex) { //skip } catch (Throwable ex) { diff --git a/test/jdk/java/foreign/TestHeapAlignment.java b/test/jdk/java/foreign/TestHeapAlignment.java new file mode 100644 index 0000000000000000000000000000000000000000..3395a686f38e7114e7b1c0a7505b8eb99263cfc1 --- /dev/null +++ b/test/jdk/java/foreign/TestHeapAlignment.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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.arch == "amd64" | os.arch == "x86_64") & sun.arch.data.model == "64") | os.arch == "aarch64" + * @run testng/othervm --enable-native-access=ALL-UNNAMED TestHeapAlignment + */ + +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.MemoryLayout; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.ValueLayout; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +import static org.testng.Assert.fail; + +public class TestHeapAlignment { + + @Test(dataProvider = "layouts") + public void testHeapAlignment(MemorySegment segment, int align, Object val, Object arr, ValueLayout layout, Function<Object, MemorySegment> segmentFactory) { + assertAligned(align, layout, () -> layout.varHandle().get(segment)); + assertAligned(align, layout, () -> layout.varHandle().set(segment, val)); + MemoryLayout seq = MemoryLayout.sequenceLayout(10, layout); + assertAligned(align, layout, () -> seq.varHandle(MemoryLayout.PathElement.sequenceElement()).get(segment, 0L)); + assertAligned(align, layout, () -> seq.varHandle(MemoryLayout.PathElement.sequenceElement()).set(segment, 0L, val)); + assertAligned(align, layout, () -> segment.spliterator(layout)); + if (arr != null) { + assertAligned(align, layout, () -> MemorySegment.copy(arr, 0, segment, layout, 0, 1)); + assertAligned(align, layout, () -> MemorySegment.copy(segment, layout, 0, arr, 0, 1)); + assertAligned(align, layout, () -> { + MemorySegment other = segmentFactory.apply(arr); + MemorySegment.copy(other, layout, 0, segment, layout, 0, 1); + }); + MemorySegment other = segmentFactory.apply(arr); + assertAligned(align, layout, () -> { + MemorySegment.copy(segment, layout, 0, other, layout, 0, 1); + }); + assertAligned(align, layout, () -> { + MemorySegment.copy(other, layout, 0, segment, layout, 0, 1); + }); + } + } + + static void assertAligned(int align, ValueLayout layout, Runnable runnable) { + boolean shouldFail = layout.byteAlignment() > align && align != -1; + try { + runnable.run(); + if (shouldFail) { + fail("Should not get here!"); + } + } catch (IllegalArgumentException ex) { + if (!shouldFail) { + fail("Should not get here!"); + } else if (!ex.getMessage().contains("alignment") && !ex.getMessage().contains("Misaligned")) { + fail("Unexpected exception: " + ex); + } + } + } + + static final ValueLayout.OfChar JAVA_CHAR_ALIGNED = ValueLayout.JAVA_CHAR.withBitAlignment(16); + static final ValueLayout.OfShort JAVA_SHORT_ALIGNED = ValueLayout.JAVA_SHORT.withBitAlignment(16); + static final ValueLayout.OfInt JAVA_INT_ALIGNED = ValueLayout.JAVA_INT.withBitAlignment(32); + static final ValueLayout.OfFloat JAVA_FLOAT_ALIGNED = ValueLayout.JAVA_FLOAT.withBitAlignment(32); + static final ValueLayout.OfLong JAVA_LONG_ALIGNED = ValueLayout.JAVA_LONG.withBitAlignment(64); + static final ValueLayout.OfDouble JAVA_DOUBLE_ALIGNED = ValueLayout.JAVA_DOUBLE.withBitAlignment(64); + static final ValueLayout.OfAddress ADDRESS_ALIGNED = ValueLayout.ADDRESS.withBitAlignment(ValueLayout.ADDRESS.bitSize()); + + enum SegmentAndAlignment { + HEAP_BYTE(MemorySegment.ofArray(new byte[8]), 1), + HEAP_SHORT(MemorySegment.ofArray(new short[4]), 2), + HEAP_CHAR(MemorySegment.ofArray(new char[4]), 2), + HEAP_INT(MemorySegment.ofArray(new int[2]), 4), + HEAP_FLOAT(MemorySegment.ofArray(new float[2]), 4), + HEAP_LONG(MemorySegment.ofArray(new long[1]), 8), + HEAP_DOUBLE(MemorySegment.ofArray(new double[1]), 8), + NATIVE(MemorySegment.allocateNative(8, ResourceScope.newImplicitScope()), -1); + + final MemorySegment segment; + final int align; + + SegmentAndAlignment(MemorySegment segment, int align) { + this.segment = segment; + this.align = align; + } + } + + @DataProvider + public static Object[][] layouts() { + List<Object[]> layouts = new ArrayList<>(); + for (SegmentAndAlignment testCase : SegmentAndAlignment.values()) { + layouts.add(new Object[] { testCase.segment, testCase.align, (byte) 42, new byte[]{42}, ValueLayout.JAVA_BYTE, (Function<byte[], MemorySegment>)MemorySegment::ofArray }); + layouts.add(new Object[] { testCase.segment, testCase.align, true, null, ValueLayout.JAVA_BOOLEAN, null }); + layouts.add(new Object[] { testCase.segment, testCase.align, (char) 42, new char[]{42}, JAVA_CHAR_ALIGNED, (Function<char[], MemorySegment>)MemorySegment::ofArray }); + layouts.add(new Object[] { testCase.segment, testCase.align, (short) 42, new short[]{42}, JAVA_SHORT_ALIGNED, (Function<short[], MemorySegment>)MemorySegment::ofArray }); + layouts.add(new Object[] { testCase.segment, testCase.align, 42, new int[]{42}, JAVA_INT_ALIGNED, (Function<int[], MemorySegment>)MemorySegment::ofArray }); + layouts.add(new Object[] { testCase.segment, testCase.align, 42f, new float[]{42}, JAVA_FLOAT_ALIGNED, (Function<float[], MemorySegment>)MemorySegment::ofArray }); + layouts.add(new Object[] { testCase.segment, testCase.align, 42L, new long[]{42}, JAVA_LONG_ALIGNED, (Function<long[], MemorySegment>)MemorySegment::ofArray }); + layouts.add(new Object[] { testCase.segment, testCase.align, 42d, new double[]{42}, JAVA_DOUBLE_ALIGNED, (Function<double[], MemorySegment>)MemorySegment::ofArray }); + layouts.add(new Object[] { testCase.segment, testCase.align, MemoryAddress.ofLong(42), null, ADDRESS_ALIGNED, null }); + } + return layouts.toArray(new Object[0][]); + } +} diff --git a/test/jdk/java/foreign/TestMemoryAccessInstance.java b/test/jdk/java/foreign/TestMemoryAccessInstance.java index 702e95bf8da38c72ef5c25b314418c36cd9bdeff..83daa11ce4ea984478229f7f0cc91a6ae5bc5815 100644 --- a/test/jdk/java/foreign/TestMemoryAccessInstance.java +++ b/test/jdk/java/foreign/TestMemoryAccessInstance.java @@ -35,12 +35,13 @@ import java.util.function.Function; import jdk.incubator.foreign.ResourceScope; import jdk.incubator.foreign.ValueLayout; +import org.testng.SkipException; import org.testng.annotations.*; import static org.testng.Assert.*; public class TestMemoryAccessInstance { - static class Accessor<T, X, L> { + static class Accessor<T, X, L extends ValueLayout> { interface SegmentGetter<T, X, L> { X get(T buffer, L layout, long offset); @@ -90,13 +91,34 @@ public class TestMemoryAccessInstance { } } - static <L, X> Accessor<MemorySegment, X, L> ofSegment(L layout, X value, + @SuppressWarnings("unchecked") + void testHyperAligned() { + try (ResourceScope scope = ResourceScope.newConfinedScope()) { + MemorySegment segment = MemorySegment.allocateNative(64, scope); + T t = transform.apply(segment); + L alignedLayout = (L)layout.withBitAlignment(layout.byteSize() * 8 * 2); + try { + segmentSetter.set(t, alignedLayout, 0, value); + fail(); + } catch (IllegalArgumentException exception) { + assertTrue(exception.getMessage().contains("greater")); + } + try { + segmentGetter.get(t, alignedLayout, 0); + fail(); + } catch (IllegalArgumentException exception) { + assertTrue(exception.getMessage().contains("greater")); + } + } + } + + static <L extends ValueLayout, X> Accessor<MemorySegment, X, L> ofSegment(L layout, X value, SegmentGetter<MemorySegment, X, L> segmentGetter, SegmentSetter<MemorySegment, X, L> segmentSetter, BufferGetter<X> bufferGetter, BufferSetter<X> bufferSetter) { return new Accessor<>(Function.identity(), layout, value, segmentGetter, segmentSetter, bufferGetter, bufferSetter); } - static <L, X> Accessor<MemoryAddress, X, L> ofAddress(L layout, X value, + static <L extends ValueLayout, X> Accessor<MemoryAddress, X, L> ofAddress(L layout, X value, SegmentGetter<MemoryAddress, X, L> segmentGetter, SegmentSetter<MemoryAddress, X, L> segmentSetter, BufferGetter<X> bufferGetter, BufferSetter<X> bufferSetter) { return new Accessor<>(MemorySegment::address, layout, value, segmentGetter, segmentSetter, bufferGetter, bufferSetter); @@ -113,6 +135,24 @@ public class TestMemoryAccessInstance { accessor.test(); } + @Test(dataProvider = "segmentAccessors") + public void testSegmentAccessHyper(String testName, Accessor<?, ?, ?> accessor) { + if (testName.contains("index")) { + accessor.testHyperAligned(); + } else { + throw new SkipException("Skipping"); + } + } + + @Test(dataProvider = "addressAccessors") + public void testAddressAccessHyper(String testName, Accessor<?, ?, ?> accessor) { + if (testName.contains("index")) { + accessor.testHyperAligned(); + } else { + throw new SkipException("Skipping"); + } + } + static final ByteOrder NE = ByteOrder.nativeOrder(); @DataProvider(name = "segmentAccessors") diff --git a/test/jdk/java/foreign/TestMemoryAlignment.java b/test/jdk/java/foreign/TestMemoryAlignment.java index d486581435a7efa70ac666b205df678830b5fd1f..2726fd6d91eee0abe6d28f93ea346ed0adb19dfb 100644 --- a/test/jdk/java/foreign/TestMemoryAlignment.java +++ b/test/jdk/java/foreign/TestMemoryAlignment.java @@ -74,7 +74,7 @@ public class TestMemoryAlignment { MemorySegment segment = MemorySegment.allocateNative(alignedGroup, scope); vh.set(segment.asSlice(1L), -42); assertEquals(align, 8); //this is the only case where access is aligned - } catch (IllegalStateException ex) { + } catch (IllegalArgumentException ex) { assertNotEquals(align, 8); //if align != 8, access is always unaligned } } diff --git a/test/jdk/java/foreign/TestSegmentCopy.java b/test/jdk/java/foreign/TestSegmentCopy.java index de2dba0848341758a3969c19dca198cddc6ecbc3..1185f4360271072a0b03661f66d58719f47e326e 100644 --- a/test/jdk/java/foreign/TestSegmentCopy.java +++ b/test/jdk/java/foreign/TestSegmentCopy.java @@ -40,6 +40,7 @@ import java.util.ArrayList; import java.util.List; import java.util.function.IntFunction; +import static jdk.incubator.foreign.ValueLayout.JAVA_BYTE; import static org.testng.Assert.*; public class TestSegmentCopy { @@ -81,12 +82,16 @@ public class TestSegmentCopy { } } - interface Getter<X> { - X get(MemorySegment segment, ValueLayout layout, long index); + @Test(expectedExceptions = IllegalArgumentException.class) + public void testHyperAlignedSrc() { + MemorySegment segment = MemorySegment.ofArray(new byte[] {1, 2, 3, 4}); + MemorySegment.copy(segment, 0, segment, JAVA_BYTE.withBitAlignment(16), 0, 4); } - interface Setter<X> { - void set(MemorySegment segment, ValueLayout layout, long index, X val); + @Test(expectedExceptions = IllegalArgumentException.class) + public void testHyperAlignedDst() { + MemorySegment segment = MemorySegment.ofArray(new byte[] {1, 2, 3, 4}); + MemorySegment.copy(segment, JAVA_BYTE.withBitAlignment(16), 0, segment, 0, 4); } enum Type { diff --git a/test/jdk/java/foreign/TestSpliterator.java b/test/jdk/java/foreign/TestSpliterator.java index 17f4ef392590420b42337971f8fd3051df18ddcf..7fcd6a16d3628d4a06b6e2dca5b041231c567942 100644 --- a/test/jdk/java/foreign/TestSpliterator.java +++ b/test/jdk/java/foreign/TestSpliterator.java @@ -127,6 +127,11 @@ public class TestSpliterator { MemorySegment.ofArray(new byte[7]).elements(MemoryLayout.sequenceLayout(0, ValueLayout.JAVA_INT)); } + @Test(expectedExceptions = IllegalArgumentException.class) + public void testHyperAligned() { + MemorySegment.ofArray(new byte[8]).elements(MemoryLayout.sequenceLayout(2, ValueLayout.JAVA_INT.withBitAlignment(64))); + } + static long sumSingle(long acc, MemorySegment segment) { return acc + (int)INT_HANDLE.get(segment, 0L); } diff --git a/test/jdk/java/foreign/TestVarHandleCombinators.java b/test/jdk/java/foreign/TestVarHandleCombinators.java index e9beaebafa84c00377da2281a0e9fd209b1de9b7..e2c9d0bcfc2833d094d4c0348fe3c70e0db420d0 100644 --- a/test/jdk/java/foreign/TestVarHandleCombinators.java +++ b/test/jdk/java/foreign/TestVarHandleCombinators.java @@ -51,7 +51,7 @@ public class TestVarHandleCombinators { assertEquals((byte) vh.get(segment, 2), (byte) -1); } - @Test(expectedExceptions = IllegalStateException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testUnalignedElement() { VarHandle vh = MemoryHandles.varHandle(ValueLayout.JAVA_BYTE.withBitAlignment(32)); MemorySegment segment = MemorySegment.ofArray(new byte[4]); diff --git a/test/jdk/java/io/ClassCache/ContinuousGCTest.java b/test/jdk/java/io/ClassCache/ContinuousGCTest.java new file mode 100644 index 0000000000000000000000000000000000000000..681663029e40dc73c8098e58cd5e0c3518eae40e --- /dev/null +++ b/test/jdk/java/io/ClassCache/ContinuousGCTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.NameClassCache; + +/** + * @test + * @bug 8280041 + * @summary Sanity test for ClassCache under continuous GC + * @compile/module=java.base java/io/NameClassCache.java + * @run main ContinuousGCTest + */ +public class ContinuousGCTest { + static final NameClassCache CACHE = new NameClassCache(); + static final String VALUE = "ClassCache-ContinuousGCTest"; + + public static void main(String... args) throws Throwable { + for (int c = 0; c < 1000; c++) { + test(); + System.gc(); + } + } + + public static void test() { + String cached = CACHE.get(ContinuousGCTest.class); + if (!cached.equals(VALUE)) { + throw new IllegalStateException("Cache failure, got: " + cached); + } + } +} diff --git a/test/jdk/java/io/ClassCache/NullValueTest.java b/test/jdk/java/io/ClassCache/NullValueTest.java new file mode 100644 index 0000000000000000000000000000000000000000..22b41fa071d163c55f58ccabca3a13fd01aac8ad --- /dev/null +++ b/test/jdk/java/io/ClassCache/NullValueTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.NullClassCache; + +/** + * @test + * @bug 8280041 + * @summary Test that ClassCache throws on trying to pass null value + * @compile/module=java.base java/io/NullClassCache.java + * @run main NullValueTest + */ +public class NullValueTest { + public static void main(String... args) throws Throwable { + try { + new NullClassCache().get(Object.class); + throw new IllegalStateException("Should have failed"); + } catch (NullPointerException npe) { + // Expected + } + } +} diff --git a/test/jdk/java/io/ClassCache/java.base/java/io/NameClassCache.java b/test/jdk/java/io/ClassCache/java.base/java/io/NameClassCache.java new file mode 100644 index 0000000000000000000000000000000000000000..ff2149fc6a28158a38cac54566aa17d391aa875a --- /dev/null +++ b/test/jdk/java/io/ClassCache/java.base/java/io/NameClassCache.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +public class NameClassCache extends ClassCache<String> { + protected String computeValue(Class<?> cl) { + // Return string that is not interned and specific to class + return "ClassCache-" + cl.getName(); + } + + public String get(Class<?> cl) { + return super.get(cl); + } +} diff --git a/test/jdk/java/io/ClassCache/java.base/java/io/NullClassCache.java b/test/jdk/java/io/ClassCache/java.base/java/io/NullClassCache.java new file mode 100644 index 0000000000000000000000000000000000000000..58c92ef139906fdda469242fa609b0343c158f21 --- /dev/null +++ b/test/jdk/java/io/ClassCache/java.base/java/io/NullClassCache.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +public class NullClassCache extends ClassCache<Object> { + protected Object computeValue(Class<?> cl) { + return null; + } + + public Object get(Class<?> cl) { + return super.get(cl); + } +} diff --git a/test/jdk/java/io/File/GetXSpace.java b/test/jdk/java/io/File/GetXSpace.java index eacc75652272a453f8c7026301518f131f7f37d6..ac80bdf68fd2cfdeff8980d1318f8874beec28ee 100644 --- a/test/jdk/java/io/File/GetXSpace.java +++ b/test/jdk/java/io/File/GetXSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,6 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FilePermission; import java.io.InputStreamReader; import java.io.IOException; import java.nio.file.Files; @@ -108,8 +107,8 @@ public class GetXSpace { Space(String total, String free, String name) { try { - this.total = Long.valueOf(total) * KSIZE; - this.free = Long.valueOf(free) * KSIZE; + this.total = Long.parseLong(total) * KSIZE; + this.free = Long.parseLong(free) * KSIZE; } catch (NumberFormatException x) { throw new RuntimeException("the regex should have caught this", x); } @@ -157,7 +156,7 @@ public class GetXSpace { } al.add(new Space(m.group(2), m.group(3), name));; } - j = m.end() + 1; + j = m.end(); } else { throw new RuntimeException("unrecognized df output format: " + "charAt(" + j + ") = '" @@ -227,7 +226,7 @@ public class GetXSpace { // On Linux, ignore the NSFE if the path is one of the // /run/user/$UID mounts created by pam_systemd(8) as it // might be deleted during the test - if (!Platform.isLinux() || s.name().indexOf("/run/user") == -1) + if (!Platform.isLinux() || !s.name().contains("/run/user")) throw new RuntimeException(nsfe); } catch (IOException e) { throw new RuntimeException(e); diff --git a/test/jdk/java/io/File/LastModifiedTest.java b/test/jdk/java/io/File/LastModifiedTest.java index 62e88baa6ea07732288d473a9936244229d8bfd6..52c7d390401478634da4e8d5ce65d5792b615e8c 100644 --- a/test/jdk/java/io/File/LastModifiedTest.java +++ b/test/jdk/java/io/File/LastModifiedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon and/or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java b/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java new file mode 100644 index 0000000000000000000000000000000000000000..74c21c540d8649c84144af451a7096b06f7dddc0 --- /dev/null +++ b/test/jdk/java/io/ObjectStreamClass/ObjectStreamClassCaching.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; +import java.io.ObjectStreamClass; +import java.io.Serializable; +import java.util.ArrayList; +import org.testng.annotations.Test; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +/* @test + * @bug 8277072 + * @library /test/lib/ + * @summary ObjectStreamClass caches keep ClassLoaders alive + * @run testng/othervm -Xmx10m -XX:SoftRefLRUPolicyMSPerMB=1 ObjectStreamClassCaching + */ +public class ObjectStreamClassCaching { + + @Test + public void testCachingEffectiveness() throws Exception { + var ref = lookupObjectStreamClass(TestClass.class); + System.gc(); + Thread.sleep(100L); + // to trigger any ReferenceQueue processing... + lookupObjectStreamClass(AnotherTestClass.class); + assertFalse(ref.refersTo(null), + "Cache lost entry although memory was not under pressure"); + } + + @Test + public void testCacheReleaseUnderMemoryPressure() throws Exception { + var ref = lookupObjectStreamClass(TestClass.class); + pressMemoryHard(ref); + System.gc(); + Thread.sleep(100L); + assertTrue(ref.refersTo(null), + "Cache still has entry although memory was pressed hard"); + } + + // separate method so that the looked-up ObjectStreamClass is not kept on stack + private static WeakReference<?> lookupObjectStreamClass(Class<?> cl) { + return new WeakReference<>(ObjectStreamClass.lookup(cl)); + } + + private static void pressMemoryHard(Reference<?> ref) { + try { + var list = new ArrayList<>(); + while (!ref.refersTo(null)) { + list.add(new byte[1024 * 1024 * 64]); // 64 MiB chunks + } + } catch (OutOfMemoryError e) { + // release + } + } +} + +class TestClass implements Serializable { +} + +class AnotherTestClass implements Serializable { +} diff --git a/test/jdk/java/io/ObjectStreamClass/TestOSCClassLoaderLeak.java b/test/jdk/java/io/ObjectStreamClass/TestOSCClassLoaderLeak.java new file mode 100644 index 0000000000000000000000000000000000000000..3a99760bb6ebb6798feddeddf833e52663435ce3 --- /dev/null +++ b/test/jdk/java/io/ObjectStreamClass/TestOSCClassLoaderLeak.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.ObjectStreamClass; +import java.io.ObjectStreamField; +import java.io.Serializable; +import java.util.Arrays; +import org.testng.annotations.Test; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import jdk.test.lib.util.ForceGC; + +/* @test + * @bug 8277072 + * @library /test/lib/ + * @build jdk.test.lib.util.ForceGC + * @summary ObjectStreamClass caches keep ClassLoaders alive + * @run testng TestOSCClassLoaderLeak + */ +public class TestOSCClassLoaderLeak { + + @Test + public void testClassLoaderLeak() throws Exception { + TestClassLoader myOwnClassLoader = new TestClassLoader(); + Class<?> loadClass = myOwnClassLoader.loadClass("ObjectStreamClass_MemoryLeakExample"); + Constructor con = loadClass.getConstructor(); + con.setAccessible(true); + Object objectStreamClass_MemoryLeakExample = con.newInstance(); + objectStreamClass_MemoryLeakExample.toString(); + + WeakReference<Object> myOwnClassLoaderWeakReference = new WeakReference<>(myOwnClassLoader); + assertNotNull(myOwnClassLoaderWeakReference.get()); + objectStreamClass_MemoryLeakExample = null; + myOwnClassLoader = null; + loadClass = null; + con = null; + assertNotNull(myOwnClassLoaderWeakReference.get()); + + ForceGC gc = new ForceGC(); + assertTrue(gc.await(() -> myOwnClassLoaderWeakReference.get() == null)); + } +} + +class ObjectStreamClass_MemoryLeakExample { + private static final ObjectStreamField[] fields = ObjectStreamClass.lookup(TestClass.class).getFields(); + public ObjectStreamClass_MemoryLeakExample() { + } + + @Override + public String toString() { + return Arrays.toString(fields); + } +} + +class TestClassLoader extends ClassLoader { + + @Override + public Class<?> loadClass(String name) throws ClassNotFoundException { + if (name.equals("TestClass") || name.equals("ObjectStreamClass_MemoryLeakExample")) { + byte[] bt = loadClassData(name); + return defineClass(name, bt, 0, bt.length); + } else { + return super.loadClass(name); + } + } + + private static byte[] loadClassData(String className) { + ByteArrayOutputStream byteSt = new ByteArrayOutputStream(); + try (InputStream is = TestClassLoader.class.getClassLoader().getResourceAsStream(className.replace(".", "/") + ".class")) { + int len = 0; + while ((len = is.read()) != -1) { + byteSt.write(len); + } + } catch (java.io.IOException e) { + e.printStackTrace(); + } + return byteSt.toByteArray(); + } +} + +class TestClass implements Serializable { + public String x; +} diff --git a/test/jdk/java/io/OutputStreamWriter/WriteAfterClose.java b/test/jdk/java/io/OutputStreamWriter/WriteAfterClose.java index 0982df62a6de6a9b20e6b72a9a7e47e86276891d..d2bdd362065197bf3f4829256f96e614e9ae4aa0 100644 --- a/test/jdk/java/io/OutputStreamWriter/WriteAfterClose.java +++ b/test/jdk/java/io/OutputStreamWriter/WriteAfterClose.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ public class WriteAfterClose { try { wtr.write("a", 0, 1); - System.out.println("FALIED: Allows string buf write on a closed stream"); + System.out.println("FAILED: Allows string buf write on a closed stream"); failed = true; } catch (Exception e) { } diff --git a/test/jdk/java/io/Serializable/oldTests/WritePrimitive.java b/test/jdk/java/io/Serializable/oldTests/WritePrimitive.java index f2bd28d75f73a06b3065cc8bf6d0a9732526c89f..e6b841e7a49751d02ebd6db06884c6fa11af63d1 100644 --- a/test/jdk/java/io/Serializable/oldTests/WritePrimitive.java +++ b/test/jdk/java/io/Serializable/oldTests/WritePrimitive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ /* @test + * @bug 8276806 8278463 * @summary it is a new version of an old test which was * /src/share/test/serialization/piotest.java * Test of serialization/deserialization of @@ -32,28 +33,27 @@ */ import java.io.*; +import java.util.Arrays; public class WritePrimitive { public static void main (String argv[]) throws IOException { System.err.println("\nRegression test for testing of " + "serialization/deserialization of primitives \n"); + int i = 123456; + byte b = 12; + short s = 45; + char c = 'A'; + long l = 1234567890000L; + float f = 3.14159f; + double d = f * 2; + boolean z = true; + String string = "The String"; + PrimitivesTest prim = new PrimitivesTest(); + byte[] ba = {1, 2, 3, 4, 5, 6, 7}; // byte array to write - FileInputStream istream = null; - FileOutputStream ostream = null; - try { - int i = 123456; - byte b = 12; - short s = 45; - char c = 'A'; - long l = 1234567890000L; - float f = 3.14159f; - double d = f*2; - boolean z = true; - String string = "The String"; - PrimitivesTest prim = new PrimitivesTest(); - - ostream = new FileOutputStream("piotest1.tmp"); - ObjectOutputStream p = new ObjectOutputStream(ostream); + byte[] bytes; + try (ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + ObjectOutputStream p = new ObjectOutputStream(ostream)) { p.writeInt(i); p.writeByte(b); @@ -63,14 +63,20 @@ public class WritePrimitive { p.writeFloat(f); p.writeDouble(d); p.writeBoolean(z); + p.write(ba); // for simple read(byte[]) + p.write(ba); // for readFully(byte[]) + p.write(ba, 0, ba.length - 2); // for readFully(byte[], 0, 7) p.writeUTF(string); p.writeObject(string); p.writeObject(prim); p.flush(); + bytes = ostream.toByteArray(); + + } - istream = new FileInputStream("piotest1.tmp"); - ObjectInputStream q = new ObjectInputStream(istream); + ByteArrayInputStream istream = new ByteArrayInputStream(bytes); + try (ObjectInputStream q = new ObjectInputStream(istream);) { int i_u = q.readInt(); byte b_u = q.readByte(); @@ -80,6 +86,12 @@ public class WritePrimitive { float f_u = q.readFloat(); double d_u = q.readDouble(); boolean z_u = q.readBoolean(); + byte[] ba_readBuf = new byte[ba.length]; + int ba_readLen = q.read(ba_readBuf); + byte[] ba_readFullyBuf = new byte[ba.length]; + int ba_readFullyLen = q.read(ba_readFullyBuf); + byte[] ba_readFullySizedBuf = new byte[ba.length]; + int ba_readFullySizedLen = q.read(ba_readFullySizedBuf, 0, ba.length - 2); String string_utf = q.readUTF(); String string_u = (String)q.readObject(); if (i != i_u) { @@ -120,6 +132,10 @@ public class WritePrimitive { z_u); throw new Error(); } + checkArray("read(byte[])", ba, ba.length, ba_readBuf, ba_readLen); + checkArray("readFully(byte[])", ba, ba.length, ba_readFullyBuf, ba_readFullyLen); + checkArray("readFully(byte[], off, len)", ba, ba.length - 2, ba_readFullySizedBuf, ba_readFullySizedLen); + if (!string.equals(string_utf)) { System.err.println("\nString: expected " + string + " actual " + string_utf); @@ -144,20 +160,26 @@ public class WritePrimitive { System.err.print("TEST FAILED: "); e.printStackTrace(); - System.err.println("\nInput remaining"); + System.err.println("\nBytes read: " + (bytes.length - istream.available()) + + ", Input remaining: " + istream.available()); int ch; try { while ((ch = istream.read()) != -1) { System.err.print("\n " + Integer.toString(ch, 16)+ " "); } System.out.println("\n "); - } catch (Exception f) { + } catch (Exception fex) { throw new Error(); } throw new Error(); - } finally { - if (istream != null) istream.close(); - if (ostream != null) ostream.close(); + } + } + + static void checkArray(String label, byte[] expected, int expectedLen, byte[] actual, int actualLen) { + int mismatch = Arrays.mismatch(expected, 0, expectedLen, actual, 0, actualLen); + if (actualLen != expectedLen || mismatch >= 0) { + System.err.println("\n" + label + ": expected " + expectedLen + " actual " + actualLen + ", mismatch: " + mismatch); + throw new Error(); } } } diff --git a/test/jdk/java/io/Serializable/serialFilter/InvalidGlobalFilterTest.java b/test/jdk/java/io/Serializable/serialFilter/InvalidGlobalFilterTest.java index a00f42f65653d1198c83a998326a19f7fc8cbf03..a017354b103d2a534136c066f0a521bacfb091ed 100644 --- a/test/jdk/java/io/Serializable/serialFilter/InvalidGlobalFilterTest.java +++ b/test/jdk/java/io/Serializable/serialFilter/InvalidGlobalFilterTest.java @@ -21,67 +21,100 @@ * questions. */ -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; -import java.io.File; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.ObjectInputFilter; +import java.io.ObjectInputStream; +import java.util.Map; /* * @test - * @bug 8269336 + * @bug 8278087 * @summary Test that an invalid pattern value for the jdk.serialFilter system property causes an - * exception to be thrown in the class initialization of java.io.ObjectInputFilter.Config class - * @library /test/lib - * @run driver InvalidGlobalFilterTest + * exception to be thrown when an attempt is made to use the filter or deserialize. + * A subset of invalid filter patterns is tested. + * @run testng/othervm -Djdk.serialFilter=.* InvalidGlobalFilterTest + * @run testng/othervm -Djdk.serialFilter=! InvalidGlobalFilterTest + * @run testng/othervm -Djdk.serialFilter=/ InvalidGlobalFilterTest + * */ +@Test public class InvalidGlobalFilterTest { private static final String serialPropName = "jdk.serialFilter"; + private static final String serialFilter = System.getProperty(serialPropName); + + static { + // Enable logging + System.setProperty("java.util.logging.config.file", + System.getProperty("test.src", ".") + "/logging.properties"); + } /** - * Launches multiple instances of a Java program by passing each instance an invalid value - * for the {@code jdk.serialFilter} system property. The launched program then triggers the - * class initialization of {@code ObjectInputFilter.Config} class to have it parse the (invalid) - * value of the system property. The launched program is expected to propagate the exception - * raised by the {@code ObjectInputFilter.Config} initialization and the test asserts that the - * launched program did indeed fail with this expected exception. + * Map of invalid patterns to the expected exception message. */ - public static void main(final String[] args) throws Exception { - final String[] invalidPatterns = {".*", ".**", "!", "/java.util.Hashtable", "java.base/", "/"}; - for (final String invalidPattern : invalidPatterns) { - final ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder( - "-D" + serialPropName + "=" + invalidPattern, - "-Djava.util.logging.config.file=" + System.getProperty("test.src") - + File.separator + "logging.properties", - ObjectInputFilterConfigLoader.class.getName()); - // launch a process by passing it an invalid value for -Djdk.serialFilter - final OutputAnalyzer outputAnalyzer = ProcessTools.executeProcess(processBuilder); - try { - // we expect the JVM launch to fail - outputAnalyzer.shouldNotHaveExitValue(0); - // do an additional check to be sure it failed for the right reason - outputAnalyzer.stderrShouldContain("java.lang.ExceptionInInitializerError"); - } finally { - // fail or pass, we print out the generated output from the launched program - // for any debugging - System.err.println("Diagnostics from process " + outputAnalyzer.pid() + ":"); - // print out any stdout/err that was generated in the launched program - outputAnalyzer.reportDiagnosticSummary(); - } + private static final Map<String, String> invalidMessages = + Map.of(".*", "Invalid jdk.serialFilter: package missing in: \".*\"", + ".**", "Invalid jdk.serialFilter: package missing in: \".**\"", + "!", "Invalid jdk.serialFilter: class or package missing in: \"!\"", + "/java.util.Hashtable", "Invalid jdk.serialFilter: module name is missing in: \"/java.util.Hashtable\"", + "java.base/", "Invalid jdk.serialFilter: class or package missing in: \"java.base/\"", + "/", "Invalid jdk.serialFilter: module name is missing in: \"/\""); + + @DataProvider(name = "MethodsToCall") + private Object[][] cases() { + return new Object[][] { + {serialFilter, "getSerialFilter", (Assert.ThrowingRunnable) () -> ObjectInputFilter.Config.getSerialFilter()}, + {serialFilter, "setSerialFilter", (Assert.ThrowingRunnable) () -> ObjectInputFilter.Config.setSerialFilter(new NoopFilter())}, + {serialFilter, "new ObjectInputStream(is)", (Assert.ThrowingRunnable) () -> new ObjectInputStream(new ByteArrayInputStream(new byte[0]))}, + {serialFilter, "new OISSubclass()", (Assert.ThrowingRunnable) () -> new OISSubclass()}, + }; + } + + /** + * Test each method that should throw IllegalStateException based on + * the invalid arguments it was launched with. + */ + @Test(dataProvider = "MethodsToCall") + public void initFaultTest(String pattern, String method, Assert.ThrowingRunnable runnable) { + + IllegalStateException ex = Assert.expectThrows(IllegalStateException.class, + runnable); + + String expected = invalidMessages.get(serialFilter); + if (expected == null) { + Assert.fail("No expected message for filter: " + serialFilter); } + System.out.println(ex.getMessage()); + Assert.assertEquals(ex.getMessage(), expected, "wrong message"); } - // A main() class which just triggers the class initialization of ObjectInputFilter.Config - private static final class ObjectInputFilterConfigLoader { + private static class NoopFilter implements ObjectInputFilter { + /** + * Returns UNDECIDED. + * + * @param filter the FilterInfo + * @return Status.UNDECIDED + */ + public ObjectInputFilter.Status checkInput(FilterInfo filter) { + return ObjectInputFilter.Status.UNDECIDED; + } - public static void main(final String[] args) throws Exception { - System.out.println("JVM was launched with " + serialPropName - + " system property set to " + System.getProperty(serialPropName)); - // this call is expected to fail and we aren't interested in the result. - // we just let the exception propagate out of this call and fail the - // launched program. The test which launched this main, then asserts - // that the exception was indeed thrown. - ObjectInputFilter.Config.getSerialFilter(); + public String toString() { + return "NoopFilter"; } } + + /** + * Subclass of ObjectInputStream to test subclassing constructor. + */ + private static class OISSubclass extends ObjectInputStream { + + protected OISSubclass() throws IOException { + } + } + } diff --git a/test/jdk/java/io/Serializable/serialFilter/SerialFactoryFaults.java b/test/jdk/java/io/Serializable/serialFilter/SerialFactoryFaults.java index 30d35aa888e5e3c39d984bdf4877e1f9450e3a1e..1d35306a42683f9da9f3494828e2da18a5d7d9f4 100644 --- a/test/jdk/java/io/Serializable/serialFilter/SerialFactoryFaults.java +++ b/test/jdk/java/io/Serializable/serialFilter/SerialFactoryFaults.java @@ -22,10 +22,14 @@ */ import org.testng.Assert; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.ObjectInputFilter; import java.io.ObjectInputFilter.Config; +import java.io.ObjectInputStream; import java.util.function.BinaryOperator; /* @test @@ -39,33 +43,47 @@ import java.util.function.BinaryOperator; @Test public class SerialFactoryFaults { + // Sample the serial factory class name + private static final String factoryName = System.getProperty("jdk.serialFilterFactory"); + static { // Enable logging System.setProperty("java.util.logging.config.file", System.getProperty("test.src", ".") + "/logging.properties"); } - public void initFaultTest() { - String factoryName = System.getProperty("jdk.serialFilterFactory"); - ExceptionInInitializerError ex = Assert.expectThrows(ExceptionInInitializerError.class, - () -> Config.getSerialFilterFactory()); - Throwable cause = ex.getCause(); + @DataProvider(name = "MethodsToCall") + private Object[][] cases() { + return new Object[][] { + {"getSerialFilterFactory", (Assert.ThrowingRunnable) () -> Config.getSerialFilterFactory()}, + {"setSerialFilterFactory", (Assert.ThrowingRunnable) () -> Config.setSerialFilterFactory(new NoopFactory())}, + {"new ObjectInputStream(is)", (Assert.ThrowingRunnable) () -> new ObjectInputStream(new ByteArrayInputStream(new byte[0]))}, + {"new OISSubclass()", (Assert.ThrowingRunnable) () -> new OISSubclass()}, + }; + } + + /** + * Test each method that should throw IllegalStateException based on + * the invalid arguments it was launched with. + */ + @Test(dataProvider = "MethodsToCall") + public void initFaultTest(String name, Assert.ThrowingRunnable runnable) { + IllegalStateException ex = Assert.expectThrows(IllegalStateException.class, + runnable); + final String msg = ex.getMessage(); if (factoryName.equals("ForcedError_NoSuchClass")) { - Assert.assertEquals(cause.getClass(), - ClassNotFoundException.class, "wrong exception"); + Assert.assertEquals(msg, + "invalid jdk.serialFilterFactory: ForcedError_NoSuchClass: java.lang.ClassNotFoundException: ForcedError_NoSuchClass", "wrong exception"); } else if (factoryName.equals("SerialFactoryFaults$NoPublicConstructor")) { - Assert.assertEquals(cause.getClass(), - NoSuchMethodException.class, "wrong exception"); + Assert.assertEquals(msg, + "invalid jdk.serialFilterFactory: SerialFactoryFaults$NoPublicConstructor: java.lang.NoSuchMethodException: SerialFactoryFaults$NoPublicConstructor.<init>()", "wrong exception"); } else if (factoryName.equals("SerialFactoryFaults$ConstructorThrows")) { - Assert.assertEquals(cause.getClass(), - IllegalStateException.class, "wrong exception"); + Assert.assertEquals(msg, + "invalid jdk.serialFilterFactory: SerialFactoryFaults$ConstructorThrows: java.lang.RuntimeException: constructor throwing a runtime exception", "wrong exception"); } else if (factoryName.equals("SerialFactoryFaults$FactorySetsFactory")) { - Assert.assertEquals(cause.getClass(), - IllegalStateException.class, "wrong exception"); - Assert.assertEquals(cause.getMessage(), - "Cannot replace filter factory: initialization incomplete", - "wrong message"); + Assert.assertEquals(msg, + "invalid jdk.serialFilterFactory: SerialFactoryFaults$FactorySetsFactory: java.lang.IllegalStateException: Serial filter factory initialization incomplete", "wrong exception"); } else { Assert.fail("No test for filter factory: " + factoryName); } @@ -90,7 +108,7 @@ public class SerialFactoryFaults { public static final class ConstructorThrows implements BinaryOperator<ObjectInputFilter> { public ConstructorThrows() { - throw new IllegalStateException("SerialFactoryFaults$ConstructorThrows"); + throw new RuntimeException("constructor throwing a runtime exception"); } public ObjectInputFilter apply(ObjectInputFilter curr, ObjectInputFilter next) { @@ -112,4 +130,21 @@ public class SerialFactoryFaults { } } + public static final class NoopFactory implements BinaryOperator<ObjectInputFilter> { + public NoopFactory() {} + + public ObjectInputFilter apply(ObjectInputFilter curr, ObjectInputFilter next) { + throw new RuntimeException("NYI"); + } + } + + /** + * Subclass of ObjectInputStream to test subclassing constructor. + */ + private static class OISSubclass extends ObjectInputStream { + + protected OISSubclass() throws IOException { + } + } + } diff --git a/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java b/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java index 8883f0d8263296b52ec6111ece22a043cb745b3d..abe63eb0b7c881885241ef39f36f064f606b7806 100644 --- a/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java +++ b/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * 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 8080535 8191410 8215194 8221431 8239383 + * @bug 8080535 8191410 8215194 8221431 8239383 8268081 * @summary Expected size of Character.UnicodeBlock.map is not optimal * @library /test/lib * @modules java.base/java.lang:open @@ -48,13 +48,14 @@ import jdk.test.lib.util.OptimalCapacity; // As of Unicode 11, 667 entries are expected. // As of Unicode 12.1, 676 entries are expected. // As of Unicode 13.0, 684 entries are expected. +// As of Unicode 14.0, 696 entries are expected. // // Initialization of the map and this test will have to be adjusted // accordingly then. // // Note that HashMap's implementation aligns the initial capacity to // a power of two size, so it will end up 1024 (and thus succeed) in -// cases, such as 638, 667, 676, and 684. +// cases, such as 638, 667, 676, 684, and 696. public class OptimalMapSize { public static void main(String[] args) throws Throwable { @@ -63,7 +64,7 @@ public class OptimalMapSize { Field f = Character.UnicodeBlock.class.getDeclaredField("NUM_ENTITIES"); f.setAccessible(true); int num_entities = f.getInt(null); - assert num_entities == 684; + assert num_entities == 696; int initialCapacity = (int)(num_entities / 0.75f + 1.0f); OptimalCapacity.ofHashMap(Character.UnicodeBlock.class, diff --git a/test/jdk/java/lang/Math/Atan2Tests.java b/test/jdk/java/lang/Math/Atan2Tests.java index d6ff8605dddc154e6d24b06491cef00927e2cc65..7e5dca17f1b5033b0a5e6c761284622141854b10 100644 --- a/test/jdk/java/lang/Math/Atan2Tests.java +++ b/test/jdk/java/lang/Math/Atan2Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 4984407 * @summary Tests for {Math, StrictMath}.atan2 - * @author Joseph D. Darcy */ public class Atan2Tests { @@ -33,10 +32,8 @@ public class Atan2Tests { static int testAtan2Case(double input1, double input2, double expected) { int failures = 0; - failures += Tests.test("StrictMath.atan2(double, double)", input1, input2, - StrictMath.atan2(input1, input2), expected); - failures += Tests.test("Math.atan2(double, double)", input1, input2, - Math.atan2(input1, input2), expected); + failures += Tests.test("StrictMath.atan2", input1, input2, StrictMath::atan2, expected); + failures += Tests.test("Math.atan2", input1, input2, Math::atan2, expected); return failures; } @@ -55,7 +52,7 @@ public class Atan2Tests { return failures; } - public static void main(String [] argv) { + public static void main(String... argv) { int failures = 0; failures += testAtan2(); diff --git a/test/jdk/java/lang/Math/CeilAndFloorTests.java b/test/jdk/java/lang/Math/CeilAndFloorTests.java index d4508f839c8d329719c3caabc7a49dc1fc63b758..6b75b2a8dcb663712145361753f57a0d1dff1324 100644 --- a/test/jdk/java/lang/Math/CeilAndFloorTests.java +++ b/test/jdk/java/lang/Math/CeilAndFloorTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,15 +30,15 @@ public class CeilAndFloorTests { private static int testCeilCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.ceil", input, Math.ceil(input), expected); - failures += Tests.test("StrictMath.ceil", input, StrictMath.ceil(input), expected); + failures += Tests.test("Math.ceil", input, Math::ceil, expected); + failures += Tests.test("StrictMath.ceil", input, StrictMath::ceil, expected); return failures; } private static int testFloorCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.floor", input, Math.floor(input), expected); - failures += Tests.test("StrictMath.floor", input, StrictMath.floor(input), expected); + failures += Tests.test("Math.floor", input, Math::floor, expected); + failures += Tests.test("StrictMath.floor", input, StrictMath::floor, expected); return failures; } diff --git a/test/jdk/java/lang/Math/CubeRootTests.java b/test/jdk/java/lang/Math/CubeRootTests.java index 53ef270377fffacb2005939cff18f7d0a7808c62..a6350702d90baa9645e64603a3fcfd8dcfa1598b 100644 --- a/test/jdk/java/lang/Math/CubeRootTests.java +++ b/test/jdk/java/lang/Math/CubeRootTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ * @run main CubeRootTests * @bug 4347132 4939441 8078672 * @summary Tests for {Math, StrictMath}.cbrt (use -Dseed=X to set PRNG seed) - * @author Joseph D. Darcy * @key randomness */ @@ -46,17 +45,10 @@ public class CubeRootTests { static int testCubeRootCase(double input, double expected) { int failures=0; - double minus_input = -input; - double minus_expected = -expected; - - failures+=Tests.test("Math.cbrt(double)", input, - Math.cbrt(input), expected); - failures+=Tests.test("Math.cbrt(double)", minus_input, - Math.cbrt(minus_input), minus_expected); - failures+=Tests.test("StrictMath.cbrt(double)", input, - StrictMath.cbrt(input), expected); - failures+=Tests.test("StrictMath.cbrt(double)", minus_input, - StrictMath.cbrt(minus_input), minus_expected); + failures+=Tests.test("Math.cbrt", input, Math::cbrt, expected); + failures+=Tests.test("Math.cbrt", -input, Math::cbrt, -expected); + failures+=Tests.test("StrictMath.cbrt", input, StrictMath::cbrt, expected); + failures+=Tests.test("StrictMath.cbrt", -input, StrictMath::cbrt, -expected); return failures; } @@ -324,7 +316,7 @@ public class CubeRootTests { return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testCubeRoot(); diff --git a/test/jdk/java/lang/Math/ExpCornerCaseTests.java b/test/jdk/java/lang/Math/ExpCornerCaseTests.java index 16168254378ec1cb224e3f262fea7aad6968faaf..e48f31beb9106ac77dddbccde046280c7b542006 100644 --- a/test/jdk/java/lang/Math/ExpCornerCaseTests.java +++ b/test/jdk/java/lang/Math/ExpCornerCaseTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,8 +61,8 @@ public class ExpCornerCaseTests { private static int testExp(double input, double expected) { int failures = 0; - failures += Tests.test("StrictMath.exp", input, StrictMath.exp(input), expected); - failures += Tests.test("Math.exp", input, Math.exp(input), expected); + failures += Tests.test("StrictMath.exp", input, StrictMath::exp, expected); + failures += Tests.test("Math.exp", input, Math::exp, expected); return failures; } } diff --git a/test/jdk/java/lang/Math/Expm1Tests.java b/test/jdk/java/lang/Math/Expm1Tests.java index 5bf267d15fd23f0985d156283db078c9030b8afc..204fe44ef15813529e5f01056fae59c7fb61d695 100644 --- a/test/jdk/java/lang/Math/Expm1Tests.java +++ b/test/jdk/java/lang/Math/Expm1Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 4851638 4900189 4939441 * @summary Tests for {Math, StrictMath}.expm1 - * @author Joseph D. Darcy */ /* @@ -214,7 +213,7 @@ public class Expm1Tests { return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testExpm1(); diff --git a/test/jdk/java/lang/Math/FusedMultiplyAddTests.java b/test/jdk/java/lang/Math/FusedMultiplyAddTests.java index 03e164c2198842a85ab4b8c531b31ace32d3d367..61a3bfb0de171ebaea1a06d2e09465945053a700 100644 --- a/test/jdk/java/lang/Math/FusedMultiplyAddTests.java +++ b/test/jdk/java/lang/Math/FusedMultiplyAddTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -365,16 +365,12 @@ public class FusedMultiplyAddTests { private static int testFusedMacCase(double input1, double input2, double input3, double expected) { int failures = 0; - failures += Tests.test("Math.fma(double)", input1, input2, input3, - Math.fma(input1, input2, input3), expected); - failures += Tests.test("StrictMath.fma(double)", input1, input2, input3, - StrictMath.fma(input1, input2, input3), expected); + failures += Tests.test("Math.fma", input1, input2, input3, Math::fma, expected); + failures += Tests.test("StrictMath.fma", input1, input2, input3, StrictMath::fma, expected); // Permute first two inputs - failures += Tests.test("Math.fma(double)", input2, input1, input3, - Math.fma(input2, input1, input3), expected); - failures += Tests.test("StrictMath.fma(double)", input2, input1, input3, - StrictMath.fma(input2, input1, input3), expected); + failures += Tests.test("Math.fma", input2, input1, input3, Math::fma, expected); + failures += Tests.test("StrictMath.fma", input2, input1, input3, StrictMath::fma, expected); return failures; } diff --git a/test/jdk/java/lang/Math/HyperbolicTests.java b/test/jdk/java/lang/Math/HyperbolicTests.java index 0df493698fe1c4f6069000068e4fa741ac7cdf34..8309606f63d745c7a2678bfc6b7e0249ae842e08 100644 --- a/test/jdk/java/lang/Math/HyperbolicTests.java +++ b/test/jdk/java/lang/Math/HyperbolicTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 4851625 4900189 4939441 * @summary Tests for {Math, StrictMath}.{sinh, cosh, tanh} - * @author Joseph D. Darcy */ public class HyperbolicTests { @@ -33,6 +32,20 @@ public class HyperbolicTests { static final double NaNd = Double.NaN; + public static void main(String... argv) { + int failures = 0; + + failures += testSinh(); + failures += testCosh(); + failures += testTanh(); + + if (failures > 0) { + System.err.println("Testing the hyperbolic functions incurred " + + failures + " failures."); + throw new RuntimeException(); + } + } + /** * Test accuracy of {Math, StrictMath}.sinh. The specified * accuracy is 2.5 ulps. @@ -355,19 +368,11 @@ public class HyperbolicTests { double expected, double tolerance) { int failures = 0; - failures += Tests.testTolerance("Math.sinh(double)", - input, Math.sinh(input), - expected, tolerance); - failures += Tests.testTolerance("Math.sinh(double)", - -input, Math.sinh(-input), - -expected, tolerance); + failures += Tests.testTolerance("Math.sinh", input, Math::sinh, expected, tolerance); + failures += Tests.testTolerance("Math.sinh", -input, Math::sinh, -expected, tolerance); - failures += Tests.testTolerance("StrictMath.sinh(double)", - input, StrictMath.sinh(input), - expected, tolerance); - failures += Tests.testTolerance("StrictMath.sinh(double)", - -input, StrictMath.sinh(-input), - -expected, tolerance); + failures += Tests.testTolerance("StrictMath.sinh", input, StrictMath::sinh, expected, tolerance); + failures += Tests.testTolerance("StrictMath.sinh", -input, StrictMath::sinh, -expected, tolerance); return failures; } @@ -375,23 +380,14 @@ public class HyperbolicTests { double expected, double ulps) { int failures = 0; - failures += Tests.testUlpDiff("Math.sinh(double)", - input, Math.sinh(input), - expected, ulps); - failures += Tests.testUlpDiff("Math.sinh(double)", - -input, Math.sinh(-input), - -expected, ulps); - - failures += Tests.testUlpDiff("StrictMath.sinh(double)", - input, StrictMath.sinh(input), - expected, ulps); - failures += Tests.testUlpDiff("StrictMath.sinh(double)", - -input, StrictMath.sinh(-input), - -expected, ulps); + failures += Tests.testUlpDiff("Math.sinh", input, Math::sinh, expected, ulps); + failures += Tests.testUlpDiff("Math.sinh", -input, Math::sinh, -expected, ulps); + + failures += Tests.testUlpDiff("StrictMath.sinh", input, StrictMath::sinh, expected, ulps); + failures += Tests.testUlpDiff("StrictMath.sinh", -input, StrictMath::sinh, -expected, ulps); return failures; } - /** * Test accuracy of {Math, StrictMath}.cosh. The specified * accuracy is 2.5 ulps. @@ -594,7 +590,6 @@ public class HyperbolicTests { 3.0); } - double [][] specialTestCases = { {0.0, 1.0}, {NaNd, NaNd}, @@ -733,23 +728,14 @@ public class HyperbolicTests { double expected, double ulps) { int failures = 0; - failures += Tests.testUlpDiff("Math.cosh(double)", - input, Math.cosh(input), - expected, ulps); - failures += Tests.testUlpDiff("Math.cosh(double)", - -input, Math.cosh(-input), - expected, ulps); - - failures += Tests.testUlpDiff("StrictMath.cosh(double)", - input, StrictMath.cosh(input), - expected, ulps); - failures += Tests.testUlpDiff("StrictMath.cosh(double)", - -input, StrictMath.cosh(-input), - expected, ulps); + failures += Tests.testUlpDiff("Math.cosh", input, Math::cosh, expected, ulps); + failures += Tests.testUlpDiff("Math.cosh", -input, Math::cosh, expected, ulps); + + failures += Tests.testUlpDiff("StrictMath.cosh", input, StrictMath::cosh, expected, ulps); + failures += Tests.testUlpDiff("StrictMath.cosh", -input, StrictMath::cosh, expected, ulps); return failures; } - /** * Test accuracy of {Math, StrictMath}.tanh. The specified * accuracy is 2.5 ulps. @@ -952,7 +938,6 @@ public class HyperbolicTests { 3.0); } - double [][] specialTestCases = { {0.0, 0.0}, {NaNd, NaNd}, @@ -1007,19 +992,11 @@ public class HyperbolicTests { double expected, double tolerance) { int failures = 0; - failures += Tests.testTolerance("Math.tanh(double", - input, Math.tanh(input), - expected, tolerance); - failures += Tests.testTolerance("Math.tanh(double", - -input, Math.tanh(-input), - -expected, tolerance); + failures += Tests.testTolerance("Math.tanh", input, Math::tanh, expected, tolerance); + failures += Tests.testTolerance("Math.tanh", -input, Math::tanh, -expected, tolerance); - failures += Tests.testTolerance("StrictMath.tanh(double", - input, StrictMath.tanh(input), - expected, tolerance); - failures += Tests.testTolerance("StrictMath.tanh(double", - -input, StrictMath.tanh(-input), - -expected, tolerance); + failures += Tests.testTolerance("StrictMath.tanh", input, StrictMath::tanh, expected, tolerance); + failures += Tests.testTolerance("StrictMath.tanh", -input, StrictMath::tanh, -expected, tolerance); return failures; } @@ -1028,35 +1005,11 @@ public class HyperbolicTests { double ulps) { int failures = 0; - failures += Tests.testUlpDiffWithAbsBound("Math.tanh(double)", - input, Math.tanh(input), - expected, ulps, 1.0); - failures += Tests.testUlpDiffWithAbsBound("Math.tanh(double)", - -input, Math.tanh(-input), - -expected, ulps, 1.0); - - failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh(double)", - input, StrictMath.tanh(input), - expected, ulps, 1.0); - failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh(double)", - -input, StrictMath.tanh(-input), - -expected, ulps, 1.0); - return failures; - } - - - public static void main(String argv[]) { - int failures = 0; + failures += Tests.testUlpDiffWithAbsBound("Math.tanh", input, Math::tanh, expected, ulps, 1.0); + failures += Tests.testUlpDiffWithAbsBound("Math.tanh", -input, Math::tanh, -expected, ulps, 1.0); - failures += testSinh(); - failures += testCosh(); - failures += testTanh(); - - if (failures > 0) { - System.err.println("Testing the hyperbolic functions incurred " - + failures + " failures."); - throw new RuntimeException(); - } + failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh", input, StrictMath::tanh, expected, ulps, 1.0); + failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh", -input, StrictMath::tanh, -expected, ulps, 1.0); + return failures; } - } diff --git a/test/jdk/java/lang/Math/HypotTests.java b/test/jdk/java/lang/Math/HypotTests.java index d7e562ca5fd27cde31f2d4409534306fe77786cd..e09799e34a4f3e3c1c00991bbd4bbc7c9c9b5f8d 100644 --- a/test/jdk/java/lang/Math/HypotTests.java +++ b/test/jdk/java/lang/Math/HypotTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ * @run main HypotTests * @bug 4851638 4939441 8078672 8240632 * @summary Tests for {Math, StrictMath}.hypot (use -Dseed=X to set PRNG seed) - * @author Joseph D. Darcy * @key randomness */ @@ -51,7 +50,6 @@ public class HypotTests { long N = n; long result[] = new long[3]; - result[0] = Math.abs(M*M - N*N); result[1] = Math.abs(2*M*N); result[2] = Math.abs(M*M + N*N); @@ -188,13 +186,11 @@ public class HypotTests { pcNeighborsStrictHypot[j+1] ); } - } } } - return failures; } @@ -221,26 +217,22 @@ public class HypotTests { // each input negated singly, and both inputs negated. Also // test inputs in reversed order. - for(int i = -1; i <= 1; i+=2) { - for(int j = -1; j <= 1; j+=2) { + for(int i = -1; i <= 1; i += 2) { + for(int j = -1; j <= 1; j += 2) { double x = i * input1; double y = j * input2; - failures += Tests.testUlpDiff("Math.hypot", x, y, - Math.hypot(x, y), expected, ulps); - failures += Tests.testUlpDiff("Math.hypot", y, x, - Math.hypot(y, x ), expected, ulps); - - failures += Tests.testUlpDiff("StrictMath.hypot", x, y, - StrictMath.hypot(x, y), expected, ulps); - failures += Tests.testUlpDiff("StrictMath.hypot", y, x, - StrictMath.hypot(y, x), expected, ulps); + failures += Tests.testUlpDiff("Math.hypot", x, y, Math::hypot, expected, ulps); + failures += Tests.testUlpDiff("Math.hypot", y, x, Math::hypot, expected, ulps); + + failures += Tests.testUlpDiff("StrictMath.hypot", x, y, StrictMath::hypot, expected, ulps); + failures += Tests.testUlpDiff("StrictMath.hypot", y, x, StrictMath::hypot, expected, ulps); } } return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testHypot(); @@ -252,5 +244,4 @@ public class HypotTests { throw new RuntimeException(); } } - } diff --git a/test/jdk/java/lang/Math/Ieee754SpecialCaseTests.java b/test/jdk/java/lang/Math/Ieee754SpecialCaseTests.java index d8192f2fee36d088bddd15e09b01eb33be562555..f53f231464760b2ce93f146915e69b0e77f8c91b 100644 --- a/test/jdk/java/lang/Math/Ieee754SpecialCaseTests.java +++ b/test/jdk/java/lang/Math/Ieee754SpecialCaseTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,8 +62,8 @@ public class Ieee754SpecialCaseTests { private static int testCosCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.cos", input, Math.cos(input), expected); - failures += Tests.test("StrictMath.cos", input, StrictMath.cos(input), expected); + failures += Tests.test("Math.cos", input, Math::cos, expected); + failures += Tests.test("StrictMath.cos", input, StrictMath::cos, expected); return failures; } @@ -82,8 +82,8 @@ public class Ieee754SpecialCaseTests { private static int testAcosCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.acos", input, Math.acos(input), expected); - failures += Tests.test("StrictMath.acos", input, StrictMath.acos(input), expected); + failures += Tests.test("Math.acos", input, Math::acos, expected); + failures += Tests.test("StrictMath.acos", input, StrictMath::acos, expected); return failures; } @@ -103,8 +103,8 @@ public class Ieee754SpecialCaseTests { private static int testAtanCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.atan", input, Math.atan(input), expected); - failures += Tests.test("StrictMath.atan", input, StrictMath.atan(input), expected); + failures += Tests.test("Math.atan", input, Math::atan, expected); + failures += Tests.test("StrictMath.atan", input, StrictMath::atan, expected); return failures; } @@ -123,8 +123,8 @@ public class Ieee754SpecialCaseTests { private static int testLogCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.log", input, Math.log(input), expected); - failures += Tests.test("StrictMath.log", input, StrictMath.log(input), expected); + failures += Tests.test("Math.log", input, Math::log, expected); + failures += Tests.test("StrictMath.log", input, StrictMath::log, expected); return failures; } } diff --git a/test/jdk/java/lang/Math/IeeeRecommendedTests.java b/test/jdk/java/lang/Math/IeeeRecommendedTests.java index 830b16d765a45e48588a1d32c0512d514a13d27a..8570508ff446f6e0204f6aa11fdfdcd559f72035 100644 --- a/test/jdk/java/lang/Math/IeeeRecommendedTests.java +++ b/test/jdk/java/lang/Math/IeeeRecommendedTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ * @run main IeeeRecommendedTests * @bug 4860891 4826732 4780454 4939441 4826652 8078672 * @summary Tests for IEEE 754[R] recommended functions and similar methods (use -Dseed=X to set PRNG seed) - * @author Joseph D. Darcy * @key randomness */ @@ -364,14 +363,14 @@ public class IeeeRecommendedTests { double minus_expected = -expected; failures+=Tests.test("Math.nextAfter(double,double)", start, direction, - Math.nextAfter(start, direction), expected); + Math::nextAfter, expected); failures+=Tests.test("Math.nextAfter(double,double)", minus_start, minus_direction, - Math.nextAfter(minus_start, minus_direction), minus_expected); + Math::nextAfter, minus_expected); failures+=Tests.test("StrictMath.nextAfter(double,double)", start, direction, - StrictMath.nextAfter(start, direction), expected); + StrictMath::nextAfter, expected); failures+=Tests.test("StrictMath.nextAfter(double,double)", minus_start, minus_direction, - StrictMath.nextAfter(minus_start, minus_direction), minus_expected); + StrictMath::nextAfter, minus_expected); return failures; } @@ -586,10 +585,10 @@ public class IeeeRecommendedTests { for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.nextUp(double)", - testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]); + testCases[i][0], Math::nextUp, testCases[i][1]); failures+=Tests.test("StrictMath.nextUp(double)", - testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]); + testCases[i][0], StrictMath::nextUp, testCases[i][1]); } return failures; @@ -665,10 +664,10 @@ public class IeeeRecommendedTests { for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.nextDown(double)", - testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]); + testCases[i][0], Math::nextDown, testCases[i][1]); failures+=Tests.test("StrictMath.nextDown(double)", - testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]); + testCases[i][0], StrictMath::nextDown, testCases[i][1]); } return failures; @@ -906,12 +905,12 @@ public class IeeeRecommendedTests { // copySign(magnitude, sign) failures+=Tests.test("MathcopySign(double,double)", testCases[i][m],testCases[j][n], - Math.copySign(testCases[i][m], testCases[j][n]), + Math::copySign, (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) ); failures+=Tests.test("StrictMath.copySign(double,double)", testCases[i][m],testCases[j][n], - StrictMath.copySign(testCases[i][m], testCases[j][n]), + StrictMath::copySign, (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) ); } } @@ -932,7 +931,7 @@ public class IeeeRecommendedTests { failures+=Tests.test("StrictMath.copySign(double,double)", testCases[i][m], NaNs[j], - StrictMath.copySign(testCases[i][m], NaNs[j]), + StrictMath::copySign, Math.abs(testCases[i][m]) ); } } @@ -1384,13 +1383,13 @@ public class IeeeRecommendedTests { int failures=0; failures+=Tests.test("Math.ulp(double)", d, - Math.ulp(d), expected); + Math::ulp, expected); failures+=Tests.test("Math.ulp(double)", minus_d, - Math.ulp(minus_d), expected); + Math::ulp, expected); failures+=Tests.test("StrictMath.ulp(double)", d, - StrictMath.ulp(d), expected); + StrictMath::ulp, expected); failures+=Tests.test("StrictMath.ulp(double)", minus_d, - StrictMath.ulp(minus_d), expected); + StrictMath::ulp, expected); return failures; } @@ -1664,16 +1663,16 @@ public class IeeeRecommendedTests { for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.signum(double)", - testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]); + testCases[i][0], Math::signum, testCases[i][1]); failures+=Tests.test("StrictMath.signum(double)", - testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]); + testCases[i][0], StrictMath::signum, testCases[i][1]); } return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testFloatGetExponent(); diff --git a/test/jdk/java/lang/Math/Log10Tests.java b/test/jdk/java/lang/Math/Log10Tests.java index 7bc75644f2b155c953b761af836e9e31272d8261..dbdd7c141794f98dc8ba5a4e8ca7107fab32f846 100644 --- a/test/jdk/java/lang/Math/Log10Tests.java +++ b/test/jdk/java/lang/Math/Log10Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 4074599 4939441 * @summary Tests for {Math, StrictMath}.log10 - * @author Joseph D. Darcy */ public class Log10Tests { @@ -41,11 +40,8 @@ public class Log10Tests { static int testLog10Case(double input, double expected) { int failures=0; - failures+=Tests.test("Math.log10(double)", input, - Math.log10(input), expected); - - failures+=Tests.test("StrictMath.log10(double)", input, - StrictMath.log10(input), expected); + failures+=Tests.test("Math.log10", input, Math::log10, expected); + failures+=Tests.test("StrictMath.log10", input, StrictMath::log10, expected); return failures; } @@ -121,8 +117,6 @@ public class Log10Tests { "log(input)/log(10): log10(input) = " + result + "\tlog(input)/log(10) = " + expected); } - - } } } @@ -205,7 +199,7 @@ public class Log10Tests { return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testLog10(); @@ -216,5 +210,4 @@ public class Log10Tests { throw new RuntimeException(); } } - } diff --git a/test/jdk/java/lang/Math/Log1pTests.java b/test/jdk/java/lang/Math/Log1pTests.java index 021a651ed1870727609d5f38fb34b40e7665210f..2fa7ddec4429d353b5cfac8b4cf47879dfa35d82 100644 --- a/test/jdk/java/lang/Math/Log1pTests.java +++ b/test/jdk/java/lang/Math/Log1pTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ * @run main Log1pTests * @bug 4851638 4939441 8078672 * @summary Tests for {Math, StrictMath}.log1p (use -Dseed=X to set PRNG seed) - * @author Joseph D. Darcy * @key randomness */ @@ -167,9 +166,7 @@ public class Log1pTests { pcNeighborsStrictLog1p[j+1] ); } - } - } } @@ -185,16 +182,12 @@ public class Log1pTests { double expected, double ulps) { int failures = 0; - failures += Tests.testUlpDiff("Math.lop1p(double", - input, Math.log1p(input), - expected, ulps); - failures += Tests.testUlpDiff("StrictMath.log1p(double", - input, StrictMath.log1p(input), - expected, ulps); + failures += Tests.testUlpDiff("Math.lop1p", input, Math::log1p, expected, ulps); + failures += Tests.testUlpDiff("StrictMath.log1p", input, StrictMath::log1p, expected, ulps); return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testLog1p(); diff --git a/test/jdk/java/lang/Math/PowTests.java b/test/jdk/java/lang/Math/PowTests.java index 88221c5415a4eb76ed321dd71d92c1173b2770c4..8f8ea098bdaef20ace6fd930b28cb770dbbab8ab 100644 --- a/test/jdk/java/lang/Math/PowTests.java +++ b/test/jdk/java/lang/Math/PowTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 4984407 5033578 8134795 * @summary Tests for {Math, StrictMath}.pow - * @author Joseph D. Darcy */ public class PowTests { @@ -35,35 +34,29 @@ public class PowTests { static int testPowCase(double input1, double input2, double expected) { int failures = 0; - failures += Tests.test("StrictMath.pow(double, double)", input1, input2, - StrictMath.pow(input1, input2), expected); - failures += Tests.test("Math.pow(double, double)", input1, input2, - Math.pow(input1, input2), expected); + failures += Tests.test("StrictMath.pow", input1, input2, StrictMath::pow, expected); + failures += Tests.test("Math.pow", input1, input2, Math::pow, expected); return failures; } - static int testStrictPowCase(double input1, double input2, double expected) { int failures = 0; - failures += Tests.test("StrictMath.pow(double, double)", input1, input2, - StrictMath.pow(input1, input2), expected); + failures += Tests.test("StrictMath.pow", input1, input2, + StrictMath::pow, expected); return failures; } static int testNonstrictPowCase(double input1, double input2, double expected) { int failures = 0; - failures += Tests.test("Math.pow(double, double)", input1, input2, - Math.pow(input1, input2), expected); + failures += Tests.test("Math.pow", input1, input2, + Math::pow, expected); return failures; } static int testStrictVsNonstrictPowCase(double input1, double input2) { - double smResult = StrictMath.pow(input1, input2); - double mResult = Math.pow(input1, input2); return Tests.testUlpDiff( "StrictMath.pow(double, double) vs Math.pow(double, double)", - input1, input2, mResult, smResult, 2.0 - ); + input1, input2, Math::pow, StrictMath.pow(input1, input2), 2.0); } /* @@ -313,7 +306,7 @@ public class PowTests { } } - public static void main(String [] argv) { + public static void main(String... argv) { int failures = 0; failures += testPow(); diff --git a/test/jdk/java/lang/Math/Rint.java b/test/jdk/java/lang/Math/Rint.java index 53e4d26b13134887e8cf924649af15c1db1230e0..a9c6952b90b1227906f2e3c78fa03da20e611447 100644 --- a/test/jdk/java/lang/Math/Rint.java +++ b/test/jdk/java/lang/Math/Rint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * 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,17 +32,14 @@ public class Rint { static int testRintCase(double input, double expected) { int failures = 0; double result; - failures += Tests.test("Math.rint", input, Math.rint(input), expected); - failures += Tests.test("Math.rint", -input, Math.rint(-input), -expected); - failures += Tests.test("StrictMath.rint", - input, StrictMath.rint(input), expected); - failures += Tests.test("StrictMath.rint", -input, - StrictMath.rint(-input), -expected); + failures += Tests.test("Math.rint", input, Math::rint, expected); + failures += Tests.test("Math.rint", -input, Math::rint, -expected); + failures += Tests.test("StrictMath.rint", input, StrictMath::rint, expected); + failures += Tests.test("StrictMath.rint", -input, StrictMath::rint, -expected); return failures; } - - public static void main(String args[]) { + public static void main(String... args) { int failures = 0; double twoToThe52 = Math.scalb(1.0, 52); // 2^52 @@ -97,7 +94,6 @@ public class Rint { }; - for(int i = 0; i < testCases.length; i++) { failures += testRintCase(testCases[i][0], testCases[i][1]); } diff --git a/test/jdk/java/lang/Math/RoundTests.java b/test/jdk/java/lang/Math/RoundTests.java index cae190f9770218e9f924f5fd8aabc447245527d8..0a51b426386b8ded5d75a43dfaefa84759430a33 100644 --- a/test/jdk/java/lang/Math/RoundTests.java +++ b/test/jdk/java/lang/Math/RoundTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,8 +64,8 @@ public class RoundTests { private static int testNearHalfCases(double input, double expected) { int failures = 0; - failures += Tests.test("Math.round", input, Math.round(input), expected); - failures += Tests.test("StrictMath.round", input, StrictMath.round(input), expected); + failures += Tests.test("Math.round", input, Math::round, expected); + failures += Tests.test("StrictMath.round", input, StrictMath::round, expected); return failures; } @@ -145,20 +145,14 @@ public class RoundTests { failures += Tests.test("Math.round", -Float.MIN_VALUE, Math.round(-Float.MIN_VALUE), 0.0F); - failures += Tests.test("Math.round", Double.NaN, Math.round(Double.NaN), 0.0); - failures += Tests.test("Math.round", Double.POSITIVE_INFINITY, - Math.round(Double.POSITIVE_INFINITY), Long.MAX_VALUE); - failures += Tests.test("Math.round", Double.NEGATIVE_INFINITY, - Math.round(Double.NEGATIVE_INFINITY), Long.MIN_VALUE); - failures += Tests.test("Math.round", -(double)Long.MIN_VALUE, - Math.round(-(double)Long.MIN_VALUE), Long.MAX_VALUE); - failures += Tests.test("Math.round", (double) Long.MIN_VALUE, - Math.round((double) Long.MIN_VALUE), Long.MIN_VALUE); - failures += Tests.test("Math.round", 0, Math.round(0), 0.0); - failures += Tests.test("Math.round", Double.MIN_VALUE, - Math.round(Double.MIN_VALUE), 0.0); - failures += Tests.test("Math.round", -Double.MIN_VALUE, - Math.round(-Double.MIN_VALUE), 0.0); + failures += Tests.test("Math.round", Double.NaN, Math::round, 0.0); + failures += Tests.test("Math.round", Double.POSITIVE_INFINITY, Math::round, Long.MAX_VALUE); + failures += Tests.test("Math.round", Double.NEGATIVE_INFINITY, Math::round, Long.MIN_VALUE); + failures += Tests.test("Math.round", -(double)Long.MIN_VALUE, Math::round, Long.MAX_VALUE); + failures += Tests.test("Math.round", (double) Long.MIN_VALUE, Math::round, Long.MIN_VALUE); + failures += Tests.test("Math.round", 0, Math::round, 0.0); + failures += Tests.test("Math.round", Double.MIN_VALUE, Math::round, 0.0); + failures += Tests.test("Math.round", -Double.MIN_VALUE, Math::round, 0.0); return failures; } diff --git a/test/jdk/java/lang/Math/SinCosCornerCasesTests.java b/test/jdk/java/lang/Math/SinCosCornerCasesTests.java index e144857443f9916b9fe10ea3cb19645113e58a69..225cdaebf0ef08a1be94cc1bbfba78794f097d26 100644 --- a/test/jdk/java/lang/Math/SinCosCornerCasesTests.java +++ b/test/jdk/java/lang/Math/SinCosCornerCasesTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ * @build Tests * @build SinCosCornerCasesTests * @run main SinCosCornerCasesTests - * @author Vivek Deshpande */ public class SinCosCornerCasesTests { @@ -1502,7 +1501,7 @@ public class SinCosCornerCasesTests { private static int testSinCase(double input, double bound1, double bound2) { int failures = 0; - failures += Tests.testBounds("Math.sin", input, Math.sin(input), bound1, bound2); + failures += Tests.testBounds("Math.sin", input, Math::sin, bound1, bound2); return failures; } @@ -2921,7 +2920,7 @@ public class SinCosCornerCasesTests { private static int testCosCase(double input, double bound1, double bound2) { int failures = 0; - failures += Tests.testBounds("Math.cos", input, Math.cos(input), bound1, bound2); + failures += Tests.testBounds("Math.cos", input, Math::cos, bound1, bound2); return failures; } } diff --git a/test/jdk/java/lang/Math/TanTests.java b/test/jdk/java/lang/Math/TanTests.java index f4ad1872238f3ce3f179d7ce15c2d92a937911ee..04ed7d47ed1ca0f055973b9a3f0dc488d5be06a3 100644 --- a/test/jdk/java/lang/Math/TanTests.java +++ b/test/jdk/java/lang/Math/TanTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 5033578 * @summary Tests for {Math, StrictMath}.tan - * @author Joseph D. Darcy */ public class TanTests { @@ -33,10 +32,8 @@ public class TanTests { static int testTanCase(double input, double expected, double ulps) { int failures = 0; - failures += Tests.testUlpDiff("StrictMath.tan(double, double)", input, - StrictMath.tan(input), expected, ulps); - failures += Tests.testUlpDiff("Math.tan(double, double)", input, - Math.tan(input), expected, ulps); + failures += Tests.testUlpDiff("StrictMath.tan", input, StrictMath::tan, expected, ulps); + failures += Tests.testUlpDiff("Math.tan", input, Math::tan, expected, ulps); return failures; } @@ -173,7 +170,7 @@ public class TanTests { return failures; } - public static void main(String [] argv) { + public static void main(String... argv) { int failures = 0; failures += testTan(); diff --git a/test/jdk/java/lang/Math/Tests.java b/test/jdk/java/lang/Math/Tests.java index 98821142fc971f085b60ca0a8edca6d9a0f411f7..f1de6319a9ed3438a64ac2969ab37a3b483a7c78 100644 --- a/test/jdk/java/lang/Math/Tests.java +++ b/test/jdk/java/lang/Math/Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,10 @@ * questions. */ +import java.util.function.DoubleBinaryOperator; +import java.util.function.DoubleUnaryOperator; +import java.util.function.DoubleToIntFunction; + /* * Shared static test methods for numerical tests. Sharing these * helper test methods avoids repeated functions in the various test @@ -235,9 +239,9 @@ public class Tests { "\texpected " + expected + "\n" + "\tgot " + result + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, double input, @@ -248,9 +252,9 @@ public class Tests { "\texpected " + expected + "\n" + "\tgot " + result + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, float input1, float input2, @@ -291,6 +295,13 @@ public class Tests { return 0; } + public static int test(String testName, + double input, + DoubleToIntFunction func, + int expected) { + return test(testName, input, func.applyAsInt(input), expected); + } + public static int test(String testName, double input, int result, int expected) { if (expected != result) { @@ -299,9 +310,9 @@ public class Tests { "\texpected " + expected + "\n" + "\tgot " + result + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, float input, @@ -312,11 +323,17 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } + public static int test(String testName, + double input, + DoubleUnaryOperator func, + double expected) { + return test(testName, input, func.applyAsDouble(input), expected); + } public static int test(String testName, double input, double result, double expected) { @@ -326,9 +343,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, @@ -341,9 +358,16 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } + } + + public static int test(String testName, + double input1, double input2, + DoubleBinaryOperator func, + double expected) { + return test(testName, input1, input2, func.applyAsDouble(input1, input2), expected); } public static int test(String testName, @@ -356,9 +380,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, @@ -371,9 +395,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, @@ -386,9 +410,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, @@ -402,9 +426,21 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } + } + + @FunctionalInterface + public interface DoubleTernaryOperator { + double applyAsDouble(double input1, double input2, double input3); + } + + public static int test(String testName, + double input1, double input2, double input3, + DoubleTernaryOperator func, double expected) { + return test(testName, input1, input2, input3, func.applyAsDouble(input1, input2, input3), expected); + } public static int test(String testName, @@ -418,9 +454,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } static int testUlpCore(double result, double expected, double ulps) { @@ -442,14 +478,19 @@ public class Tests { // fail if greater than or unordered !(Math.abs( difference/Math.ulp(expected) ) <= Math.abs(ulps)) ) { return 1; - } - else + } else { return 0; + } } } } // One input argument. + public static int testUlpDiff(String testName, double input, + DoubleUnaryOperator func, double expected, double ulps) { + return testUlpDiff(testName, input, func.applyAsDouble(input), expected, ulps); + } + public static int testUlpDiff(String testName, double input, double result, double expected, double ulps) { int code = testUlpCore(result, expected, ulps); @@ -464,6 +505,11 @@ public class Tests { } // Two input arguments. + public static int testUlpDiff(String testName, double input1, double input2, + DoubleBinaryOperator func, double expected, double ulps) { + return testUlpDiff(testName, input1, input2, func.applyAsDouble(input1, input2), expected, ulps); + } + public static int testUlpDiff(String testName, double input1, double input2, double result, double expected, double ulps) { int code = testUlpCore(result, expected, ulps); @@ -481,6 +527,14 @@ public class Tests { // For a successful test, the result must be within the ulp bound of // expected AND the result must have absolute value less than or // equal to absBound. + public static int testUlpDiffWithAbsBound(String testName, double input, + DoubleUnaryOperator func, double expected, + double ulps, double absBound) { + return testUlpDiffWithAbsBound(testName, input, + func.applyAsDouble(input), expected, + ulps, absBound); + } + public static int testUlpDiffWithAbsBound(String testName, double input, double result, double expected, double ulps, double absBound) { @@ -506,6 +560,14 @@ public class Tests { // For a successful test, the result must be within the ulp bound of // expected AND the result must have absolute value greater than // or equal to the lowerBound. + public static int testUlpDiffWithLowerBound(String testName, double input, + DoubleUnaryOperator func, double expected, + double ulps, double lowerBound) { + return testUlpDiffWithLowerBound(testName, input, + func.applyAsDouble(input), expected, + ulps, lowerBound); + } + public static int testUlpDiffWithLowerBound(String testName, double input, double result, double expected, double ulps, double lowerBound) { @@ -513,8 +575,9 @@ public class Tests { if (!(result >= lowerBound) && !Double.isNaN(expected)) { code = 1; - } else + } else { code = testUlpCore(result, expected, ulps); + } if (code == 1) { System.err.println("Failure for " + testName + @@ -528,6 +591,11 @@ public class Tests { return code; } + public static int testTolerance(String testName, double input, + DoubleUnaryOperator func, double expected, double tolerance) { + return testTolerance(testName, input, func.applyAsDouble(input), expected, tolerance); + + } public static int testTolerance(String testName, double input, double result, double expected, double tolerance) { if (Double.compare(expected, result ) != 0) { @@ -544,13 +612,18 @@ public class Tests { return 1; } return 0; - } - else + } else { return 0; + } } // For a successful test, the result must be within the upper and // lower bounds. + public static int testBounds(String testName, double input, DoubleUnaryOperator func, + double bound1, double bound2) { + return testBounds(testName, input, func.applyAsDouble(input), bound1, bound2); + } + public static int testBounds(String testName, double input, double result, double bound1, double bound2) { if ((result >= bound1 && result <= bound2) || diff --git a/test/jdk/java/lang/Math/WorstCaseTests.java b/test/jdk/java/lang/Math/WorstCaseTests.java index be98d977aabbc926df801d6debf56f13ce7fac0f..2cffa8fabfc0deec5c5137d4250f177de2b7db09 100644 --- a/test/jdk/java/lang/Math/WorstCaseTests.java +++ b/test/jdk/java/lang/Math/WorstCaseTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ * @build WorstCaseTests * @run main WorstCaseTests * @run main/othervm -Xcomp WorstCaseTests - * @author Joseph D. Darcy */ /** @@ -126,8 +125,8 @@ public class WorstCaseTests { private static int testExpCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.exp", input, Math.exp(input), expected, out); - failures += Tests.testBounds("StrictMath.exp", input, StrictMath.exp(input), expected, out); + failures += Tests.testBounds("Math.exp", input, Math::exp, expected, out); + failures += Tests.testBounds("StrictMath.exp", input, StrictMath::exp, expected, out); return failures; } @@ -158,8 +157,8 @@ public class WorstCaseTests { private static int testLogCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.log", input, Math.log(input), expected, out); - failures += Tests.testBounds("StrictMath.log", input, StrictMath.log(input), expected, out); + failures += Tests.testBounds("Math.log", input, Math::log, expected, out); + failures += Tests.testBounds("StrictMath.log", input, StrictMath::log, expected, out); return failures; } @@ -191,8 +190,8 @@ public class WorstCaseTests { private static int testSinCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.sin", input, Math.sin(input), expected, out); - failures += Tests.testBounds("StrictMath.sin", input, StrictMath.sin(input), expected, out); + failures += Tests.testBounds("Math.sin", input, Math::sin, expected, out); + failures += Tests.testBounds("StrictMath.sin", input, StrictMath::sin, expected, out); return failures; } @@ -223,8 +222,8 @@ public class WorstCaseTests { private static int testAsinCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.asin", input, Math.asin(input), expected, out); - failures += Tests.testBounds("StrictMath.asin", input, StrictMath.asin(input), expected, out); + failures += Tests.testBounds("Math.asin", input, Math::asin, expected, out); + failures += Tests.testBounds("StrictMath.asin", input, StrictMath::asin, expected, out); return failures; } @@ -256,8 +255,8 @@ public class WorstCaseTests { private static int testCosCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.cos", input, Math.cos(input), expected, out); - failures += Tests.testBounds("StrictMath.cos", input, StrictMath.cos(input), expected, out); + failures += Tests.testBounds("Math.cos", input, Math::cos, expected, out); + failures += Tests.testBounds("StrictMath.cos", input, StrictMath::cos, expected, out); return failures; } @@ -280,8 +279,8 @@ public class WorstCaseTests { private static int testAcosCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.acos", input, Math.acos(input), expected, out); - failures += Tests.testBounds("StrictMath.acos", input, StrictMath.acos(input), expected, out); + failures += Tests.testBounds("Math.acos", input, Math::acos, expected, out); + failures += Tests.testBounds("StrictMath.acos", input, StrictMath::acos, expected, out); return failures; } @@ -309,8 +308,8 @@ public class WorstCaseTests { private static int testTanCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.tan", input, Math.tan(input), expected, out); - failures += Tests.testBounds("StrictMath.tan", input, StrictMath.tan(input), expected, out); + failures += Tests.testBounds("Math.tan", input, Math::tan, expected, out); + failures += Tests.testBounds("StrictMath.tan", input, StrictMath::tan, expected, out); return failures; } @@ -341,8 +340,8 @@ public class WorstCaseTests { private static int testAtanCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.atan", input, Math.atan(input), expected, out); - failures += Tests.testBounds("StrictMath.atan", input, StrictMath.atan(input), expected, out); + failures += Tests.testBounds("Math.atan", input, Math::atan, expected, out); + failures += Tests.testBounds("StrictMath.atan", input, StrictMath::atan, expected, out); return failures; } @@ -367,8 +366,8 @@ public class WorstCaseTests { private static int testPow2Case(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.pow2", input, Math.pow(2, input), expected, out); - failures += Tests.testBounds("StrictMath.pow2", input, StrictMath.pow(2, input), expected, out); + failures += Tests.testBounds("Math.pow2", input, d -> Math.pow(2, d), expected, out); + failures += Tests.testBounds("StrictMath.pow2", input, d -> StrictMath.pow(2, d), expected, out); return failures; } @@ -400,8 +399,8 @@ public class WorstCaseTests { private static int testSinhCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.sinh", input, Math.sinh(input), expected, out); - failures += Tests.testBounds("StrictMath.sinh", input, StrictMath.sinh(input), expected, out); + failures += Tests.testBounds("Math.sinh", input, Math::sinh, expected, out); + failures += Tests.testBounds("StrictMath.sinh", input, StrictMath::sinh, expected, out); return failures; } @@ -428,8 +427,8 @@ public class WorstCaseTests { private static int testCoshCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.cosh", input, Math.cosh(input), expected, out); - failures += Tests.testBounds("StrictMath.cosh", input, StrictMath.cosh(input), expected, out); + failures += Tests.testBounds("Math.cosh", input, Math::cosh, expected, out); + failures += Tests.testBounds("StrictMath.cosh", input, StrictMath::cosh, expected, out); return failures; } } diff --git a/test/jdk/java/lang/Object/FinalizationOption.java b/test/jdk/java/lang/Object/FinalizationOption.java new file mode 100644 index 0000000000000000000000000000000000000000..7d50412e26f07a0d21b067ad7bf1b4e8dced9216 --- /dev/null +++ b/test/jdk/java/lang/Object/FinalizationOption.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8276422 + * @summary add command-line option to disable finalization + * @run main/othervm FinalizationOption yes + * @run main/othervm --finalization=enabled FinalizationOption yes + * @run main/othervm --finalization=disabled FinalizationOption no + */ +public class FinalizationOption { + static volatile boolean finalizerWasCalled = false; + + @SuppressWarnings("deprecation") + protected void finalize() { + finalizerWasCalled = true; + } + + static void create() { + new FinalizationOption(); + } + + /** + * Checks whether the finalizer thread is or is not running. The finalizer thread + * is a thread in the root thread group whose named is "Finalizer". + * @param expected boolean indicating whether a finalizer thread should exist + * @return boolean indicating whether the expectation was met + */ + static boolean checkFinalizerThread(boolean expected) { + ThreadGroup root = Thread.currentThread().getThreadGroup(); + for (ThreadGroup parent = root; + parent != null; + root = parent, parent = root.getParent()) + ; + + int nt = 100; + Thread[] threads; + while (true) { + threads = new Thread[nt]; + nt = root.enumerate(threads); + if (nt < threads.length) + break; + threads = new Thread[nt + 100]; + } + + Thread ft = null; + for (int i = 0; i < nt; i++) { + if ("Finalizer".equals(threads[i].getName())) { + ft = threads[i]; + break; + } + } + + String msg = (ft == null) ? "(none)" : ft.toString(); + boolean passed = (ft != null) == expected; + System.out.printf("Finalizer thread. Expected: %s Actual: %s %s%n", + expected, msg, passed ? "Passed." : "FAILED!"); + return passed; + } + + /** + * Checks whether there was a call to the finalize() method. + * @param expected boolean whether finalize() should be called + * @return boolean indicating whether the expecation was met + */ + static boolean checkFinalizerCalled(boolean expected) { + create(); + for (int i = 0; i < 100; i++) { + System.gc(); + try { + Thread.sleep(10L); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + if (finalizerWasCalled) { + break; + } + } + boolean passed = (expected == finalizerWasCalled); + System.out.printf("Call to finalize(). Expected: %s Actual: %s %s%n", + expected, finalizerWasCalled, + passed ? "Passed." : "FAILED!"); + return passed; + } + + public static void main(String[] args) { + boolean finalizationEnabled = switch (args[0]) { + case "yes" -> true; + case "no" -> false; + default -> { + throw new AssertionError("usage: FinalizationOption yes|no"); + } + }; + + boolean threadPass = checkFinalizerThread(finalizationEnabled); + boolean calledPass = checkFinalizerCalled(finalizationEnabled); + + if (!threadPass || !calledPass) + throw new AssertionError("Test failed."); + } +} diff --git a/test/jdk/java/lang/Object/InvalidFinalizationOption.java b/test/jdk/java/lang/Object/InvalidFinalizationOption.java new file mode 100644 index 0000000000000000000000000000000000000000..c5cca549ead095f62a251d65cfb80ae78799d201 --- /dev/null +++ b/test/jdk/java/lang/Object/InvalidFinalizationOption.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8276422 + * @summary Invalid/missing values for the finalization option should be rejected + * @library /test/lib + * @run driver InvalidFinalizationOption + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class InvalidFinalizationOption { + public static void main(String[] args) throws Exception { + record TestData(String arg, String expected) { } + + TestData[] testData = { + new TestData("--finalization", "Unrecognized option"), + new TestData("--finalization=", "Invalid finalization value"), + new TestData("--finalization=azerty", "Invalid finalization value") + }; + + for (var data : testData) { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(data.arg); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain(data.expected); + output.shouldHaveExitValue(1); + } + } +} diff --git a/test/jdk/java/lang/StrictMath/CubeRootTests.java b/test/jdk/java/lang/StrictMath/CubeRootTests.java index f4a3978075d4ad1dee36c1fbfe885c1dce4d3f95..0423f1ff087532a1ff3c7291501d651e8d8af0cc 100644 --- a/test/jdk/java/lang/StrictMath/CubeRootTests.java +++ b/test/jdk/java/lang/StrictMath/CubeRootTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ * @build CubeRootTests * @run main CubeRootTests * @summary Tests specifically for StrictMath.cbrt - * @author Joseph D. Darcy */ import jdk.test.lib.RandomFactory; @@ -71,9 +70,9 @@ public class CubeRootTests { double minus_expected = -expected; failures+=Tests.test("StrictMath.cbrt(double)", input, - StrictMath.cbrt(input), expected); + StrictMath::cbrt, expected); failures+=Tests.test("StrictMath.cbrt(double)", minus_input, - StrictMath.cbrt(minus_input), minus_expected); + StrictMath::cbrt, minus_expected); return failures; } diff --git a/test/jdk/java/lang/StrictMath/Expm1Tests.java b/test/jdk/java/lang/StrictMath/Expm1Tests.java index 368d1025993c42c5a6fb412a304e28613c80b67d..e7d9696535d9b9033abc075b5bc86f9c250e8434 100644 --- a/test/jdk/java/lang/StrictMath/Expm1Tests.java +++ b/test/jdk/java/lang/StrictMath/Expm1Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ * @test * @bug 4851638 * @summary Tests for StrictMath.expm1 - * @author Joseph D. Darcy + * @compile -Xdiags:verbose Expm1Tests.java + * @run main Expm1Tests */ /** @@ -44,7 +45,7 @@ public class Expm1Tests { static int testExpm1Case(double input, double expected) { return Tests.test("StrictMath.expm1(double)", input, - StrictMath.expm1(input), expected); + StrictMath::expm1, expected); } static int testExpm1() { diff --git a/test/jdk/java/lang/StrictMath/HyperbolicTests.java b/test/jdk/java/lang/StrictMath/HyperbolicTests.java index 37b851dd795e85b366bd4ad7c4bf903e71b5b049..4dfc7596d38d40fa1b2f5d0e4960c42d5ab19cf1 100644 --- a/test/jdk/java/lang/StrictMath/HyperbolicTests.java +++ b/test/jdk/java/lang/StrictMath/HyperbolicTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 4851625 * @summary Tests for StrictMath.{sinh, cosh, tanh} - * @author Joseph D. Darcy */ /** @@ -45,17 +44,17 @@ public class HyperbolicTests { static int testSinhCase(double input, double expected) { return Tests.test("StrictMath.sinh(double)", input, - StrictMath.sinh(input), expected); + StrictMath::sinh, expected); } static int testCoshCase(double input, double expected) { return Tests.test("StrictMath.cosh(double)", input, - StrictMath.cosh(input), expected); + StrictMath::cosh, expected); } static int testTanhCase(double input, double expected) { return Tests.test("StrictMath.tanh(double)", input, - StrictMath.tanh(input), expected); + StrictMath::tanh, expected); } static int testSinh() { diff --git a/test/jdk/java/lang/StrictMath/HypotTests.java b/test/jdk/java/lang/StrictMath/HypotTests.java index 0b1dd41691fda3a90c5a553d09cf3f00d84750e5..c714dcf1499dd76f7b2c74c2b19e1e54cea29b76 100644 --- a/test/jdk/java/lang/StrictMath/HypotTests.java +++ b/test/jdk/java/lang/StrictMath/HypotTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ * @build FdlibmTranslit * @build HypotTests * @run main HypotTests - * @author Joseph D. Darcy */ import jdk.test.lib.RandomFactory; @@ -72,28 +71,28 @@ public class HypotTests { static int testHypotCase(double input1, double input2, double expected) { int failures = 0; failures += Tests.test("StrictMath.hypot(double)", input1, input2, - StrictMath.hypot(input1, input2), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", input2, input1, - StrictMath.hypot(input2, input1), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", -input1, input2, - StrictMath.hypot(-input1, input2), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", input2, -input1, - StrictMath.hypot(input2, -input1), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", input1, -input2, - StrictMath.hypot(input1, -input2), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", -input2, input1, - StrictMath.hypot(-input2, input1), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", -input1, -input2, - StrictMath.hypot(-input1, -input2), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", -input2, -input1, - StrictMath.hypot(-input2, -input1), expected); + StrictMath::hypot, expected); return failures; } diff --git a/test/jdk/java/lang/StrictMath/Log10Tests.java b/test/jdk/java/lang/StrictMath/Log10Tests.java index af07eac7e66f084478c51526ac0769bbd4e8c772..eed6e8a510637c89297b6a8f813f6ffe1c3a8076 100644 --- a/test/jdk/java/lang/StrictMath/Log10Tests.java +++ b/test/jdk/java/lang/StrictMath/Log10Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 4074599 * @summary Tests for StrictMath.log10 - * @author Joseph D. Darcy */ @@ -45,7 +44,7 @@ public class Log10Tests { static int testLog10Case(double input, double expected) { return Tests.test("StrictMath.log10(double)", input, - StrictMath.log10(input), expected); + StrictMath::log10, expected); } static int testLog10() { diff --git a/test/jdk/java/lang/StrictMath/Log1pTests.java b/test/jdk/java/lang/StrictMath/Log1pTests.java index 91b0835222c88553c650895053c05f3a7818add3..9cd03d3306af62f71c452418699aeef324bf73fe 100644 --- a/test/jdk/java/lang/StrictMath/Log1pTests.java +++ b/test/jdk/java/lang/StrictMath/Log1pTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 4851638 * @summary Tests for StrictMath.log1p - * @author Joseph D. Darcy */ /** @@ -44,7 +43,7 @@ public class Log1pTests { static int testLog1pCase(double input, double expected) { return Tests.test("StrictMath.log1p(double)", input, - StrictMath.log1p(input), expected); + StrictMath::log1p, expected); } static int testLog1p() { diff --git a/test/jdk/java/lang/StrictMath/PowTests.java b/test/jdk/java/lang/StrictMath/PowTests.java index 338cf42d54c8736f9d1fc23f50c4ccc2145b38a4..2936dfdf247087c0988f24c3df25a1bc101fa343 100644 --- a/test/jdk/java/lang/StrictMath/PowTests.java +++ b/test/jdk/java/lang/StrictMath/PowTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ * @test * @bug 8136874 * @summary Tests for StrictMath.pow - * @author Joseph D. Darcy */ /** @@ -295,7 +294,7 @@ public class PowTests { private static int testPowCase(double input1, double input2, double expected) { int failures = 0; failures += Tests.test("StrictMath.pow(double)", input1, input2, - StrictMath.pow(input1, input2), expected); + StrictMath::pow, expected); return failures; } } diff --git a/test/jdk/java/lang/StrictMath/Tests.java b/test/jdk/java/lang/StrictMath/Tests.java index 0513cb70d1e82fc11267d227cbf5eb4879dba087..a675b2e961719e3c9d60c9ce3a2de7700ac0f95c 100644 --- a/test/jdk/java/lang/StrictMath/Tests.java +++ b/test/jdk/java/lang/StrictMath/Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,33 +21,48 @@ * questions. */ +import java.util.function.DoubleBinaryOperator; +import java.util.function.DoubleUnaryOperator; + /* - * - * * Shared static test method for StrictMath tests. */ - public class Tests { private Tests(){} - static int test(String testName, - double input, - double result, - double expected) { + public static int test(String testName, + double input, + DoubleUnaryOperator func, + double expected) { + return test(testName, input, func.applyAsDouble(input), expected); + } + + public static int test(String testName, + double input, + double result, + double expected) { if (Double.compare(expected, result ) != 0) { System.err.println("Failure for " + testName + ":\n" + "\tFor input " + input + "\t(" + Double.toHexString(input) + ")\n" + "\texpected " + expected + "\t(" + Double.toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + Double.toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } + } + + public static int test(String testName, + double input1, + double input2, + DoubleBinaryOperator func, + double expected) { + return test(testName, input1, input2, func.applyAsDouble(input1, input2), expected); } - static int test(String testName, double input1, double input2, - double result, double expected) { + public static int test(String testName, double input1, double input2, + double result, double expected) { if (Double.compare(expected, result ) != 0) { System.err.println("Failure for " + testName + ":\n" + "\tFor input " + input1 + "\t(" + Double.toHexString(input1) + "), " + @@ -55,9 +70,9 @@ public class Tests { "\texpected " + expected + "\t(" + Double.toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + Double.toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } /** diff --git a/test/jdk/java/lang/StringBuffer/HugeCapacity.java b/test/jdk/java/lang/StringBuffer/HugeCapacity.java index d30d2d945b5f404525be91459a6c6047a7e6383e..e3c98496c50c80fc59ed25ee09b0ad350554a3dd 100644 --- a/test/jdk/java/lang/StringBuffer/HugeCapacity.java +++ b/test/jdk/java/lang/StringBuffer/HugeCapacity.java @@ -26,8 +26,8 @@ * @bug 8218227 * @summary StringBuilder/StringBuffer constructor throws confusing * NegativeArraySizeException - * @requires (sun.arch.data.model == "64" & os.maxMemory >= 6G) - * @run main/othervm -Xms5G -Xmx5G HugeCapacity + * @requires (sun.arch.data.model == "64" & os.maxMemory >= 8G) + * @run main/othervm -Xms6G -Xmx6G HugeCapacity */ public class HugeCapacity { diff --git a/test/jdk/java/lang/StringBuilder/HugeCapacity.java b/test/jdk/java/lang/StringBuilder/HugeCapacity.java index 9f1617a9dd241e956da6670cb5af95350d8cb576..a584ce1f07a9d25dfa0f32f042b96c0a799c8fc4 100644 --- a/test/jdk/java/lang/StringBuilder/HugeCapacity.java +++ b/test/jdk/java/lang/StringBuilder/HugeCapacity.java @@ -26,9 +26,9 @@ * @bug 8149330 8218227 * @summary Capacity should not get close to Integer.MAX_VALUE unless * necessary - * @requires (sun.arch.data.model == "64" & os.maxMemory >= 6G) - * @run main/othervm -Xms5G -Xmx5G -XX:+CompactStrings HugeCapacity true - * @run main/othervm -Xms5G -Xmx5G -XX:-CompactStrings HugeCapacity false + * @requires (sun.arch.data.model == "64" & os.maxMemory >= 8G) + * @run main/othervm -Xms6G -Xmx6G -XX:+CompactStrings HugeCapacity true + * @run main/othervm -Xms6G -Xmx6G -XX:-CompactStrings HugeCapacity false */ public class HugeCapacity { diff --git a/test/jdk/java/lang/annotation/TypeAnnotationReflection.java b/test/jdk/java/lang/annotation/TypeAnnotationReflection.java index 64234ccc215ff48deb78e6c9cf696648e3827ccf..9c0a101c2b6af872f8f7856a984ab67677b4ea69 100644 --- a/test/jdk/java/lang/annotation/TypeAnnotationReflection.java +++ b/test/jdk/java/lang/annotation/TypeAnnotationReflection.java @@ -39,7 +39,8 @@ public class TypeAnnotationReflection { testReturnType(); testNested(); testArray(); - testRunException(); + testRunException(TestClassException.class.getDeclaredMethod("foo", (Class<?>[])null)); + testRunException(Outer2.TestClassException2.class.getDeclaredConstructor(Outer2.class)); testClassTypeVarBounds(); testMethodTypeVarBounds(); testFields(); @@ -142,9 +143,8 @@ public class TypeAnnotationReflection { check(((TypeAnno)annos[0]).value().equals("return4")); } - private static void testRunException() throws Exception { - Method m = TestClassException.class.getDeclaredMethod("foo", (Class<?>[])null); - AnnotatedType[] ts = m.getAnnotatedExceptionTypes(); + private static void testRunException(Executable e) throws Exception { + AnnotatedType[] ts = e.getAnnotatedExceptionTypes(); check(ts.length == 3); AnnotatedType t; @@ -624,6 +624,15 @@ abstract class TestClassException { } } +class Outer2 { + abstract class TestClassException2 { + public TestClassException2() throws + @TypeAnno("RE") @TypeAnno2("RE2") RuntimeException, + NullPointerException, + @TypeAnno("AIOOBE") ArrayIndexOutOfBoundsException {} + } +} + abstract class TestClassTypeVarAndField <T extends @TypeAnno("Object1") Object & @TypeAnno("Runnable1") @TypeAnno2("Runnable2") Runnable, @TypeAnno("EE")EE extends @TypeAnno2("EEBound") Runnable, V > { diff --git a/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java b/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java index 1417eb427a00d3dd3235f3c29a64311b3d247da4..a4fdab2ec4709fe58e444445a671338d2f115108 100644 --- a/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java +++ b/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Red Hat, Inc. All rights reserved. + * Copyright (c) 2020, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -264,6 +264,36 @@ * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest */ +/* + * @test + * @summary Test for fInst.getObjectSize with large arrays + * @library /test/lib + * @requires vm.bits == 64 + * @requires vm.debug + * @requires os.maxMemory >= 10G + * + * @build sun.hotspot.WhiteBox + * @run build GetObjectSizeIntrinsicsTest + * @run shell MakeJAR.sh basicAgent + * + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * + * @run main/othervm -Xmx8g + * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -Xint + * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large + * + * @run main/othervm -Xmx8g + * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -Xbatch -XX:TieredStopAtLevel=1 + * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large + * + * @run main/othervm -Xmx8g + * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -Xbatch -XX:-TieredCompilation + * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large + */ + import java.util.*; import jdk.test.lib.Platform; @@ -271,18 +301,27 @@ import sun.hotspot.WhiteBox; public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase { - static final Boolean compressedOops = WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompressedOops"); - static final int REF_SIZE = (compressedOops == null || compressedOops == true) ? 4 : 8; + static final Boolean COMPRESSED_OOPS = WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompressedOops"); + static final long REF_SIZE = (COMPRESSED_OOPS == null || COMPRESSED_OOPS == true) ? 4 : 8; static final Long align = WhiteBox.getWhiteBox().getIntxVMFlag("ObjectAlignmentInBytes"); static final int OBJ_ALIGN = (align == null ? 8 : align.intValue()); - public GetObjectSizeIntrinsicsTest(String name) { + static final int SMALL_ARRAY_SIZE = 1024; + + // These should overflow 4G size boundary + static final int LARGE_INT_ARRAY_SIZE = 1024*1024*1024 + 1024; + static final int LARGE_OBJ_ARRAY_SIZE = (4096/(int)REF_SIZE)*1024*1024 + 1024; + + final String mode; + + public GetObjectSizeIntrinsicsTest(String name, String mode) { super(name); + this.mode = mode; } public static void main(String[] args)throws Throwable { - new GetObjectSizeIntrinsicsTest(args[0]).runTest(); + new GetObjectSizeIntrinsicsTest(args[0], (args.length >= 2 ? args[1] : "")).runTest(); } public static final int ITERS = 200_000; @@ -312,30 +351,35 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase testSize_localObject(); testSize_fieldObject(); - testSize_newSmallByteArray(); - testSize_localSmallByteArray(); - testSize_fieldSmallByteArray(); + testSize_newSmallIntArray(); + testSize_localSmallIntArray(); + testSize_fieldSmallIntArray(); testSize_newSmallObjArray(); testSize_localSmallObjArray(); testSize_fieldSmallObjArray(); + if (mode.equals("large")) { + testSize_localLargeIntArray(); + testSize_localLargeObjArray(); + } + testNulls(); } - private static int roundUp(int v, int a) { + private static long roundUp(long v, long a) { return (v + a - 1) / a * a; } private void testSize_newObject() { - int expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); + long expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(new Object())); } } private void testSize_localObject() { - int expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); + long expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); Object o = new Object(); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(o)); @@ -345,60 +389,76 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase static Object staticO = new Object(); private void testSize_fieldObject() { - int expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); + long expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(staticO)); } } - private void testSize_newSmallByteArray() { - int expected = roundUp(1024 + 16, OBJ_ALIGN); + private void testSize_newSmallIntArray() { + long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { - assertEquals(expected, fInst.getObjectSize(new byte[1024])); + assertEquals(expected, fInst.getObjectSize(new int[SMALL_ARRAY_SIZE])); } } - private void testSize_localSmallByteArray() { - byte[] arr = new byte[1024]; - int expected = roundUp(arr.length + 16, OBJ_ALIGN); + private void testSize_localSmallIntArray() { + int[] arr = new int[SMALL_ARRAY_SIZE]; + long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(arr)); } } - static byte[] smallArr = new byte[1024]; + static int[] smallArr = new int[SMALL_ARRAY_SIZE]; - private void testSize_fieldSmallByteArray() { - int expected = roundUp(smallArr.length + 16, OBJ_ALIGN); + private void testSize_fieldSmallIntArray() { + long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(smallArr)); } } private void testSize_newSmallObjArray() { - int expected = roundUp(1024*REF_SIZE + 16, OBJ_ALIGN); + long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { - assertEquals(expected, fInst.getObjectSize(new Object[1024])); + assertEquals(expected, fInst.getObjectSize(new Object[SMALL_ARRAY_SIZE])); } } private void testSize_localSmallObjArray() { - Object[] arr = new Object[1024]; - int expected = roundUp(arr.length*REF_SIZE + 16, OBJ_ALIGN); + Object[] arr = new Object[SMALL_ARRAY_SIZE]; + long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(arr)); } } - static Object[] smallObjArr = new Object[1024]; + static Object[] smallObjArr = new Object[SMALL_ARRAY_SIZE]; private void testSize_fieldSmallObjArray() { - int expected = roundUp(smallArr.length*REF_SIZE + 16, OBJ_ALIGN); + long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(smallObjArr)); } } + private void testSize_localLargeIntArray() { + int[] arr = new int[LARGE_INT_ARRAY_SIZE]; + long expected = roundUp(4L*LARGE_INT_ARRAY_SIZE + 16, OBJ_ALIGN); + for (int c = 0; c < ITERS; c++) { + assertEquals(expected, fInst.getObjectSize(arr)); + } + } + + private void testSize_localLargeObjArray() { + Object[] arr = new Object[LARGE_OBJ_ARRAY_SIZE]; + long expected = roundUp(REF_SIZE*LARGE_OBJ_ARRAY_SIZE + 16, OBJ_ALIGN); + for (int c = 0; c < ITERS; c++) { + assertEquals(expected, fInst.getObjectSize(arr)); + } + } + private void testNulls() { for (int c = 0; c < ITERS; c++) { try { diff --git a/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java b/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ef7e3818eb086de859f905a2b9d946ecfeb70bca --- /dev/null +++ b/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8240908 + * + * @library /test/lib + * @run compile -g -parameters RetransformWithMethodParametersTest.java + * @run shell MakeJAR.sh retransformAgent + * + * @run main/othervm -javaagent:retransformAgent.jar RetransformWithMethodParametersTest + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.ProtectionDomain; +import java.util.Arrays; + +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.util.ClassTransformer; + +/* + * The test verifies Instrumentation.retransformClasses() (and JVMTI function RetransformClasses) + * correctly handles MethodParameter attribute: + * 1) classfile bytes passed to transformers (and JVMTI ClassFileLoadHook event callback) contain the attribute; + * 2) the attribute is updated if new version has the attribute with different values; + * 3) the attribute is removed if new version doesn't contain the attribute. + */ + +// See ClassTransformer.transform(int) comment for @1 tag explanations. +class MethodParametersTarget { + // The class contains the only method, so we don't have issue with method sorting + // and ClassFileReconstituter should restore the same bytes as original classbytes. + public void method1( + int intParam1, String stringParam1 // @1 commentout + // @1 uncomment int intParam2, String stringParam2 + ) + { + // @1 uncomment System.out.println(stringParam2); // change CP + } +} + +public class RetransformWithMethodParametersTest extends ATransformerManagementTestCase { + + public static void main (String[] args) throws Throwable { + ATestCaseScaffold test = new RetransformWithMethodParametersTest(); + test.runTest(); + } + + private String targetClassName = "MethodParametersTarget"; + private String classFileName = targetClassName + ".class"; + private String sourceFileName = "RetransformWithMethodParametersTest.java"; + private Class targetClass; + private byte[] originalClassBytes; + + private byte[] seenClassBytes; + private byte[] newClassBytes; + + public RetransformWithMethodParametersTest() throws Throwable { + super("RetransformWithMethodParametersTest"); + + File origClassFile = new File(System.getProperty("test.classes", "."), classFileName); + log("Reading test class from " + origClassFile); + originalClassBytes = Files.readAllBytes(origClassFile.toPath()); + log("Read " + originalClassBytes.length + " bytes."); + } + + private void log(Object o) { + System.out.println(String.valueOf(o)); + } + + private Parameter[] getTargetMethodParameters() throws ClassNotFoundException { + Class cls = Class.forName(targetClassName); + // the class contains 1 method (method1) + Method method = cls.getDeclaredMethods()[0]; + Parameter[] params = method.getParameters(); + log("Params of " + method.getName() + " method (" + params.length + "):"); + for (int i = 0; i < params.length; i++) { + log(" " + i + ": " + params[i].getName() + + " (" + (params[i].isNamePresent() ? "present" : "absent") + ")"); + } + return params; + } + + // Verifies MethodParameters attribute is present and contains the expected values. + private void verifyPresentMethodParams(String... expectedNames) throws Throwable { + Parameter[] params = getTargetMethodParameters(); + assertEquals(expectedNames.length, params.length); + for (int i = 0; i < params.length; i++) { + assertTrue(params[i].isNamePresent()); + assertEquals(expectedNames[i], params[i].getName()); + } + } + + // Verifies MethodParameters attribute is absent. + private void verifyAbsentMethodParams() throws Throwable { + Parameter[] params = getTargetMethodParameters(); + for (int i = 0; i < params.length; i++) { + assertTrue(!params[i].isNamePresent()); + } + } + + // Retransforms target class using provided class bytes; + // Returns class bytes passed to the transformer. + private byte[] retransform(byte[] classBytes) throws Throwable { + seenClassBytes = null; + newClassBytes = classBytes; + fInst.retransformClasses(targetClass); + assertTrue(targetClassName + " was not seen by transform()", seenClassBytes != null); + return seenClassBytes; + } + + // Prints dissassembled class bytes. + private void printDisassembled(String description, byte[] bytes) throws Exception { + log(description + " -------------------"); + + File f = new File(classFileName); + try (FileOutputStream fos = new FileOutputStream(f)) { + fos.write(bytes); + } + JDKToolLauncher javap = JDKToolLauncher.create("javap") + .addToolArg("-verbose") + .addToolArg("-p") // Shows all classes and members. + //.addToolArg("-c") // Prints out disassembled code + //.addToolArg("-s") // Prints internal type signatures. + .addToolArg(f.toString()); + ProcessBuilder pb = new ProcessBuilder(javap.getCommand()); + OutputAnalyzer out = ProcessTools.executeProcess(pb); + out.shouldHaveExitValue(0); + try { + Files.delete(f.toPath()); + } catch (Exception ex) { + // ignore + } + out.asLines().forEach(s -> log(s)); + log("=========================================="); + } + + // Verifies class bytes are equal. + private void compareClassBytes(byte[] expected, byte[] actual) throws Exception { + + int pos = Arrays.mismatch(expected, actual); + if (pos < 0) { + log("Class bytes are identical."); + return; + } + log("Class bytes are different."); + printDisassembled("expected", expected); + printDisassembled("expected", actual); + fail(targetClassName + " did not match .class file"); + } + + protected final void doRunTest() throws Throwable { + beVerbose(); + + ClassLoader loader = getClass().getClassLoader(); + targetClass = loader.loadClass(targetClassName); + // sanity check + assertEquals(targetClassName, targetClass.getName()); + // sanity check + verifyPresentMethodParams("intParam1", "stringParam1"); + + addTransformerToManager(fInst, new Transformer(), true); + + { + log("Testcase 1: ensure ClassFileReconstituter restores MethodParameters attribute"); + + byte[] classBytes = retransform(null); + compareClassBytes(originalClassBytes, classBytes); + + log(""); + } + + { + log("Testcase 2: redefine class with changed parameter names"); + + byte[] classBytes = Files.readAllBytes(Paths.get( + ClassTransformer.fromTestSource(sourceFileName) + .transform(1, targetClassName, "-g", "-parameters"))); + retransform(classBytes); + // MethodParameters attribute should be updated. + verifyPresentMethodParams("intParam2", "stringParam2"); + + log(""); + } + + { + log("Testcase 3: redefine class with no parameter names"); + // compile without "-parameters" + byte[] classBytes = Files.readAllBytes(Paths.get( + ClassTransformer.fromTestSource(sourceFileName) + .transform(1, targetClassName, "-g"))); + retransform(classBytes); + // MethodParameters attribute should be dropped. + verifyAbsentMethodParams(); + + log(""); + } + } + + + public class Transformer implements ClassFileTransformer { + public Transformer() { + } + + public String toString() { + return Transformer.this.getClass().getName(); + } + + public byte[] transform(ClassLoader loader, String className, + Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { + + if (className.equals(targetClassName)) { + log(this + ".transform() sees '" + className + + "' of " + classfileBuffer.length + " bytes."); + seenClassBytes = classfileBuffer; + if (newClassBytes != null) { + log(this + ".transform() sets new classbytes for '" + className + + "' of " + newClassBytes.length + " bytes."); + } + return newClassBytes; + } + + return null; + } + } +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java b/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java new file mode 100644 index 0000000000000000000000000000000000000000..6acd4fb30e1d9c444ef67a3bc36e09bb42eaf6f8 --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8280377 + * @build m1/* m2/* Unnamed + * @run testng/othervm m1/p1.Main + * @run testng/othervm Unnamed + * @summary Test MethodHandleProxies::asInterfaceInstance with a default + * method with varargs + */ diff --git a/test/jdk/java/lang/invoke/MethodHandlesProxiesTest.java b/test/jdk/java/lang/invoke/MethodHandleProxies/MethodHandlesProxiesTest.java similarity index 100% rename from test/jdk/java/lang/invoke/MethodHandlesProxiesTest.java rename to test/jdk/java/lang/invoke/MethodHandleProxies/MethodHandlesProxiesTest.java diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java b/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java new file mode 100644 index 0000000000000000000000000000000000000000..f42071f04275f3488efc5f2015cb2b9928a74328 --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleProxies; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; + +import static org.testng.Assert.*; + +/* + * Test MethodHandleProxies::asInterfaceInstance with an inaccessible interface + */ +public class Unnamed { + public static void main(String... args) throws Throwable { + MethodHandle target = MethodHandles.constant(String.class, "test"); + Class<?> intf = Class.forName("p2.TestIntf"); + Object t = MethodHandleProxies.asInterfaceInstance(intf, target); + + // verify that the caller has no access to the proxy created on an + // inaccessible interface + Method m = intf.getMethod("test", Object[].class); + assertFalse(m.canAccess(null)); + } +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java new file mode 100644 index 0000000000000000000000000000000000000000..1bdeddce28fd6bb01ddbf7f6c71c5c13f8999585 --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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. + */ +module m1 { + requires m2; + requires org.testng; + exports p1; +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..df71809996b3838ff43f753b48385893296eaabf --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package p1; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleProxies; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Arrays; +import java.util.stream.Collectors; + +import p2.TestIntf; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class Main { + public interface A { + default String aConcat(Object... objs) { return Arrays.deepToString(objs); } + } + + public interface B { + default String bConcat(Object[] objs) { return Arrays.deepToString(objs); } + } + + public interface C extends A, B { + String c(Object... objs); + } + + private static String concat(Object... objs) { + return Arrays.stream(objs).map(Object::toString).collect(Collectors.joining()); + } + + /* + * Test the invocation of default methods with varargs + */ + @Test + public static void testVarargsMethods() throws Throwable { + MethodHandle target = MethodHandles.lookup().findStatic(Main.class, + "concat", MethodType.methodType(String.class, Object[].class)); + C proxy = MethodHandleProxies.asInterfaceInstance(C.class, target); + + assertEquals(proxy.c("a", "b", "c"), "abc"); + assertEquals(proxy.aConcat("a", "b", "c"), "[a, b, c]"); + assertEquals(proxy.aConcat(new Object[] { "a", "b", "c" }), "[a, b, c]"); + assertEquals(proxy.bConcat(new Object[] { "a", "b", "c" }), "[a, b, c]"); + } + + /* + * Test the invocation of a default method of an accessible interface + */ + @Test + public static void modulePrivateInterface() { + MethodHandle target = MethodHandles.constant(String.class, "test"); + TestIntf t = MethodHandleProxies.asInterfaceInstance(TestIntf.class, target); + assertEquals(t.test(), "test"); + } +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java new file mode 100644 index 0000000000000000000000000000000000000000..1015757fc9c34eb90d6ae679be62bdf36c0f7699 --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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. + */ +module m2 { + exports p2 to m1; +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java new file mode 100644 index 0000000000000000000000000000000000000000..a87d248e0c8efbae08b47cacaa5ecd2765031ed5 --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package p2; + +public interface TestIntf { + String test(); +} diff --git a/test/jdk/java/lang/management/ThreadMXBean/ThreadLists.java b/test/jdk/java/lang/management/ThreadMXBean/ThreadLists.java index 433a3f54c0d158328562f09dc3280e388d502de6..cadfff1097cbc9dd7bcbefad9542dc6c12e04b78 100644 --- a/test/jdk/java/lang/management/ThreadMXBean/ThreadLists.java +++ b/test/jdk/java/lang/management/ThreadMXBean/ThreadLists.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. * 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,11 @@ /* * @test - * @bug 5047639 + * @bug 5047639 8132785 * @summary Check that the "java-level" APIs provide a consistent view of * the thread list + * @comment Must run in othervm mode to avoid interference from other tests. + * @run main/othervm ThreadLists */ import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; @@ -50,6 +52,19 @@ public class ThreadLists { // get the thread count int activeCount = top.activeCount(); + // Now enumerate to see if we find any extras yet. + // Ensure the array is big enough for a few extras. + Thread[] threads = new Thread[activeCount * 2]; + int newCount = top.enumerate(threads); + if (newCount != activeCount) { + System.out.println("Found different threads after enumeration:"); + } else { + System.out.println("Initial set of enumerated threads:"); + } + for (int i = 0; i < newCount; i++) { + System.out.println(" - Thread: " + threads[i].getName()); + } + Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces(); ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); @@ -68,6 +83,11 @@ public class ThreadLists { if (activeCount != threadIds.length) failed = true; if (failed) { + System.out.println("Set of stack-traced threads:"); + for (Thread t : stackTraces.keySet()) { + System.out.println(" - Thread: " + + (t != null ? t.getName() : "null!")); + } throw new RuntimeException("inconsistent results"); } } diff --git a/test/jdk/java/lang/reflect/IllegalArgumentsTest.java b/test/jdk/java/lang/reflect/IllegalArgumentsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0d699485f9103ad21711b9aeff195698c0f1c134 --- /dev/null +++ b/test/jdk/java/lang/reflect/IllegalArgumentsTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277964 + * @summary Test IllegalArgumentException be thrown when an argument is invalid + * @run testng/othervm IllegalArgumentsTest + */ + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import org.testng.annotations.Test; + +public class IllegalArgumentsTest { + static class T { + public T(int i) {} + + public static void m(int i) {} + + public void m1(String s) {} + } + + @Test + public void wrongArgumentType() throws ReflectiveOperationException { + for (int i = 0; i < 100_000; ++i) { + try { + Constructor<T> ctor = T.class.getConstructor(int.class); + ctor.newInstance(int.class); // wrong argument type + throw new RuntimeException("Expected IAE not thrown"); + } catch (IllegalArgumentException e) {} + } + + for (int i = 0; i < 100_000; ++i) { + try { + Method method = T.class.getMethod("m", int.class); + method.invoke(null, int.class); // wrong argument type + throw new RuntimeException("Expected IAE not thrown"); + } catch (IllegalArgumentException e) {} + } + } + + @Test + public void nullArguments() throws ReflectiveOperationException { + for (int i = 0; i < 100_000; ++i) { + try { + Constructor<T> ctor = T.class.getConstructor(int.class); + ctor.newInstance(new Object[] {null}); + throw new RuntimeException("Expected IAE not thrown"); + } catch (IllegalArgumentException e) {} + } + + for (int i = 0; i < 100_000; ++i) { + try { + Method method = T.class.getMethod("m", int.class); + method.invoke(null, new Object[] {null}); + throw new RuntimeException("Expected IAE not thrown"); + } catch (IllegalArgumentException e) {} + } + } + + @Test + public void illegalArguments() throws ReflectiveOperationException { + for (int i = 0; i < 100_000; ++i) { + try { + Constructor<T> ctor = T.class.getConstructor(int.class); + ctor.newInstance(new Object[] { 10, 20}); + throw new RuntimeException("Expected IAE not thrown"); + } catch (IllegalArgumentException e) {} + } + + for (int i = 0; i < 100_000; ++i) { + try { + Method method = T.class.getMethod("m", int.class); + method.invoke(null, new Object[] { 10, 20}); + throw new RuntimeException("Expected IAE not thrown"); + } catch (IllegalArgumentException e) {} + } + } + + @Test + public void wrongReceiver() throws ReflectiveOperationException { + for (int i = 0; i < 100_000; ++i) { + try { + Method method = T.class.getMethod("m1", String.class); + method.invoke(this, "bad receiver"); + throw new RuntimeException("Expected IAE not thrown"); + } catch (IllegalArgumentException e) {} + } + } +} diff --git a/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java b/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java index 9f625a34a93302b51770b31f1bdb05e79e338b62..85ee270244db8cffcbae9e0367a334a0a515339c 100644 --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @bug 8221530 + * @bug 8221530 8221642 * @summary Test uses custom launcher that starts VM using JNI that verifies * reflection API with null caller class * @library /test/lib @@ -61,7 +61,10 @@ public class CallerAccessTest { System.out.println("Launching: " + launcher + " shared library path: " + env.get(sharedLibraryPathEnvName)); - new OutputAnalyzer(pb.start()).shouldHaveExitValue(0); + new OutputAnalyzer(pb.start()) + .outputTo(System.out) + .errorTo(System.err) + .shouldHaveExitValue(0); } } diff --git a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c index c38a0cb094eb0f89793b56b030ef446ce36b4473..31710138aaca5cd11d607a780d5d657732cf15c6 100644 --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,9 +32,15 @@ static jclass iaeClass; static jmethodID mid_Class_forName; static jmethodID mid_Class_getField; static jmethodID mid_Field_get; +static jmethodID mid_Field_canAccess; +static jmethodID mid_Field_trySetAccessible; +static jmethodID mid_Field_setAccessible; int getField(JNIEnv *env, char* declaringClass_name, char* field_name); int checkAndClearIllegalAccessExceptionThrown(JNIEnv *env); +int setAccessible(JNIEnv *env, char* declaringClass_name, char* field_name); +int trySetAccessible(JNIEnv *env, char* declaringClass_name, char* field_name, jboolean canAccess); +int checkAccess(JNIEnv *env, char* declaringClass_name, char* field_name, jboolean canAccess); int main(int argc, char** args) { JavaVM *jvm; @@ -65,6 +71,12 @@ int main(int argc, char** args) { jclass fieldClass = (*env)->FindClass(env, "java/lang/reflect/Field"); mid_Field_get = (*env)->GetMethodID(env, fieldClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); assert(mid_Class_getField != NULL); + mid_Field_canAccess = (*env)->GetMethodID(env, fieldClass, "canAccess", "(Ljava/lang/Object;)Z"); + assert(mid_Field_canAccess != NULL); + mid_Field_setAccessible = (*env)->GetMethodID(env, fieldClass, "setAccessible", "(Z)V"); + assert(mid_Field_setAccessible != NULL); + mid_Field_trySetAccessible = (*env)->GetMethodID(env, fieldClass, "trySetAccessible", "()Z"); + assert(mid_Field_trySetAccessible != NULL); // can access to public member of an exported type if ((rc = getField(env, "java.lang.Integer", "TYPE")) != 0) { @@ -92,6 +104,32 @@ int main(int argc, char** args) { exit(-1); } + // expect IAE to jdk.internal.misc.Unsafe class + if ((rc = setAccessible(env, "jdk.internal.misc.Unsafe", "INVALID_FIELD_OFFSET")) == 0) { + printf("ERROR: IAE not thrown\n"); + exit(-1); + } + if (checkAndClearIllegalAccessExceptionThrown(env) != JNI_TRUE) { + printf("ERROR: exception is not an instance of IAE\n"); + exit(-1); + } + + if ((rc = trySetAccessible(env, "java.lang.reflect.Modifier", "PUBLIC", JNI_TRUE)) != 0) { + printf("ERROR: unexpected result from trySetAccessible on Modifier::PUBLIC field\n"); + exit(-1); + } + if ((rc = trySetAccessible(env, "jdk.internal.misc.Unsafe", "INVALID_FIELD_OFFSET", JNI_FALSE)) != 0) { + printf("ERROR: unexpected result from trySetAccessible on Unsafe public field\n"); + exit(-1); + } + + if ((rc = checkAccess(env, "java.lang.reflect.Modifier", "PUBLIC", JNI_TRUE)) != 0) { + printf("ERROR: unexpected result from trySetAccessible on Modifier::PUBLIC field\n"); + exit(-1); + } + if ((rc = checkAccess(env, "jdk.internal.misc.Unsafe", "INVALID_FIELD_OFFSET", JNI_FALSE)) != 0) { + printf("ERROR: unexpected result from trySetAccessible on Unsafe public field\n"); + } (*jvm)->DestroyJavaVM(jvm); return 0; } @@ -127,3 +165,74 @@ int getField(JNIEnv *env, char* declaringClass_name, char* field_name) { return 0; } +int setAccessible(JNIEnv *env, char* declaringClass_name, char* field_name) { + jobject c = (*env)->CallStaticObjectMethod(env, classClass, mid_Class_forName, + (*env)->NewStringUTF(env, declaringClass_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 1; + } + + jobject f = (*env)->CallObjectMethod(env, c, mid_Class_getField, (*env)->NewStringUTF(env, field_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 2; + } + + (*env)->CallVoidMethod(env, f, mid_Field_setAccessible, JNI_TRUE); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 3; + } + return 0; +} + +int trySetAccessible(JNIEnv *env, char* declaringClass_name, char* field_name, jboolean canAccess) { + jobject c = (*env)->CallStaticObjectMethod(env, classClass, mid_Class_forName, + (*env)->NewStringUTF(env, declaringClass_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 1; + } + + jobject f = (*env)->CallObjectMethod(env, c, mid_Class_getField, (*env)->NewStringUTF(env, field_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 2; + } + + jboolean rc = (*env)->CallBooleanMethod(env, f, mid_Field_trySetAccessible); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 3; + } + if (rc != canAccess) { + return 4; + } + return 0; +} + +int checkAccess(JNIEnv *env, char* declaringClass_name, char* field_name, jboolean canAccess) { + jobject c = (*env)->CallStaticObjectMethod(env, classClass, mid_Class_forName, + (*env)->NewStringUTF(env, declaringClass_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 1; + } + + jobject f = (*env)->CallObjectMethod(env, c, mid_Class_getField, (*env)->NewStringUTF(env, field_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 2; + } + + jboolean rc = (*env)->CallBooleanMethod(env, f, mid_Field_canAccess, NULL); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 3; + } + if (rc != canAccess) { + return 4; + } + return 0; +} diff --git a/test/jdk/java/lang/runtime/ObjectMethodsTest.java b/test/jdk/java/lang/runtime/ObjectMethodsTest.java index dba92eb32ff77092053c52e542ef393eb865e4dd..0a7741c02e1788cd1ffb653bd90c727edbe88e2b 100644 --- a/test/jdk/java/lang/runtime/ObjectMethodsTest.java +++ b/test/jdk/java/lang/runtime/ObjectMethodsTest.java @@ -166,6 +166,7 @@ public class ObjectMethodsTest { assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, npt.mn(), npt.mt(), null, "x;y", C.ACCESSORS)); assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, npt.mn(), null, C.class, "x;y", C.ACCESSORS)); assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, null, npt.mt(), C.class, "x;y", C.ACCESSORS)); + assertThrows(NPE, () -> ObjectMethods.bootstrap(null, npt.mn(), npt.mt(), C.class, "x;y", C.ACCESSORS)); } } diff --git a/test/jdk/java/net/DatagramSocket/SendDatagramToBadAddress.java b/test/jdk/java/net/DatagramSocket/SendDatagramToBadAddress.java index 0656dca908393a54a98e4b23e09ff88c4c258aae..b0c0afdbd61188bc36e7ff0884d31672535e5f3a 100644 --- a/test/jdk/java/net/DatagramSocket/SendDatagramToBadAddress.java +++ b/test/jdk/java/net/DatagramSocket/SendDatagramToBadAddress.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * * @summary DatagramSocket.send should throw exception when connected * to an invalid destination (on platforms that support it). - * @run main/othervm SendDatagramToBadAddress + * @run main/othervm SendDatagramToBadAddress -d */ import java.net.*; @@ -70,6 +70,8 @@ public class SendDatagramToBadAddress { for (int i=0; i<loop; i++) { try { server.receive (pack); + print("received data from address " + pack.getAddress() + + " port " + pack.getPort()); } catch (Exception e) { if (expectError) { print ("Got expected error: " + e); @@ -116,12 +118,15 @@ public class SendDatagramToBadAddress { DatagramPacket p; byte[] buf; int port = serversock.getLocalPort (); + print("tests will be run against destination address " + addr + " port " + port); final int loop = 5; Server s = new Server (serversock); int i; print ("Checking send to connected address ..."); sock.connect(addr, port); + print("socket is locally bound to address " + sock.getLocalAddress() + + " port " + sock.getLocalPort()); for (i = 0; i < loop; i++) { try { @@ -170,6 +175,8 @@ public class SendDatagramToBadAddress { sock.send(p); p = new DatagramPacket(buf, buf.length, addr, port); sock.receive (p); + print("(unexpectedly) received data from address " + p.getAddress() + + " port " + p.getPort() + " on attempt " + i); } catch (InterruptedIOException ex) { print ("socket timeout"); } catch (Exception ex) { diff --git a/test/jdk/java/net/ServerSocket/IsClosedAfterAsyncClose.java b/test/jdk/java/net/ServerSocket/IsClosedAfterAsyncClose.java new file mode 100644 index 0000000000000000000000000000000000000000..1b77793290091ff6b2f9967ef279e8ecbe52606b --- /dev/null +++ b/test/jdk/java/net/ServerSocket/IsClosedAfterAsyncClose.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8278339 + * @summary Test that ServerSocket::isClosed returns true after async close + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; + +public class IsClosedAfterAsyncClose { + + private static final int ITERATIONS = 100; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < ITERATIONS; i++) { + System.out.printf("Test %d...%n", i); + + // create listener bound to the loopback address + ServerSocket listener = new ServerSocket(); + InetAddress loopback = InetAddress.getLoopbackAddress(); + listener.bind(new InetSocketAddress(loopback, 0)); + + // task to close listener after a delay + Runnable closeListener = () -> { + try { + Thread.sleep(100); + listener.close(); + } catch (Exception e) { + e.printStackTrace(); + } + }; + + // main thread blocks in accept. When listener is closed then accept + // should wakeup with an IOException and isClosed should be true. + try (listener) { + Thread closer = new Thread(closeListener); + closer.start(); + try { + while (true) { + Socket s = listener.accept(); + // close spurious connection + s.close(); + } + } catch (IOException ioe) { + if (!listener.isClosed()) { + throw new RuntimeException("isClosed returned false!!"); + } + } finally { + closer.join(); + } + } + } + } +} + diff --git a/test/jdk/java/net/httpclient/LineBodyHandlerTest.java b/test/jdk/java/net/httpclient/LineBodyHandlerTest.java index 601f1ad408022e3af8ef814ce4e716d417e93882..10717a848bd40b0a2aa35f1f438cb03edee89fda 100644 --- a/test/jdk/java/net/httpclient/LineBodyHandlerTest.java +++ b/test/jdk/java/net/httpclient/LineBodyHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,7 @@ import static org.testng.Assert.assertTrue; * java.logging * jdk.httpserver * @library /test/lib http2/server - * @build Http2TestServer LineBodyHandlerTest HttpServerAdapters + * @build Http2TestServer LineBodyHandlerTest HttpServerAdapters ReferenceTracker * @build jdk.test.lib.net.SimpleSSLContext * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:DiagnoseSyncOnValueBasedClasses=1 LineBodyHandlerTest */ @@ -101,6 +101,10 @@ public class LineBodyHandlerTest implements HttpServerAdapters { String http2URI; String https2URI; + final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; + final AtomicInteger clientCount = new AtomicInteger(); + HttpClient sharedClient; + @DataProvider(name = "uris") public Object[][] variants() { return new Object[][]{ @@ -189,10 +193,14 @@ public class LineBodyHandlerTest implements HttpServerAdapters { } HttpClient newClient() { - return HttpClient.newBuilder() + if (sharedClient != null) { + return sharedClient; + } + clientCount.incrementAndGet(); + return sharedClient = TRACKER.track(HttpClient.newBuilder() .sslContext(sslContext) .proxy(Builder.NO_PROXY) - .build(); + .build()); } @Test(dataProvider = "uris") @@ -695,10 +703,21 @@ public class LineBodyHandlerTest implements HttpServerAdapters { @AfterTest public void teardown() throws Exception { + sharedClient = null; + try { + System.gc(); + Thread.sleep(200); + } catch (InterruptedException io) { + // don't care; + } + AssertionError fail = TRACKER.check(500); + System.out.printf("Tear down: %s client created.%n", clientCount.get()); + System.err.printf("Tear down: %s client created.%n", clientCount.get()); httpTestServer.stop(); httpsTestServer.stop(); http2TestServer.stop(); https2TestServer.stop(); + if (fail != null) throw fail; } static void printBytes(PrintStream out, String prefix, byte[] bytes) { diff --git a/test/jdk/java/net/httpclient/ManyRequests.java b/test/jdk/java/net/httpclient/ManyRequests.java index f79d565162ad8e18730855e886c70d1d363406f6..296377441a73faa12e9ba10a5452c8602bda7169 100644 --- a/test/jdk/java/net/httpclient/ManyRequests.java +++ b/test/jdk/java/net/httpclient/ManyRequests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * 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,13 +32,13 @@ * @compile ../../../com/sun/net/httpserver/LogFilter.java * @compile ../../../com/sun/net/httpserver/EchoHandler.java * @compile ../../../com/sun/net/httpserver/FileServerHandler.java - * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests - * @run main/othervm/timeout=40 -Dtest.insertDelay=true ManyRequests - * @run main/othervm/timeout=40 -Dtest.chunkSize=64 ManyRequests - * @run main/othervm/timeout=40 -Dtest.insertDelay=true -Dtest.chunkSize=64 ManyRequests + * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl,channel ManyRequests + * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=channel -Dtest.insertDelay=true ManyRequests + * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=channel -Dtest.chunkSize=64 ManyRequests + * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=channel -Dtest.insertDelay=true -Dtest.chunkSize=64 ManyRequests * @summary Send a large number of requests asynchronously */ - // * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests + // * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl,channel ManyRequests import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsParameters; @@ -47,6 +47,7 @@ import com.sun.net.httpserver.HttpExchange; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; @@ -54,13 +55,18 @@ import java.net.http.HttpClient; import java.net.http.HttpClient.Builder; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.time.Duration; import java.util.Arrays; import java.util.Formatter; import java.util.HashMap; import java.util.LinkedList; +import java.util.Map; import java.util.Random; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; @@ -68,17 +74,27 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; import java.util.logging.Level; import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; import javax.net.ssl.SSLContext; + +import jdk.test.lib.Platform; +import jdk.test.lib.RandomFactory; import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; public class ManyRequests { - volatile static int counter = 0; + static final int MAX_COUNT = 20; + static final int MAX_LIMIT = 40; + static final AtomicInteger COUNT = new AtomicInteger(); + static final AtomicInteger LIMIT = new AtomicInteger(MAX_LIMIT); + static final Random RANDOM = RandomFactory.getRandom(); public static void main(String[] args) throws Exception { Logger logger = Logger.getLogger("com.sun.net.httpserver"); logger.setLevel(Level.ALL); logger.info("TEST"); + Stream.of(Logger.getLogger("").getHandlers()).forEach((h) -> h.setLevel(Level.ALL)); System.out.println("Sending " + REQUESTS + " requests; delay=" + INSERT_DELAY + ", chunks=" + CHUNK_SIZE @@ -106,14 +122,14 @@ public class ManyRequests { } //static final int REQUESTS = 1000; - static final int REQUESTS = 20; + static final int REQUESTS = MAX_COUNT; static final boolean INSERT_DELAY = Boolean.getBoolean("test.insertDelay"); static final int CHUNK_SIZE = Math.max(0, Integer.parseInt(System.getProperty("test.chunkSize", "0"))); static final boolean XFIXED = Boolean.getBoolean("test.XFixed"); static class TestEchoHandler extends EchoHandler { - final Random rand = jdk.test.lib.RandomFactory.getRandom(); + final Random rand = RANDOM; @Override public void handle(HttpExchange e) throws IOException { System.out.println("Server: received " + e.getRequestURI()); @@ -139,60 +155,126 @@ public class ManyRequests { } } + static String now(long start) { + long elapsed = System.nanoTime() - start; + long ms = elapsed / 1000_000L; + long s = ms / 1000L; + if (s == 0) return ms + "ms: "; + return s + "s, " + (ms - s * 1000L) + "ms: "; + } + + static String failure(Throwable t) { + String s = "\n\t failed: " + t; + for (t = t.getCause(); t != null ; t = t.getCause()) { + s = s + "\n\t\t Caused by: " + t; + } + return s; + } + static void test(HttpsServer server, HttpClient client) throws Exception { int port = server.getAddress().getPort(); - URI baseURI = new URI("https://localhost:" + port + "/foo/x"); + + URI baseURI = URIBuilder.newBuilder() + .scheme("https") + .host(InetAddress.getLoopbackAddress().getHostName()) + .port(port) + .path("/foo/x").build(); server.createContext("/foo", new TestEchoHandler()); server.start(); - RequestLimiter limiter = new RequestLimiter(40); - Random rand = new Random(); - CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS]; - HashMap<HttpRequest,byte[]> bodies = new HashMap<>(); - - for (int i=0; i<REQUESTS; i++) { - byte[] buf = new byte[(i+1)*CHUNK_SIZE+i+1]; // different size bodies - rand.nextBytes(buf); - URI uri = new URI(baseURI.toString() + String.valueOf(i+1)); - HttpRequest r = HttpRequest.newBuilder(uri) - .header("XFixed", "true") - .POST(BodyPublishers.ofByteArray(buf)) - .build(); - bodies.put(r, buf); - - results[i] = - limiter.whenOkToSend() - .thenCompose((v) -> { - System.out.println("Client: sendAsync: " + r.uri()); - return client.sendAsync(r, BodyHandlers.ofByteArray()); - }) - .thenCompose((resp) -> { - limiter.requestComplete(); - if (resp.statusCode() != 200) { - String s = "Expected 200, got: " + resp.statusCode(); - System.out.println(s + " from " - + resp.request().uri().getPath()); - return completedWithIOException(s); - } else { - counter++; - System.out.println("Result (" + counter + ") from " - + resp.request().uri().getPath()); - } - return CompletableFuture.completedStage(resp.body()) - .thenApply((b) -> new Pair<>(resp, b)); - }) - .thenAccept((pair) -> { - HttpRequest request = pair.t.request(); - byte[] requestBody = bodies.get(request); - check(Arrays.equals(requestBody, pair.u), - "bodies not equal:[" + bytesToHexString(requestBody) - + "] [" + bytesToHexString(pair.u) + "]"); - - }); - } + // This loop implements a retry mechanism to work around an issue + // on some systems (observed on Windows 10) that seem to be trying to + // throttle the number of connections that can be made concurrently by + // rejecting connection attempts. + // On the first iteration of this loop, we will attempt 20 concurrent + // requests. If this fails with ConnectException, we will retry the + // 20 requests, but limiting the concurrency to 10 (LIMIT <- 10). + // If this fails again, the test will fail. + boolean done = false; + LOOP: do { + RequestLimiter limiter = new RequestLimiter(LIMIT.get()); + Random rand = RANDOM; + CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS]; + Map<HttpRequest,byte[]> bodies = new ConcurrentHashMap<>(); + + long start = System.nanoTime(); + + for (int i = 0; i < REQUESTS; i++) { + byte[] buf = new byte[(i + 1) * CHUNK_SIZE + i + 1]; // different size bodies + rand.nextBytes(buf); + URI uri = new URI(baseURI.toString() + String.valueOf(i + 1)); + HttpRequest r = HttpRequest.newBuilder(uri) + .header("XFixed", "true") + .POST(BodyPublishers.ofByteArray(buf)) + .build(); + bodies.put(r, buf); + + results[i] = + limiter.whenOkToSend() + .thenCompose((v) -> { + System.out.println("Client: sendAsync: " + r.uri()); + return client.sendAsync(r, BodyHandlers.ofByteArray()); + }) + .handle((resp, t) -> { + limiter.requestComplete(); + CompletionStage<Pair<HttpResponse<byte[]>, byte[]>> res; + String now = now(start); + if (t == null) { + if (resp.statusCode() != 200) { + String s = "Expected 200, got: " + resp.statusCode(); + System.out.println(now + s + " from " + + resp.request().uri().getPath()); + res = completedWithIOException(s); + return res; + } else { + int counter = COUNT.incrementAndGet(); + System.out.println(now + "Result (" + counter + ") from " + + resp.request().uri().getPath()); + } + res = CompletableFuture.completedStage(resp.body()) + .thenApply((b) -> new Pair<>(resp, b)); + return res; + } else { + int counter = COUNT.incrementAndGet(); + System.out.println(now + "Result (" + counter + ") from " + + r.uri().getPath() + + failure(t)); + res = CompletableFuture.failedFuture(t); + return res; + } + }) + .thenCompose(c -> c) + .thenAccept((pair) -> { + HttpRequest request = pair.t.request(); + byte[] requestBody = bodies.get(request); + check(Arrays.equals(requestBody, pair.u), + "bodies not equal:[" + bytesToHexString(requestBody) + + "] [" + bytesToHexString(pair.u) + "]"); + + }); + } + + // wait for them all to complete and throw exception in case of err + try { + CompletableFuture.allOf(results).join(); + done = true; + } catch (CompletionException e) { + if (!Platform.isWindows()) throw e; + if (LIMIT.get() < REQUESTS) throw e; + Throwable cause = e; + while ((cause = cause.getCause()) != null) { + if (cause instanceof ConnectException) { + // try again, limit concurrency by half + COUNT.set(0); + LIMIT.set(REQUESTS/2); + System.out.println("*** Retrying due to " + cause); + continue LOOP; + } + } + throw e; + } + } while (!done); - // wait for them all to complete and throw exception in case of error - CompletableFuture.allOf(results).join(); } static <T> CompletableFuture<T> completedWithIOException(String message) { @@ -213,13 +295,7 @@ public class ManyRequests { return sb.toString(); } - static final class Pair<T,U> { - Pair(T t, U u) { - this.t = t; this.u = u; - } - T t; - U u; - } + record Pair<T,U>(T t, U u) { } /** * A simple limiter for controlling the number of requests to be run in diff --git a/test/jdk/java/net/httpclient/ManyRequests2.java b/test/jdk/java/net/httpclient/ManyRequests2.java index b0eee6e3be413b3be44dbf858635928958989009..49e7f758f7c14cee5916a8041df775bcdb33069e 100644 --- a/test/jdk/java/net/httpclient/ManyRequests2.java +++ b/test/jdk/java/net/httpclient/ManyRequests2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,10 +33,14 @@ * @compile ../../../com/sun/net/httpserver/EchoHandler.java * @compile ../../../com/sun/net/httpserver/FileServerHandler.java * @build ManyRequests ManyRequests2 - * @run main/othervm/timeout=40 -Dtest.XFixed=true ManyRequests2 - * @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.insertDelay=true ManyRequests2 - * @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.chunkSize=64 ManyRequests2 + * @run main/othervm/timeout=40 -Dtest.XFixed=true + * -Djdk.httpclient.HttpClient.log=channel ManyRequests2 + * @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.insertDelay=true + * -Djdk.httpclient.HttpClient.log=channel ManyRequests2 + * @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.chunkSize=64 + * -Djdk.httpclient.HttpClient.log=channel ManyRequests2 * @run main/othervm/timeout=40 -Djdk.internal.httpclient.debug=true + * -Djdk.httpclient.HttpClient.log=channel * -Dtest.XFixed=true -Dtest.insertDelay=true * -Dtest.chunkSize=64 ManyRequests2 * @summary Send a large number of requests asynchronously. diff --git a/test/jdk/java/net/httpclient/ManyRequestsLegacy.java b/test/jdk/java/net/httpclient/ManyRequestsLegacy.java index b8d296087b9584cd37c1eb97c37e0487942f158a..0e9aba5deafa7df8dba718ae3db84ab184f7c7c7 100644 --- a/test/jdk/java/net/httpclient/ManyRequestsLegacy.java +++ b/test/jdk/java/net/httpclient/ManyRequestsLegacy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HostnameVerifier; + import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsParameters; import com.sun.net.httpserver.HttpsServer; @@ -50,12 +51,18 @@ import com.sun.net.httpserver.HttpExchange; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URI; import java.net.URLConnection; +import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; @@ -73,12 +80,20 @@ import java.util.LinkedList; import java.util.Random; import java.util.logging.Logger; import java.util.logging.Level; + +import jdk.test.lib.Platform; +import jdk.test.lib.RandomFactory; import jdk.test.lib.net.SimpleSSLContext; import static java.net.Proxy.NO_PROXY; public class ManyRequestsLegacy { - volatile static int counter = 0; + static final int MAX_COUNT = 20; + static final int MAX_LIMIT = 40; + static final AtomicInteger COUNT = new AtomicInteger(); + static final AtomicInteger LIMIT = new AtomicInteger(MAX_LIMIT); + static final Random RANDOM = RandomFactory.getRandom(); + public static void main(String[] args) throws Exception { Logger logger = Logger.getLogger("com.sun.net.httpserver"); @@ -110,7 +125,7 @@ public class ManyRequestsLegacy { } //static final int REQUESTS = 1000; - static final int REQUESTS = 20; + static final int REQUESTS = MAX_COUNT; static final boolean INSERT_DELAY = Boolean.getBoolean("test.insertDelay"); static final int CHUNK_SIZE = Math.max(0, Integer.parseInt(System.getProperty("test.chunkSize", "0"))); @@ -194,7 +209,7 @@ public class ManyRequestsLegacy { } static class TestEchoHandler extends EchoHandler { - final Random rand = new Random(); + final Random rand = RANDOM; @Override public void handle(HttpExchange e) throws IOException { System.out.println("Server: received " + e.getRequestURI()); @@ -220,60 +235,119 @@ public class ManyRequestsLegacy { } } + static String now(long start) { + long elapsed = System.nanoTime() - start; + long ms = elapsed / 1000_000L; + long s = ms / 1000L; + if (s == 0) return ms + "ms: "; + return s + "s, " + (ms - s * 1000L) + "ms: "; + } + + static String failure(Throwable t) { + String s = "\n\t failed: " + t; + for (t = t.getCause(); t != null ; t = t.getCause()) { + s = s + "\n\t\t Caused by: " + t; + } + return s; + } + static void test(HttpsServer server, LegacyHttpClient client) throws Exception { int port = server.getAddress().getPort(); URI baseURI = new URI("https://localhost:" + port + "/foo/x"); server.createContext("/foo", new TestEchoHandler()); server.start(); - RequestLimiter limiter = new RequestLimiter(40); - Random rand = new Random(); - CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS]; - HashMap<HttpRequest,byte[]> bodies = new HashMap<>(); - - for (int i=0; i<REQUESTS; i++) { - byte[] buf = new byte[(i+1)*CHUNK_SIZE+i+1]; // different size bodies - rand.nextBytes(buf); - URI uri = new URI(baseURI.toString() + String.valueOf(i+1)); - HttpRequest r = HttpRequest.newBuilder(uri) - .header("XFixed", "true") - .POST(BodyPublishers.ofByteArray(buf)) - .build(); - bodies.put(r, buf); - - results[i] = - limiter.whenOkToSend() - .thenCompose((v) -> { - System.out.println("Client: sendAsync: " + r.uri()); - return client.sendAsync(r, buf); - }) - .thenCompose((resp) -> { - limiter.requestComplete(); - if (resp.statusCode() != 200) { - String s = "Expected 200, got: " + resp.statusCode(); - System.out.println(s + " from " - + resp.request().uri().getPath()); - return completedWithIOException(s); - } else { - counter++; - System.out.println("Result (" + counter + ") from " - + resp.request().uri().getPath()); - } - return CompletableFuture.completedStage(resp.body()) - .thenApply((b) -> new Pair<>(resp, b)); - }) - .thenAccept((pair) -> { - HttpRequest request = pair.t.request(); - byte[] requestBody = bodies.get(request); - check(Arrays.equals(requestBody, pair.u), - "bodies not equal:[" + bytesToHexString(requestBody) - + "] [" + bytesToHexString(pair.u) + "]"); - - }); - } + // This loop implements a retry mechanism to work around an issue + // on some systems (observed on Windows 10) that seem to be trying to + // throttle the number of connections that can be made concurrently by + // rejecting connection attempts. + // On the first iteration of this loop, we will attempt 20 concurrent + // requests. If this fails with ConnectException, we will retry the + // 20 requests, but limiting the concurrency to 10 (LIMIT <- 10). + // If this fails again, the test will fail. + boolean done = false; + LOOP: do { + RequestLimiter limiter = new RequestLimiter(LIMIT.get()); + Random rand = RANDOM; + CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS]; + Map<HttpRequest,byte[]> bodies = new ConcurrentHashMap<>(); + long start = System.nanoTime(); + + for (int i = 0; i < REQUESTS; i++) { + byte[] buf = new byte[(i + 1) * CHUNK_SIZE + i + 1]; // different size bodies + rand.nextBytes(buf); + URI uri = new URI(baseURI.toString() + String.valueOf(i + 1)); + HttpRequest r = HttpRequest.newBuilder(uri) + .header("XFixed", "true") + .POST(BodyPublishers.ofByteArray(buf)) + .build(); + bodies.put(r, buf); + + results[i] = + limiter.whenOkToSend() + .thenCompose((v) -> { + System.out.println("Client: sendAsync: " + r.uri()); + return client.sendAsync(r, buf); + }) + .handle((resp, t) -> { + limiter.requestComplete(); + CompletionStage<Pair<HttpResponse<byte[]>, byte[]>> res; + String now = now(start); + if (t == null) { + if (resp.statusCode() != 200) { + String s = "Expected 200, got: " + resp.statusCode(); + System.out.println(now + s + " from " + + resp.request().uri().getPath()); + res = completedWithIOException(s); + return res; + } else { + int counter = COUNT.incrementAndGet(); + System.out.println(now + "Result (" + counter + ") from " + + resp.request().uri().getPath()); + } + res = CompletableFuture.completedStage(resp.body()) + .thenApply((b) -> new Pair<>(resp, b)); + return res; + } else { + int counter = COUNT.incrementAndGet(); + System.out.println(now + "Result (" + counter + ") from " + + r.uri().getPath() + + failure(t)); + res = CompletableFuture.failedFuture(t); + return res; + } + }) + .thenCompose(c -> c) + .thenAccept((pair) -> { + HttpRequest request = pair.t.request(); + byte[] requestBody = bodies.get(request); + check(Arrays.equals(requestBody, pair.u), + "bodies not equal:[" + bytesToHexString(requestBody) + + "] [" + bytesToHexString(pair.u) + "]"); + + }); + } - // wait for them all to complete and throw exception in case of error - CompletableFuture.allOf(results).join(); + try { + // wait for them all to complete and throw exception in case of error + CompletableFuture.allOf(results).join(); + done = true; + } catch (CompletionException e) { + if (!Platform.isWindows()) throw e; + if (LIMIT.get() < REQUESTS) throw e; + Throwable cause = e; + while ((cause = cause.getCause()) != null) { + if (cause instanceof ConnectException) { + // try again, limit concurrency by half + COUNT.set(0); + LIMIT.set(REQUESTS/2); + System.out.println("*** Retrying due to " + cause); + continue LOOP; + } + } + throw e; + } + } while (!done); } static <T> CompletableFuture<T> completedWithIOException(String message) { @@ -294,13 +368,7 @@ public class ManyRequestsLegacy { return sb.toString(); } - static final class Pair<T,U> { - Pair(T t, U u) { - this.t = t; this.u = u; - } - T t; - U u; - } + record Pair<T,U>(T t, U u) { } /** * A simple limiter for controlling the number of requests to be run in diff --git a/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java b/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java index 33e5ade4f8340d89c7c5a81a278b0faef65b49cf..f8592272588781d37dac70a26600d8ac6f5b5239 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java +++ b/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java @@ -124,6 +124,20 @@ public class Http2TestServer implements AutoCloseable { this(serverName, secure, port, exec, backlog, properties, context, false); } + public Http2TestServer(String serverName, + boolean secure, + int port, + ExecutorService exec, + int backlog, + Properties properties, + SSLContext context, + boolean supportsHTTP11) + throws Exception + { + this(InetAddress.getLoopbackAddress(), serverName, secure, port, exec, + backlog, properties, context, supportsHTTP11); + } + /** * Create a Http2Server listening on the given port. Currently needs * to know in advance whether incoming connections are plain TCP "h2c" @@ -134,6 +148,7 @@ public class Http2TestServer implements AutoCloseable { * "X-Magic", "HTTP/1.1 request received by HTTP/2 server", * "X-Received-Body", <the request body>); * + * @param localAddr local address to bind to * @param serverName SNI servername * @param secure https or http * @param port listen port @@ -146,7 +161,8 @@ public class Http2TestServer implements AutoCloseable { * connection without the h2 ALPN. Otherwise, false to operate in * HTTP/2 mode exclusively. */ - public Http2TestServer(String serverName, + public Http2TestServer(InetAddress localAddr, + String serverName, boolean secure, int port, ExecutorService exec, @@ -163,7 +179,7 @@ public class Http2TestServer implements AutoCloseable { this.sslContext = context; else this.sslContext = SSLContext.getDefault(); - server = initSecure(port, backlog); + server = initSecure(localAddr, port, backlog); } else { this.sslContext = context; server = initPlaintext(port, backlog); @@ -236,14 +252,14 @@ public class Http2TestServer implements AutoCloseable { } - final ServerSocket initSecure(int port, int backlog) throws Exception { + final ServerSocket initSecure(InetAddress localAddr, int port, int backlog) throws Exception { ServerSocketFactory fac; SSLParameters sslp = null; fac = sslContext.getServerSocketFactory(); sslp = sslContext.getSupportedSSLParameters(); SSLServerSocket se = (SSLServerSocket) fac.createServerSocket(); se.setReuseAddress(false); - se.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), backlog); + se.bind(new InetSocketAddress(localAddr, 0), backlog); if (supportsHTTP11) { sslp.setApplicationProtocols(new String[]{"h2", "http/1.1"}); } else { diff --git a/test/jdk/java/nio/channels/Channels/ReadXBytes.java b/test/jdk/java/nio/channels/Channels/ReadXBytes.java index 1f36d4031fd09f9af4a490c9182a8f51efd8cad5..f146d629da189e4812d6e9212daaab99c82c66d1 100644 --- a/test/jdk/java/nio/channels/Channels/ReadXBytes.java +++ b/test/jdk/java/nio/channels/Channels/ReadXBytes.java @@ -25,12 +25,12 @@ * @test * @bug 8268435 8274780 * @summary Verify ChannelInputStream methods readAllBytes and readNBytes - * @requires vm.bits == 64 + * @requires (sun.arch.data.model == "64" & os.maxMemory >= 16g) * @library .. * @library /test/lib * @build jdk.test.lib.RandomFactory * @modules java.base/jdk.internal.util - * @run testng/othervm/timeout=900 -Xmx8G ReadXBytes + * @run testng/othervm/timeout=900 -Xmx12G ReadXBytes * @key randomness */ import java.io.File; @@ -38,7 +38,7 @@ import java.io.FileInputStream; import java.io.FilterInputStream; import java.io.InputStream; import java.io.IOException; -import java.io.RandomAccessFile; +import java.nio.ByteBuffer; import java.nio.channels.Channel; import java.nio.channels.Channels; import java.nio.channels.FileChannel; @@ -46,11 +46,12 @@ import java.nio.channels.ReadableByteChannel; import java.nio.channels.SeekableByteChannel; import java.nio.file.Files; import java.nio.file.Path; -import static java.nio.file.StandardOpenOption.READ; import java.util.List; import java.util.Random; import jdk.internal.util.ArraysSupport; +import static java.nio.file.StandardOpenOption.*; + import jdk.test.lib.RandomFactory; import org.testng.Assert; @@ -72,30 +73,51 @@ public class ReadXBytes { // A length greater than a 32-bit integer can accommodate private static final long HUGE_LENGTH = Integer.MAX_VALUE + 27L; + // Current directory + private static final Path DIR = Path.of(System.getProperty("test.dir", ".")); + // --- Framework --- + // Create a temporary file path + static Path createFilePath() { + String name = String.format("ReadXBytes%d.tmp", System.nanoTime()); + return DIR.resolve(name); + } + // Creates a temporary file of a specified length with undefined content static Path createFile(long length) throws IOException { - File file = File.createTempFile("foo", ".bar"); - file.deleteOnExit(); - try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) { - raf.setLength(length); + Path path = createFilePath(); + path.toFile().deleteOnExit(); + try (FileChannel fc = FileChannel.open(path, CREATE_NEW, SPARSE, WRITE)) { + if (length > 0) { + fc.position(length - 1); + fc.write(ByteBuffer.wrap(new byte[] {27})); + } } - return file.toPath(); + return path; } // Creates a temporary file of a specified length with random content static Path createFileWithRandomContent(long length) throws IOException { Path file = createFile(length); - try (RandomAccessFile raf = new RandomAccessFile(file.toFile(), "rw")) { - long written = 0L; - int bufLength = Math.min(32768, (int)Math.min(length, BIG_LENGTH)); + try (FileChannel fc = FileChannel.open(file, WRITE);) { + long pos = 0L; + // if the length exceeds 2 GB, skip the first 2 GB - 1 MB bytes + if (length >= 2L*1024*1024*1024) { + // write the last (length - 2GB - 1MB) bytes + pos = 2047L*1024*1024; + } else if (length > 0) { + // write either the first or last bytes only + long p = Math.min(Math.abs(RAND.nextLong()), length - 1); + pos = RAND.nextBoolean() ? p : length - 1 - p; + } + fc.position(pos); + int bufLength = Math.min(32768, (int)Math.min(length - pos, BIG_LENGTH)); byte[] buf = new byte[bufLength]; - while (written < length) { + while (pos < length) { RAND.nextBytes(buf); - int len = (int)Math.min(bufLength, length - written); - raf.write(buf, 0, len); - written += len; + int len = (int)Math.min(bufLength, length - pos); + pos += fc.write(ByteBuffer.wrap(buf, 0, len)); } } return file; diff --git a/test/jdk/java/nio/channels/Channels/SocketChannelStreams.java b/test/jdk/java/nio/channels/Channels/SocketChannelStreams.java new file mode 100644 index 0000000000000000000000000000000000000000..57142fb03d74b6fb368907aa6dd594887bdae48a --- /dev/null +++ b/test/jdk/java/nio/channels/Channels/SocketChannelStreams.java @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8279339 + * @run testng SocketChannelStreams + * @summary Exercise InputStream/OutputStream returned by Channels.newXXXStream + * when channel is a SocketChannel + */ + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.nio.channels.Channels; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Objects; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.testng.annotations.*; +import static org.testng.Assert.*; + +@Test +public class SocketChannelStreams { + private ScheduledExecutorService executor; + + @BeforeClass() + public void init() { + executor = Executors.newSingleThreadScheduledExecutor(); + } + + @AfterClass + public void finish() { + executor.shutdown(); + } + + /** + * Test read when bytes are available. + */ + public void testRead1() throws Exception { + withConnection((sc, peer) -> { + write(peer, 99); + int n = Channels.newInputStream(sc).read(); + assertEquals(n, 99); + }); + } + + /** + * Test read blocking before bytes are available. + */ + public void testRead2() throws Exception { + withConnection((sc, peer) -> { + scheduleWrite(peer, 99, 1000); + int n = Channels.newInputStream(sc).read(); + assertEquals(n, 99); + }); + } + + /** + * Test read after peer has closed connection. + */ + public void testRead3() throws Exception { + withConnection((sc, peer) -> { + peer.close(); + int n = Channels.newInputStream(sc).read(); + assertEquals(n, -1); + }); + } + + /** + * Test read blocking before peer closes connection. + */ + public void testRead4() throws Exception { + withConnection((sc, peer) -> { + scheduleClose(peer, 1000); + int n = Channels.newInputStream(sc).read(); + assertEquals(n, -1); + }); + } + + /** + * Test async close of channel when thread blocked in read. + */ + public void testRead5() throws Exception { + withConnection((sc, peer) -> { + scheduleClose(sc, 2000); + InputStream in = Channels.newInputStream(sc); + expectThrows(IOException.class, () -> in.read()); + }); + } + + /** + * Test async close of input stream, when thread blocked in read. + */ + public void testRead6() throws Exception { + withConnection((sc, peer) -> { + InputStream in = Channels.newInputStream(sc); + scheduleClose(in, 2000); + expectThrows(IOException.class, () -> in.read()); + }); + } + + /** + * Test interrupt status set before read. + */ + public void testRead7() throws Exception { + withConnection((sc, peer) -> { + Thread.currentThread().interrupt(); + try { + InputStream in = Channels.newInputStream(sc); + expectThrows(IOException.class, () -> in.read()); + } finally { + Thread.interrupted(); // clear interrupt + } + assertFalse(sc.isOpen()); + }); + } + + /** + * Test interrupt of thread blocked in read. + */ + public void testRead8() throws Exception { + withConnection((sc, peer) -> { + Future<?> interrupter = scheduleInterrupt(Thread.currentThread(), 2000); + try { + InputStream in = Channels.newInputStream(sc); + expectThrows(IOException.class, () -> in.read()); + } finally { + interrupter.cancel(true); + Thread.interrupted(); // clear interrupt + } + assertFalse(sc.isOpen()); + }); + } + + /** + * Test that read is untimed when SO_TIMEOUT is set on the Socket adaptor. + */ + public void testRead9() throws Exception { + withConnection((sc, peer) -> { + sc.socket().setSoTimeout(100); + scheduleWrite(peer, 99, 2000); + // read should block until bytes are available + int b = Channels.newInputStream(sc).read(); + assertTrue(b == 99); + }); + } + + /** + * Test write. + */ + public void testWrite1() throws Exception { + withConnection((sc, peer) -> { + OutputStream out = Channels.newOutputStream(sc); + out.write(99); + int n = read(peer); + assertEquals(n, 99); + }); + } + + /** + * Test async close of channel when thread blocked in write. + */ + public void testWrite2() throws Exception { + withConnection((sc, peer) -> { + scheduleClose(sc, 2000); + expectThrows(IOException.class, () -> { + OutputStream out = Channels.newOutputStream(sc); + byte[] data = new byte[64*1000]; + while (true) { + out.write(data); + } + }); + }); + } + + /** + * Test async close of output stream when thread blocked in write. + */ + public void testWrite3() throws Exception { + withConnection((sc, peer) -> { + OutputStream out = Channels.newOutputStream(sc); + scheduleClose(out, 2000); + expectThrows(IOException.class, () -> { + byte[] data = new byte[64*1000]; + while (true) { + out.write(data); + } + }); + }); + } + + /** + * Test interrupt status set before write. + */ + public void testWrite4() throws Exception { + withConnection((sc, peer) -> { + Thread.currentThread().interrupt(); + try { + OutputStream out = Channels.newOutputStream(sc); + expectThrows(IOException.class, () -> out.write(99)); + } finally { + Thread.interrupted(); // clear interrupt + } + assertFalse(sc.isOpen()); + }); + } + + /** + * Test interrupt of thread blocked in write. + */ + public void testWrite5() throws Exception { + withConnection((sc, peer) -> { + Future<?> interrupter = scheduleInterrupt(Thread.currentThread(), 2000); + try { + expectThrows(IOException.class, () -> { + OutputStream out = Channels.newOutputStream(sc); + byte[] data = new byte[64*1000]; + while (true) { + out.write(data); + } + }); + } finally { + interrupter.cancel(true); + Thread.interrupted(); // clear interrupt + } + assertFalse(sc.isOpen()); + }); + } + + /** + * Test read when another thread is blocked in write. The read should + * complete immediately. + */ + public void testConcurrentReadWrite1() throws Exception { + withConnection((sc, peer) -> { + InputStream in = Channels.newInputStream(sc); + OutputStream out = Channels.newOutputStream(sc); + + // block thread in write + fork(() -> { + var data = new byte[64*1024]; + for (;;) { + out.write(data); + } + }); + Thread.sleep(1000); // give writer time to block + + // test read, should not be blocked by writer thread + write(peer, 99); + int n = in.read(); + assertEquals(n, 99); + }); + } + + /** + * Test read when another thread is blocked in write. The read should + * block until bytes are available. + */ + public void testConcurrentReadWrite2() throws Exception { + withConnection((sc, peer) -> { + InputStream in = Channels.newInputStream(sc); + OutputStream out = Channels.newOutputStream(sc); + + // block thread in write + fork(() -> { + var data = new byte[64*1024]; + for (;;) { + out.write(data); + } + }); + Thread.sleep(1000); // give writer time to block + + // test read, should not be blocked by writer thread + scheduleWrite(peer, 99, 500); + int n = in.read(); + assertEquals(n, 99); + }); + } + + /** + * Test writing when another thread is blocked in read. + */ + public void testConcurrentReadWrite3() throws Exception { + withConnection((sc, peer) -> { + InputStream in = Channels.newInputStream(sc); + OutputStream out = Channels.newOutputStream(sc); + + // block thread in read + fork(() -> { + in.read(); + }); + Thread.sleep(100); // give reader time to block + + // test write, should not be blocked by reader thread + out.write(99); + int n = read(peer); + assertEquals(n, 99); + }); + } + + /** + * Test read/write when channel configured non-blocking. + */ + public void testIllegalBlockingMode() throws Exception { + withConnection((sc, peer) -> { + InputStream in = Channels.newInputStream(sc); + OutputStream out = Channels.newOutputStream(sc); + + sc.configureBlocking(false); + expectThrows(IllegalBlockingModeException.class, () -> in.read()); + expectThrows(IllegalBlockingModeException.class, () -> out.write(99)); + }); + } + + /** + * Test NullPointerException. + */ + public void testNullPointerException() throws Exception { + withConnection((sc, peer) -> { + InputStream in = Channels.newInputStream(sc); + OutputStream out = Channels.newOutputStream(sc); + + expectThrows(NullPointerException.class, () -> in.read(null)); + expectThrows(NullPointerException.class, () -> in.read(null, 0, 0)); + + expectThrows(NullPointerException.class, () -> out.write(null)); + expectThrows(NullPointerException.class, () -> out.write(null, 0, 0)); + }); + } + + /** + * Test IndexOutOfBoundsException. + */ + public void testIndexOutOfBoundsException() throws Exception { + withConnection((sc, peer) -> { + InputStream in = Channels.newInputStream(sc); + OutputStream out = Channels.newOutputStream(sc); + byte[] ba = new byte[100]; + + expectThrows(IndexOutOfBoundsException.class, () -> in.read(ba, -1, 1)); + expectThrows(IndexOutOfBoundsException.class, () -> in.read(ba, 0, -1)); + expectThrows(IndexOutOfBoundsException.class, () -> in.read(ba, 0, 1000)); + expectThrows(IndexOutOfBoundsException.class, () -> in.read(ba, 1, 100)); + + expectThrows(IndexOutOfBoundsException.class, () -> out.write(ba, -1, 1)); + expectThrows(IndexOutOfBoundsException.class, () -> out.write(ba, 0, -1)); + expectThrows(IndexOutOfBoundsException.class, () -> out.write(ba, 0, 1000)); + expectThrows(IndexOutOfBoundsException.class, () -> out.write(ba, 1, 100)); + }); + } + + // -- test infrastructure -- + + private interface ThrowingTask { + void run() throws Exception; + } + + private interface ThrowingBiConsumer<T, U> { + void accept(T t, U u) throws Exception; + } + + /** + * Invokes the consumer with a connected pair of socket channels. + */ + private static void withConnection(ThrowingBiConsumer<SocketChannel, SocketChannel> consumer) + throws Exception + { + var loopback = InetAddress.getLoopbackAddress(); + try (ServerSocketChannel listener = ServerSocketChannel.open()) { + listener.bind(new InetSocketAddress(loopback, 0)); + try (SocketChannel sc = SocketChannel.open(listener.getLocalAddress())) { + try (SocketChannel peer = listener.accept()) { + consumer.accept(sc, peer); + } + } + } + } + + /** + * Forks a thread to execute the given task. + */ + private Future<?> fork(ThrowingTask task) { + ExecutorService pool = Executors.newFixedThreadPool(1); + try { + return pool.submit(() -> { + task.run(); + return null; + }); + } finally { + pool.shutdown(); + } + } + + /** + * Read a byte from the given socket channel. + */ + private int read(SocketChannel sc) throws IOException { + return sc.socket().getInputStream().read(); + } + + /** + * Write a byte to the given socket channel. + */ + private void write(SocketChannel sc, int b) throws IOException { + sc.socket().getOutputStream().write(b); + } + + /** + * Writes the given data to the socket channel after a delay. + */ + private Future<?> scheduleWrite(SocketChannel sc, byte[] data, long delay) { + return schedule(() -> { + try { + sc.socket().getOutputStream().write(data); + } catch (IOException ioe) { } + }, delay); + } + + /** + * Writes a byte to the socket channel after a delay. + */ + private Future<?> scheduleWrite(SocketChannel sc, int b, long delay) { + return scheduleWrite(sc, new byte[] { (byte)b }, delay); + } + + /** + * Closes the given object after a delay. + */ + private Future<?> scheduleClose(Closeable c, long delay) { + return schedule(() -> { + try { + c.close(); + } catch (IOException ioe) { } + }, delay); + } + + /** + * Interrupts the given Thread after a delay. + */ + private Future<?> scheduleInterrupt(Thread t, long delay) { + return schedule(() -> t.interrupt(), delay); + } + + /** + * Schedules the given task to run after a delay. + */ + private Future<?> schedule(Runnable task, long delay) { + return executor.schedule(task, delay, TimeUnit.MILLISECONDS); + } +} diff --git a/test/jdk/java/nio/channels/Channels/TransferTo.java b/test/jdk/java/nio/channels/Channels/TransferTo.java index c75b9913e87bfef3ac2555d02a0dddb9d673ea21..e7fa169788c3bb57847df5ea115b442d9b5b5d3e 100644 --- a/test/jdk/java/nio/channels/Channels/TransferTo.java +++ b/test/jdk/java/nio/channels/Channels/TransferTo.java @@ -23,9 +23,10 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.InputStream; +import java.io.IOException; import java.io.OutputStream; +import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.IllegalBlockingModeException; @@ -51,6 +52,7 @@ import org.testng.annotations.Test; import jdk.test.lib.RandomFactory; import static java.lang.String.format; +import static java.nio.file.StandardOpenOption.*; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertThrows; @@ -62,8 +64,8 @@ import static org.testng.Assert.assertTrue; * @build jdk.test.lib.RandomFactory * @run testng/othervm/timeout=180 TransferTo * @bug 8265891 - * @summary tests whether sun.nio.ChannelInputStream.transferTo conforms to the - * InputStream.transferTo contract defined in the javadoc + * @summary Tests whether sun.nio.ChannelInputStream.transferTo conforms to the + * InputStream.transferTo specification * @key randomness */ public class TransferTo { @@ -72,16 +74,17 @@ public class TransferTo { private static final int ITERATIONS = 10; - private static final int NUM_WRITES = 3 * 1024; - private static final int BYTES_PER_WRITE = 1024 * 1024; - private static final long BYTES_WRITTEN = (long) NUM_WRITES * BYTES_PER_WRITE; + private static final int NUM_WRITES = 3*1024; + private static final int BYTES_PER_WRITE = 1024*1024; + private static final long BYTES_WRITTEN = (long) NUM_WRITES*BYTES_PER_WRITE; private static final Random RND = RandomFactory.getRandom(); private static final Path CWD = Path.of("."); /* - * Provides test scenarios, i. e. combinations of input and output streams to be tested. + * Provides test scenarios, i.e., combinations of input and output streams + * to be tested. */ @DataProvider public static Object[][] streamCombinations() throws Exception { @@ -89,10 +92,12 @@ public class TransferTo { // tests FileChannel.transferTo(FileChannel) optimized case { fileChannelInput(), fileChannelOutput() }, - // tests FileChannel.transferTo(SelectableChannelOutput) optimized case + // tests FileChannel.transferTo(SelectableChannelOutput) + // optimized case { fileChannelInput(), selectableChannelOutput() }, - // tests FileChannel.transferTo(WritableChannelOutput) optimized case + // tests FileChannel.transferTo(WritableChannelOutput) + // optimized case { fileChannelInput(), writableByteChannelOutput() }, // tests InputStream.transferTo(OutputStream) default case @@ -101,7 +106,8 @@ public class TransferTo { } /* - * Testing API compliance: Input stream must throw NullPointerException when parameter "out" is null. + * Testing API compliance: input stream must throw NullPointerException + * when parameter "out" is null. */ @Test(dataProvider = "streamCombinations") public void testNullPointerException(InputStreamProvider inputStreamProvider, @@ -117,7 +123,8 @@ public class TransferTo { } /* - * Testing API compliance: Complete content of input stream must be transferred to output stream. + * Testing API compliance: complete content of input stream must be + * transferred to output stream. */ @Test(dataProvider = "streamCombinations") public void testStreamContents(InputStreamProvider inputStreamProvider, @@ -128,10 +135,12 @@ public class TransferTo { // tests input stream with a length between 1k and 4k checkTransferredContents(inputStreamProvider, outputStreamProvider, createRandomBytes(1024, 4096)); - // tests input stream with several data chunks, as 16k is more than a single chunk can hold + // tests input stream with several data chunks, as 16k is more than a + // single chunk can hold checkTransferredContents(inputStreamProvider, outputStreamProvider, createRandomBytes(16384, 16384)); - // tests randomly chosen starting positions within source and target stream + // tests randomly chosen starting positions within source and + // target stream for (int i = 0; i < ITERATIONS; i++) { byte[] inBytes = createRandomBytes(MIN_SIZE, MAX_SIZE_INCR); int posIn = RND.nextInt(inBytes.length); @@ -147,34 +156,60 @@ public class TransferTo { } /* - * Special test for file-to-file transfer of more than two GB. - * This test covers multiple iterations of FileChannel.transerTo(FileChannel), - * which ChannelInputStream.transferTo() only applies in this particular case, - * and cannot get tested using a single byte[] due to size limitation of arrays. + * Special test for file-to-file transfer of more than 2 GB. This test + * covers multiple iterations of FileChannel.transerTo(FileChannel), + * which ChannelInputStream.transferTo() only applies in this particular + * case, and cannot get tested using a single byte[] due to size limitation + * of arrays. */ @Test public void testMoreThanTwoGB() throws IOException { - Path sourceFile = Files.createTempFile(CWD, "test2GBSource", null); + // prepare two temporary files to be compared at the end of the test + // set the source file name + String sourceName = String.format("test3GBSource%s.tmp", + String.valueOf(RND.nextInt(Integer.MAX_VALUE))); + Path sourceFile = CWD.resolve(sourceName); + try { - // preparing two temporary files which will be compared at the end of the test - Path targetFile = Files.createTempFile(CWD, "test2GBtarget", null); + // set the target file name + String targetName = String.format("test3GBTarget%s.tmp", + String.valueOf(RND.nextInt(Integer.MAX_VALUE))); + Path targetFile = CWD.resolve(targetName); + try { - // writing 3 GB of random bytes into source file - for (int i = 0; i < NUM_WRITES; i++) - Files.write(sourceFile, createRandomBytes(BYTES_PER_WRITE, 0), StandardOpenOption.APPEND); + // calculate initial position to be just short of 2GB + final long initPos = 2047*BYTES_PER_WRITE; + + // create the source file with a hint to be sparse + try (FileChannel fc = FileChannel.open(sourceFile, CREATE_NEW, SPARSE, WRITE, APPEND);) { + // set initial position to avoid writing nearly 2GB + fc.position(initPos); + + // fill the remainder of the file with random bytes + int nw = (int)(NUM_WRITES - initPos/BYTES_PER_WRITE); + for (int i = 0; i < nw; i++) { + byte[] rndBytes = createRandomBytes(BYTES_PER_WRITE, 0); + ByteBuffer src = ByteBuffer.wrap(rndBytes); + fc.write(src); + } + } - // performing actual transfer, effectively by multiple invocations of Filechannel.transferTo(FileChannel) - long count; - try (InputStream inputStream = Channels.newInputStream(FileChannel.open(sourceFile)); - OutputStream outputStream = Channels - .newOutputStream(FileChannel.open(targetFile, StandardOpenOption.WRITE))) { - count = inputStream.transferTo(outputStream); + // create the target file with a hint to be sparse + try (FileChannel fc = FileChannel.open(targetFile, CREATE_NEW, WRITE, SPARSE);) { } - // comparing reported transferred bytes, must be 3 GB - assertEquals(count, BYTES_WRITTEN); + // perform actual transfer, effectively by multiple invocations + // of Filechannel.transferTo(FileChannel) + try (InputStream inputStream = Channels.newInputStream(FileChannel.open(sourceFile)); + OutputStream outputStream = Channels.newOutputStream(FileChannel.open(targetFile, WRITE))) { + long count = inputStream.transferTo(outputStream); + + // compare reported transferred bytes, must be 3 GB + // less the value of the initial position + assertEquals(count, BYTES_WRITTEN - initPos); + } - // comparing content of both files, failing in case of any difference + // compare content of both files, failing if different assertEquals(Files.mismatch(sourceFile, targetFile), -1); } finally { @@ -186,28 +221,33 @@ public class TransferTo { } /* - * Special test whether selectable channel based transfer throws blocking mode exception. + * Special test of whether selectable channel based transfer throws blocking + * mode exception. */ @Test public void testIllegalBlockingMode() throws IOException { Pipe pipe = Pipe.open(); try { - // testing arbitrary input (here: empty file) to non-blocking selectable output + // testing arbitrary input (here: empty file) to non-blocking + // selectable output try (FileChannel fc = FileChannel.open(Files.createTempFile(CWD, "testIllegalBlockingMode", null)); - InputStream is = Channels.newInputStream(fc); - SelectableChannel sc = pipe.sink().configureBlocking(false); - OutputStream os = Channels.newOutputStream((WritableByteChannel) sc)) { + InputStream is = Channels.newInputStream(fc); + SelectableChannel sc = pipe.sink().configureBlocking(false); + OutputStream os = Channels.newOutputStream((WritableByteChannel) sc)) { - // IllegalBlockingMode must be thrown when trying to perform a transfer + // IllegalBlockingMode must be thrown when trying to perform + // a transfer assertThrows(IllegalBlockingModeException.class, () -> is.transferTo(os)); } - // testing non-blocking selectable input to arbitrary output (here: byte array) + // testing non-blocking selectable input to arbitrary output + // (here: byte array) try (SelectableChannel sc = pipe.source().configureBlocking(false); - InputStream is = Channels.newInputStream((ReadableByteChannel) sc); - OutputStream os = new ByteArrayOutputStream()) { + InputStream is = Channels.newInputStream((ReadableByteChannel) sc); + OutputStream os = new ByteArrayOutputStream()) { - // IllegalBlockingMode must be thrown when trying to perform a transfer + // IllegalBlockingMode must be thrown when trying to perform + // a transfer assertThrows(IllegalBlockingModeException.class, () -> is.transferTo(os)); } } finally { @@ -217,9 +257,9 @@ public class TransferTo { } /* - * Asserts that the transferred content is correct, i. e. compares the actually transferred bytes - * to the expected assumption. The position of the input and output stream before the transfer is - * the start of stream (BOF). + * Asserts that the transferred content is correct, i.e., compares the bytes + * actually transferred to those expected. The position of the input and + * output streams before the transfer are zero (BOF). */ private static void checkTransferredContents(InputStreamProvider inputStreamProvider, OutputStreamProvider outputStreamProvider, byte[] inBytes) throws Exception { @@ -227,16 +267,16 @@ public class TransferTo { } /* - * Asserts that the transferred content is correct, i. e. compares the actually transferred bytes - * to the expected assumption. The position of the input and output stream before the transfer is - * provided by the caller. + * Asserts that the transferred content is correct, i. e. compares the bytes + * actually transferred to those expected. The positions of the input and + * output streams before the transfer are provided by the caller. */ private static void checkTransferredContents(InputStreamProvider inputStreamProvider, OutputStreamProvider outputStreamProvider, byte[] inBytes, int posIn, int posOut) throws Exception { AtomicReference<Supplier<byte[]>> recorder = new AtomicReference<>(); try (InputStream in = inputStreamProvider.input(inBytes); - OutputStream out = outputStreamProvider.output(recorder::set)) { - // skip bytes till starting position + OutputStream out = outputStreamProvider.output(recorder::set)) { + // skip bytes until starting position in.skipNBytes(posIn); out.write(new byte[posOut]); @@ -252,7 +292,8 @@ public class TransferTo { } /* - * Creates an array of random size (between min and min + maxRandomAdditive) filled with random bytes + * Creates an array of random size (between min and min + maxRandomAdditive) + * filled with random bytes */ private static byte[] createRandomBytes(int min, int maxRandomAdditive) { byte[] bytes = new byte[min + (maxRandomAdditive == 0 ? 0 : RND.nextInt(maxRandomAdditive))]; @@ -298,7 +339,8 @@ public class TransferTo { } /* - * Creates a provider for an input stream which wraps a readable byte channel but is not a file channel + * Creates a provider for an input stream which wraps a readable byte + * channel but is not a file channel */ private static InputStreamProvider readableByteChannelInput() { return new InputStreamProvider() { @@ -316,7 +358,7 @@ public class TransferTo { return new OutputStreamProvider() { public OutputStream output(Consumer<Supplier<byte[]>> spy) throws Exception { Path path = Files.createTempFile(CWD, "fileChannelOutput", null); - FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.WRITE); + FileChannel fileChannel = FileChannel.open(path, WRITE); spy.accept(() -> { try { return Files.readAllBytes(path); diff --git a/test/jdk/java/nio/channels/Selector/CustomFileSystem.java b/test/jdk/java/nio/channels/Selector/CustomFileSystem.java new file mode 100644 index 0000000000000000000000000000000000000000..8113a7169105af14a1dcc2adb3a2b83c30233760 --- /dev/null +++ b/test/jdk/java/nio/channels/Selector/CustomFileSystem.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, JetBrains s.r.o.. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Verifies that an attempt to call Selector.open() on a non-default + * file system succeeds. + * @build CustomFileSystem CustomFileSystemProvider + * @run main/othervm -Djava.nio.file.spi.DefaultFileSystemProvider=CustomFileSystemProvider CustomFileSystem + */ + +public class CustomFileSystem { + public static void main(String args[]) throws java.io.IOException { + java.nio.channels.Selector.open(); + } +} diff --git a/test/jdk/java/nio/channels/Selector/CustomFileSystemProvider.java b/test/jdk/java/nio/channels/Selector/CustomFileSystemProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..f3e876e08a7447ccc061ac6cc1985f5fc89f5408 --- /dev/null +++ b/test/jdk/java/nio/channels/Selector/CustomFileSystemProvider.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, JetBrains s.r.o.. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.nio.channels.FileChannel; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.AccessMode; +import java.nio.file.CopyOption; +import java.nio.file.DirectoryStream; +import java.nio.file.FileStore; +import java.nio.file.FileSystem; +import java.nio.file.LinkOption; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.ReadOnlyFileSystemException; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.UserPrincipalLookupService; +import java.nio.file.spi.FileSystemProvider; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +public class CustomFileSystemProvider extends FileSystemProvider { + + private final FileSystemProvider defaultProvider; + + public CustomFileSystemProvider(FileSystemProvider defaultProvider) { + this.defaultProvider = defaultProvider; + } + + FileSystemProvider defaultProvider() { + return defaultProvider; + } + + @Override + public String getScheme() { + return "file"; + } + + @Override + public FileSystem newFileSystem(URI uri, Map<String,?> env) throws IOException { + return defaultProvider.newFileSystem(uri, env); + } + + @Override + public FileSystem getFileSystem(URI uri) { + return defaultProvider.getFileSystem(uri); + } + + @Override + public Path getPath(URI uri) { + return defaultProvider.getPath(uri); + } + + @Override + public void setAttribute(Path file, String attribute, Object value, + LinkOption... options) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public Map<String,Object> readAttributes(Path file, String attributes, + LinkOption... options) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public <A extends BasicFileAttributes> A readAttributes(Path file, + Class<A> type, + LinkOption... options) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public <V extends FileAttributeView> V getFileAttributeView(Path file, + Class<V> type, + LinkOption... options) + { + throw new RuntimeException("not implemented"); + } + + @Override + public boolean isHidden(Path file) throws IOException { + throw new ReadOnlyFileSystemException(); + } + + @Override + public boolean isSameFile(Path file, Path other) throws IOException { + throw new RuntimeException("not implemented"); + } + + @Override + public void checkAccess(Path file, AccessMode... modes) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public void copy(Path source, Path target, CopyOption... options) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public void move(Path source, Path target, CopyOption... options) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public void delete(Path file) throws IOException { + throw new RuntimeException("not implemented"); + } + + @Override + public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public void createLink(Path link, Path existing) throws IOException { + throw new RuntimeException("not implemented"); + } + + @Override + public Path readSymbolicLink(Path link) throws IOException { + throw new RuntimeException("not implemented"); + } + + @Override + public void createDirectory(Path dir, FileAttribute<?>... attrs) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public DirectoryStream<Path> newDirectoryStream(Path dir, + DirectoryStream.Filter<? super Path> filter) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public SeekableByteChannel newByteChannel(Path file, + Set<? extends OpenOption> options, + FileAttribute<?>... attrs) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public FileChannel newFileChannel(Path file, + Set<? extends OpenOption> options, + FileAttribute<?>... attrs) + throws IOException + { + throw new RuntimeException("not implemented"); + } + + @Override + public FileStore getFileStore(Path file) throws IOException { + throw new RuntimeException("not implemented"); + } +} diff --git a/test/jdk/java/nio/file/Files/probeContentType/Basic.java b/test/jdk/java/nio/file/Files/probeContentType/Basic.java index 0812f886c30bcb4b8b14bb7082fb231ea8d662d3..b404673b2f4ff081f3963d1314a2bfbfb06067b6 100644 --- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java +++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java @@ -110,8 +110,8 @@ public class Basic { + " cannot be determined"); failures++; } else if (!expectedTypes.contains(type)) { - System.err.printf("Content type: %s; expected: %s%n", - type, expectedTypes); + System.err.printf("For extension %s we got content type: %s; expected: %s%n", + extension, type, expectedTypes); failures++; } } finally { @@ -155,7 +155,7 @@ public class Basic { // Verify that certain extensions are mapped to the correct type. var exTypes = new ExType[] { new ExType("adoc", List.of("text/plain")), - new ExType("bz2", List.of("application/bz2", "application/x-bzip2")), + new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip")), new ExType("css", List.of("text/css")), new ExType("csv", List.of("text/csv")), new ExType("doc", List.of("application/msword")), @@ -166,19 +166,19 @@ public class Basic { new ExType("js", List.of("text/javascript", "application/javascript")), new ExType("json", List.of("application/json")), new ExType("markdown", List.of("text/markdown")), - new ExType("md", List.of("text/markdown")), + new ExType("md", List.of("text/markdown", "application/x-genesis-rom")), new ExType("mp3", List.of("audio/mpeg")), new ExType("mp4", List.of("video/mp4")), new ExType("odp", List.of("application/vnd.oasis.opendocument.presentation")), new ExType("ods", List.of("application/vnd.oasis.opendocument.spreadsheet")), new ExType("odt", List.of("application/vnd.oasis.opendocument.text")), new ExType("pdf", List.of("application/pdf")), - new ExType("php", List.of("text/plain", "text/php")), + new ExType("php", List.of("text/plain", "text/php", "application/x-php")), new ExType("png", List.of("image/png")), new ExType("ppt", List.of("application/vnd.ms-powerpoint")), new ExType("pptx",List.of("application/vnd.openxmlformats-officedocument.presentationml.presentation")), new ExType("py", List.of("text/plain", "text/x-python", "text/x-python-script")), - new ExType("rar", List.of("application/rar", "application/vnd.rar")), + new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar")), new ExType("rtf", List.of("application/rtf", "text/rtf")), new ExType("webm", List.of("video/webm")), new ExType("webp", List.of("image/webp")), diff --git a/test/jdk/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java b/test/jdk/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java index 9b8ed213160787cc8e9344e8024bc4f7e5dd40c1..568eeb1e6bedf14986d60d42a990c6b8d7ed6751 100644 --- a/test/jdk/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java +++ b/test/jdk/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * 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,7 +22,7 @@ */ /* @test - * + * @bug 8280642 * @summary functional test for RMIClassLoader.loadProxyClass; test * ensures that the default RMI class loader provider implements * RMIClassLoader.loadProxyClass correctly. @@ -48,6 +48,7 @@ import java.rmi.MarshalledObject; import java.net.URL; import java.net.URLClassLoader; import java.io.Serializable; +import java.io.InvalidClassException; import java.io.IOException; import java.util.Arrays; @@ -205,20 +206,20 @@ public class LoadProxyClasses { currentThread.getContextClassLoader(); currentThread.setContextClassLoader(nonpublicLoaderB); - IllegalAccessError illegal = null; + InvalidClassException invalid = null; try { unmarshalProxyClass(proxy4, fnnLoader2, nonpublicLoaderB, 4, null); - } catch (IllegalAccessError e) { - illegal = e; + } catch (InvalidClassException e) { + invalid = e; } - if (illegal == null) { - TestLibrary.bomb("case4: IllegalAccessError not thrown " + + if (invalid == null) { + TestLibrary.bomb("case4: InvalidClassException not thrown " + "when multiple nonpublic interfaces have \n" + "different class loaders"); } else { - System.err.println("\ncase4: IllegalAccessError correctly " + + System.err.println("\ncase4: InvalidClassException correctly " + "thrown \n when trying to load proxy " + "with multiple nonpublic interfaces in \n" + " different class loaders"); diff --git a/test/jdk/java/security/KeyFactory/KeyFactoryGetKeySpecForInvalidSpec.java b/test/jdk/java/security/KeyFactory/KeyFactoryGetKeySpecForInvalidSpec.java index e5c4c5457f3b11c9c0549096a32747a39132adc4..e72d5c8decc3fa8b82b7d84f2bca41712ed229db 100644 --- a/test/jdk/java/security/KeyFactory/KeyFactoryGetKeySpecForInvalidSpec.java +++ b/test/jdk/java/security/KeyFactory/KeyFactoryGetKeySpecForInvalidSpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/java/security/KeyStore/PKCS12/UnmodifiableAttributes.java b/test/jdk/java/security/KeyStore/PKCS12/UnmodifiableAttributes.java new file mode 100644 index 0000000000000000000000000000000000000000..ae38a6af71ec578970d1107aa405d5ca7115ae80 --- /dev/null +++ b/test/jdk/java/security/KeyStore/PKCS12/UnmodifiableAttributes.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8278744 + * @summary KeyStore:getAttributes() not returning unmodifiable Set + * @library /test/lib + */ + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.Utils; + +import java.io.File; +import java.security.KeyStore; + +public class UnmodifiableAttributes { + public static final void main(String[] args) throws Exception { + + var oneAttr = new KeyStore.Entry.Attribute() { + @Override + public String getName() { + return "1.2.3"; + } + + @Override + public String getValue() { + return "testVal"; + } + }; + char[] pass = "changeit".toCharArray(); + + SecurityTools.keytool("-keystore ks -storepass changeit -genkeypair -alias a -dname CN=A -keyalg EC") + .shouldHaveExitValue(0); + + KeyStore ks = KeyStore.getInstance(new File("ks"), pass); + + var attrs = ks.getAttributes("a"); + Utils.runAndCheckException(() -> attrs.add(oneAttr), UnsupportedOperationException.class); + + var attrs2 = ks.getEntry("a", new KeyStore.PasswordProtection(pass)).getAttributes(); + Utils.runAndCheckException(() -> attrs2.add(oneAttr), UnsupportedOperationException.class); + } +} diff --git a/test/jdk/java/security/MessageDigest/ThreadSafetyTest.java b/test/jdk/java/security/MessageDigest/ThreadSafetyTest.java index 41ecbca2677b5188f05d0ce15ad771ae5859ca38..594e9926eabbf7ea83b8c03d48bd6324eb187ff9 100644 --- a/test/jdk/java/security/MessageDigest/ThreadSafetyTest.java +++ b/test/jdk/java/security/MessageDigest/ThreadSafetyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Azul Systems, Inc. All rights reserved. + * Copyright (c) 2020, 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,9 @@ /* * @test - * @bug 8241960 + * @bug 8241960 8277353 * @summary Confirm that java.security.MessageDigest is thread-safe after clone. - * @run main/othervm ThreadSafetyTest 5 4 + * @run main ThreadSafetyTest 4 2 */ import java.security.MessageDigest; @@ -56,7 +56,7 @@ public class ThreadSafetyTest { duration = Integer.parseInt(args[1]); } int nProcessors = Runtime.getRuntime().availableProcessors(); - int nTasks = nProcessors * threadsFactor; + int nTasks = Math.min(nProcessors, 4) * threadsFactor; System.out.println("Testing with " + nTasks + " threads on " + nProcessors + " processors for " + duration + diff --git a/test/jdk/java/security/Provider/CaseSensitiveServices.java b/test/jdk/java/security/Provider/CaseSensitiveServices.java index 2a6676b4f582b3c2d160ca80495e158eab5f3348..d9b8d315bd033e8cebb553716b44b43737462eb8 100644 --- a/test/jdk/java/security/Provider/CaseSensitiveServices.java +++ b/test/jdk/java/security/Provider/CaseSensitiveServices.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * 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 5097015 8130181 + * @bug 5097015 8130181 8279222 * @summary make sure we correctly treat Provider string entries as case insensitive * @author Andreas Sterbenz */ @@ -36,9 +36,12 @@ public class CaseSensitiveServices extends Provider { super("Foo", "1.0", null); put("MessageDigest.Foo", "com.Foo"); put("mESSAGEdIGEST.fOO xYz", "aBc"); - put("ALg.aliaS.MESSAGEdigest.Fu", "FoO"); + // first assign the DEF alias to algorithm Foo + put("ALg.aliaS.MESSAGEdigest.DEF", "FoO"); put("messageDigest.Bar", "com.Bar"); put("MESSAGEDIGEST.BAZ", "com.Baz"); + // reassign the DEF alias to algorithm Bar + put("ALg.aliaS.MESSAGEdigest.DEF", "Bar"); } public static void main(String[] args) throws Exception { @@ -47,12 +50,21 @@ public class CaseSensitiveServices extends Provider { if (p.getServices().size() != 3) { throw new Exception("services.size() should be 3"); } + Service s = testService(p, "MessageDigest", "fOO"); String val = s.getAttribute("Xyz"); if ("aBc".equals(val) == false) { throw new Exception("Wrong value: " + val); } - testService(p, "MessageDigest", "fU"); + if (s.toString().indexOf("DEF") != -1) { + throw new Exception("Old alias DEF should be removed"); + } + + // test Service alias DEF and its associated impl is Bar + s = testService(p, "MessageDigest", "DeF"); + if (s.getAttribute("Xyz") != null) { + throw new Exception("DEF mapped to the wrong impl"); + } testService(p, "MessageDigest", "BAR"); testService(p, "MessageDigest", "baz"); System.out.println("OK"); diff --git a/test/jdk/java/security/spec/IsAssignableFromOrder.java b/test/jdk/java/security/spec/IsAssignableFromOrder.java new file mode 100644 index 0000000000000000000000000000000000000000..db2b765283094498fa377504264a59fbe501160e --- /dev/null +++ b/test/jdk/java/security/spec/IsAssignableFromOrder.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import sun.security.util.CurveDB; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import javax.crypto.spec.DESedeKeySpec; +import javax.crypto.spec.DHParameterSpec; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.OAEPParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; +import javax.crypto.spec.RC2ParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.AlgorithmParameters; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.DSAParameterSpec; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.ECParameterSpec; +import java.security.spec.KeySpec; +import java.security.spec.PSSParameterSpec; + +/** + * @test + * @bug 8279800 + * @modules java.base/sun.security.util + * @summary isAssignableFrom checks in AlgorithmParametersSpi.engineGetParameterSpec appear to be backwards + */ + +public class IsAssignableFromOrder { + + public static void main(String[] args) throws Exception { + + // AlgorithmParameters + testAlgSpec("AES", new IvParameterSpec(new byte[16])); + testAlgSpec("ChaCha20-Poly1305", new IvParameterSpec(new byte[12])); + testAlgSpec("DiffieHellman", new DHParameterSpec(BigInteger.ONE, BigInteger.TWO)); + testAlgSpec("GCM", new GCMParameterSpec(96, new byte[16])); + testAlgSpec("OAEP", OAEPParameterSpec.DEFAULT); + testAlgSpec("PBEWithSHA1AndDESede", new PBEParameterSpec( + "saltsalt".getBytes(StandardCharsets.UTF_8), 10000)); + testAlgSpec("PBEWithHmacSHA256AndAES_256", new PBEParameterSpec( + "saltsalt".getBytes(StandardCharsets.UTF_8), 10000, + new IvParameterSpec(new byte[16]))); + testAlgSpec("RC2", new RC2ParameterSpec(256, new byte[32])); + testAlgSpec("DSA", new DSAParameterSpec( + BigInteger.ONE, BigInteger.TWO, BigInteger.TEN)); + testAlgSpec("RSASSA-PSS", PSSParameterSpec.DEFAULT); + testAlgSpec("EC", new ECGenParameterSpec("secp256r1")); + testAlgSpec("EC", CurveDB.lookup("secp256r1"), + ECParameterSpec.class, AlgorithmParameterSpec.class); + + // SecretKeyFactory + var spec = new PBEKeySpec( + "password".toCharArray(), + "saltsalt".getBytes(StandardCharsets.UTF_8), + 10000, + 32); + + testKeySpec("PBE", spec, PBEKeySpec.class); + testKeySpec("PBEWithHmacSHA256AndAES_256", spec, PBEKeySpec.class); + testKeySpec("PBKDF2WithHmacSHA1", spec, PBEKeySpec.class); + + testKeySpec("DES", new SecretKeySpec(new byte[8], "DES"), DESKeySpec.class); + testKeySpec("DESede", new SecretKeySpec(new byte[24], "DESede"), DESedeKeySpec.class); + } + + + static void testAlgSpec(String algorithm, AlgorithmParameterSpec spec, + Class<? extends AlgorithmParameterSpec>... classes) throws Exception { + System.out.println(algorithm); + var ap1 = AlgorithmParameters.getInstance(algorithm); + ap1.init(spec); + var ap2 = AlgorithmParameters.getInstance(algorithm); + ap2.init(ap1.getEncoded()); + if (classes.length == 0) { + classes = new Class[]{spec.getClass(), AlgorithmParameterSpec.class}; + } + for (var c : classes) { + ap1.getParameterSpec(c); + ap2.getParameterSpec(c); + } + } + + static void testKeySpec(String algorithm, KeySpec spec, Class<?> clazz) + throws Exception { + System.out.println(algorithm); + var kf = SecretKeyFactory.getInstance(algorithm); + var key = kf.generateSecret(spec); + kf.getKeySpec(key, KeySpec.class); + kf.getKeySpec(key, clazz); + } +} diff --git a/test/jdk/java/time/test/java/time/format/TestZoneTextPrinterParser.java b/test/jdk/java/time/test/java/time/format/TestZoneTextPrinterParser.java index 7981d7699077b153f2306184694ec2181b929600..2686ea02b25ef0d84e2497292b8e74f8573fc3e6 100644 --- a/test/jdk/java/time/test/java/time/format/TestZoneTextPrinterParser.java +++ b/test/jdk/java/time/test/java/time/format/TestZoneTextPrinterParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ import org.testng.annotations.Test; /* * @test - * @bug 8081022 8151876 8166875 8177819 8189784 8206980 8277049 + * @bug 8081022 8151876 8166875 8177819 8189784 8206980 8277049 8278434 * @key randomness */ @@ -61,6 +61,11 @@ import org.testng.annotations.Test; @Test public class TestZoneTextPrinterParser extends AbstractTestPrinterParser { + private static final Locale[] SAMPLE_LOCALES = { + Locale.US, Locale.UK, Locale.FRANCE, Locale.GERMANY, Locale.ITALY, Locale.forLanguageTag("es"), + Locale.forLanguageTag("pt-BR"), Locale.forLanguageTag("ru"), + Locale.CHINA, Locale.TAIWAN, Locale.JAPAN, Locale.KOREA, Locale.ROOT}; + protected static DateTimeFormatter getFormatter(Locale locale, TextStyle style) { return new DateTimeFormatterBuilder().appendZoneText(style) .toFormatter(locale) @@ -70,7 +75,6 @@ public class TestZoneTextPrinterParser extends AbstractTestPrinterParser { public void test_printText() { Random r = RandomFactory.getRandom(); int N = 8; - Locale[] locales = Locale.getAvailableLocales(); Set<String> zids = ZoneRulesProvider.getAvailableZoneIds(); ZonedDateTime zdt = ZonedDateTime.now(); @@ -85,7 +89,7 @@ public class TestZoneTextPrinterParser extends AbstractTestPrinterParser { zdt = zdt.withZoneSameLocal(ZoneId.of(zid)); TimeZone tz = TimeZone.getTimeZone(zid); boolean isDST = tz.inDaylightTime(new Date(zdt.toInstant().toEpochMilli())); - for (Locale locale : locales) { + for (Locale locale : SAMPLE_LOCALES) { String longDisplayName = tz.getDisplayName(isDST, TimeZone.LONG, locale); String shortDisplayName = tz.getDisplayName(isDST, TimeZone.SHORT, locale); if ((longDisplayName.startsWith("GMT+") && shortDisplayName.startsWith("GMT+")) @@ -118,9 +122,8 @@ public class TestZoneTextPrinterParser extends AbstractTestPrinterParser { } public void test_ParseText() { - Locale[] locales = new Locale[] { Locale.ENGLISH, Locale.JAPANESE, Locale.FRENCH }; Set<String> zids = ZoneRulesProvider.getAvailableZoneIds(); - for (Locale locale : locales) { + for (Locale locale : SAMPLE_LOCALES) { parseText(zids, locale, TextStyle.FULL, false); parseText(zids, locale, TextStyle.FULL, true); parseText(zids, locale, TextStyle.SHORT, false); diff --git a/test/jdk/java/util/Hashtable/DeserializedLength.java b/test/jdk/java/util/Hashtable/DeserializedLength.java index 376c1f026d0ebc1f03bebf83d77de6cbe4334e8e..d515878fd3600208cced4a6e8cf1ff935ecbb110 100644 --- a/test/jdk/java/util/Hashtable/DeserializedLength.java +++ b/test/jdk/java/util/Hashtable/DeserializedLength.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,7 +100,7 @@ public class DeserializedLength { ); for (int elements : new int[]{10, 50, 500, 5000}) { - for (float loadFactor : new float[]{0.15f, 0.5f, 0.75f, 1.0f, 2.5f}) { + for (float loadFactor : new float[]{0.25f, 0.5f, 0.75f, 1.0f, 2.5f}) { ok &= testDeserializedLength(elements, loadFactor); } } diff --git a/test/jdk/java/util/Locale/Bug7069824.java b/test/jdk/java/util/Locale/Bug7069824.java index 0eb1f21c2756f0a1aec8cfa6cd865d1a9796b872..905cde17d50202deab7760de47dbfea529e34f95 100644 --- a/test/jdk/java/util/Locale/Bug7069824.java +++ b/test/jdk/java/util/Locale/Bug7069824.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * 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 7069824 8042360 8032842 8175539 8210443 8242010 + * @bug 7069824 8042360 8032842 8175539 8210443 8242010 8276302 * @summary Verify implementation for Locale matching. * @run testng/othervm Bug7069824 */ @@ -208,27 +208,61 @@ public class Bug7069824 { Object[][] LFilterTagsData() { return new Object[][] { // Range, LanguageTags, FilteringMode, Expected language tags + {"fr-FR, fr-BG;q=0.8, *;q=0.5, en;q=0", "en-US, fr-FR, fr-CA, fr-BG", + null, "fr-FR, fr-BG, fr-CA"}, + {"fr-FR, fr-*-BG;q=0.8, *;q=0.5, en;q=0", "en-US, fr-FR, fr-CA, fr-BG", + null, "fr-FR, fr-BG, fr-CA"}, + {"en;q=0.2, *;q=0.6, ja", "de-DE, en, ja-JP-hepburn, fr-JP, he", - null, "de-DE, en, ja-JP-hepburn, fr-JP, he"}, + null, "ja-JP-hepburn, de-DE, en, fr-JP, he"}, {"en;q=0.2, ja-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he", null, "ja-JP-hepburn, en"}, {"en;q=0.2, ja-JP, fr-JP, iw", "de-DE, he, en, ja-JP-hepburn, fr, he-IL", null, "ja-JP-hepburn, he, he-IL, en"}, {"en;q=0.2, ja-JP, fr-JP, he", "de-DE, en, ja-JP-hepburn, fr, iw-IL", null, "ja-JP-hepburn, iw-IL, en"}, + {"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", - MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"}, + null, "de-DE, de-DE-x-goethe"}, + {"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", + null, + "de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + + "de-Latn-DE-1996, de-Deva-DE"}, + {"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", EXTENDED_FILTERING, "de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " - + "de-Latn-DE-1996, de-Deva-DE"}, + + "de-Latn-DE-1996, de-Deva-DE"}, {"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", EXTENDED_FILTERING, "de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " - + "de-Latn-DE-1996, de-Deva-DE"}, + + "de-Latn-DE-1996, de-Deva-DE"}, + + {"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", + IGNORE_EXTENDED_RANGES, + "de-DE, de-DE-x-goethe"}, + {"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", + IGNORE_EXTENDED_RANGES, + ""}, + + {"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", + MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"}, + {"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", + MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"}, + + {"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", + REJECT_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"}, + + // The next test in this chain is in testLFilterTagsIAE. }; } @@ -380,6 +414,15 @@ public class Bug7069824 { ranges, tags, expectedTags, actualTags)); } + @Test(expectedExceptions = IllegalArgumentException.class) + public void testLFilterTagsIAE() { + String ranges = "de-*-DE"; + String tags = "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " + + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva"; + List<LanguageRange> priorityList = LanguageRange.parse(ranges); + showLanguageTags(Locale.filterTags(priorityList, generateLanguageTags(tags), REJECT_EXTENDED_RANGES)); + } + @Test(dataProvider = "LLookupData") public void testLLookup(String ranges, String tags, String expectedLocale) { List<LanguageRange> priorityList = LanguageRange.parse(ranges); diff --git a/test/jdk/java/util/Objects/BasicObjectsTest.java b/test/jdk/java/util/Objects/BasicObjectsTest.java index a7636ef11d52b91b99e0af2c9a888955c30b40fe..51268d4cbaf4c0a236dc6b74358faca3f7905d40 100644 --- a/test/jdk/java/util/Objects/BasicObjectsTest.java +++ b/test/jdk/java/util/Objects/BasicObjectsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. * 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,8 @@ /* * @test - * @bug 6797535 6889858 6891113 8013712 8011800 8014365 + * @bug 6797535 6889858 6891113 8013712 8011800 8014365 8280168 * @summary Basic tests for methods in java.util.Objects - * @author Joseph D. Darcy */ import java.util.*; @@ -40,6 +39,7 @@ public class BasicObjectsTest { errors += testHash(); errors += testToString(); errors += testToString2(); + errors += testToIdentityString(); errors += testCompare(); errors += testRequireNonNull(); errors += testIsNull(); @@ -134,6 +134,37 @@ public class BasicObjectsTest { return errors; } + private static int testToIdentityString() { + int errors = 0; + // Test null behavior + try { + Objects.toIdentityString(null); + errors++; + } catch (NullPointerException npe) { + ; // Expected + } + // Behavior on typical objects + Object o = new Object(){}; + errors += (Objects.toIdentityString(o).equals(o.toString()))? 0 : 1; + // Verify object's toString *not* called + Object badToString = new Object() { + @Override + public String toString() { + throw new RuntimeException(); + } + }; + Objects.toIdentityString(badToString); + // Verify object's hashCode *not* called + Object badHashCode = new Object() { + @Override + public int hashCode() { + throw new RuntimeException("0xDEADBEFF"); + } + }; + Objects.toIdentityString(badHashCode); + return errors; + } + private static int testCompare() { int errors = 0; String[] values = {"e. e. cummings", "zzz"}; diff --git a/test/jdk/java/util/Random/RandomNextDoubleBoundary.java b/test/jdk/java/util/Random/RandomNextDoubleBoundary.java new file mode 100644 index 0000000000000000000000000000000000000000..971b22d55c14da5304a61c05c6393cc06b058d15 --- /dev/null +++ b/test/jdk/java/util/Random/RandomNextDoubleBoundary.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Verify nextDouble stays within range + * @bug 8280550 8280950 + */ + +import java.util.SplittableRandom; +import java.util.random.RandomGenerator; + +public class RandomNextDoubleBoundary { + public static void main(String... args) { + negativeBounds(); + positiveBounds(); + } + + private static void negativeBounds() { + // Both bounds are negative + double lowerBound = -1.0000000000000002; + double upperBound = -1.0; + var sr = new SplittableRandom(42L); + var r = sr.nextDouble(lowerBound, upperBound); + + if (r >= upperBound) { + System.err.println("r = " + r + "\t" + Double.toHexString(r)); + System.err.println("ub = " + upperBound + "\t" + Double.toHexString(upperBound)); + throw new RuntimeException("Greater than upper bound"); + } + + if (r < lowerBound) { + System.err.println("r = " + r + "\t" + Double.toHexString(r)); + System.err.println("lb = " + lowerBound + "\t" + Double.toHexString(lowerBound)); + throw new RuntimeException("Less than lower bound"); + } + } + + private static void positiveBounds() { + double[][] originAndBounds = {{10, 100}, + {12345, 123456}, + {5432167.234, 54321678.1238}}; + for (double[] originAndBound : originAndBounds) { + nextDoublesWithRange(originAndBound[0], originAndBound[1]); + } + } + + public static void nextDoublesWithRange(double origin, double bound) { + RandomGenerator rg = new RandomGenerator() { + @Override + public double nextDouble() { + return Double.MAX_VALUE; + } + + @Override + public long nextLong() { + return 0; + } + }; + double value = rg.nextDouble(origin, bound); + + assertTrue(value >= origin); + assertTrue(value < bound); + } + + public static void assertTrue(boolean condition) { + if (!condition) { + throw new AssertionError(); + } + } +} diff --git a/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java b/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java index 0f52bc67f085a115d4c4d3ffdddab360fc4e9816..922b18836dd877a36090f4cc0a601c2bec6b4a1b 100644 --- a/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java +++ b/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java @@ -45,6 +45,14 @@ * @run main/timeout=1600 MapLoops */ +/* + * @test + * @summary Exercise multithreaded maps, using only heavy monitors. + * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch == "ppc64" | os.arch == "ppc64le" + * @library /test/lib + * @run main/othervm/timeout=1600 -XX:+IgnoreUnrecognizedVMOptions -XX:+UseHeavyMonitors -XX:+VerifyHeavyMonitors MapLoops + */ + import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.util.List; diff --git a/test/jdk/java/util/regex/RegExTest.java b/test/jdk/java/util/regex/RegExTest.java index 370b0d9696b406476176c2b4a934578709ac13df..f46ce327f03e44fbcd32345c7527434897d9da04 100644 --- a/test/jdk/java/util/regex/RegExTest.java +++ b/test/jdk/java/util/regex/RegExTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ * 8151481 4867170 7080302 6728861 6995635 6736245 4916384 6328855 6192895 * 6345469 6988218 6693451 7006761 8140212 8143282 8158482 8176029 8184706 * 8194667 8197462 8184692 8221431 8224789 8228352 8230829 8236034 8235812 - * 8216332 8214245 8237599 8241055 8247546 8258259 8037397 8269753 + * 8216332 8214245 8237599 8241055 8247546 8258259 8037397 8269753 8276694 * * @library /test/lib * @library /lib/testlibrary/java/lang @@ -4538,4 +4538,22 @@ public class RegExTest { var sep = System.lineSeparator(); assertTrue(e.getMessage().contains(sep + "\t ^")); } + + //This test is for 8276694 + @Test + public static void unescapedBackslash() { + String pattern = "\\"; + var e = expectThrows(PatternSyntaxException.class, () -> + Pattern.compile(pattern)); + assertTrue(e.getMessage().contains("Unescaped trailing backslash")); + } + + //This test is for 8280403 + @Test + public static void badIntersectionSyntax() { + String pattern = "[˜\\H +F&&]"; + var e = expectThrows(PatternSyntaxException.class, () -> + Pattern.compile(pattern)); + assertTrue(e.getMessage().contains("Bad intersection syntax")); + } } diff --git a/test/jdk/java/util/zip/ZipFile/TestTooManyEntries.java b/test/jdk/java/util/zip/ZipFile/TestTooManyEntries.java new file mode 100644 index 0000000000000000000000000000000000000000..07ed760c1b76af5917b6bcd4c9aae693dcd0b927 --- /dev/null +++ b/test/jdk/java/util/zip/ZipFile/TestTooManyEntries.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8272746 + * @summary ZipFile can't open big file (NegativeArraySizeException) + * @requires (sun.arch.data.model == "64" & os.maxMemory > 8g) + * @run testng/manual/othervm -Xmx8g TestTooManyEntries + */ + +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; +import java.util.UUID; + +import static org.testng.Assert.assertThrows; + +public class TestTooManyEntries { + // Number of directories in the zip file + private static final int DIR_COUNT = 25000; + // Number of entries per directory + private static final int ENTRIES_IN_DIR = 1000; + + // Zip file to create for testing + private File hugeZipFile; + + /** + * Create a zip file and add entries that exceed the CEN limit. + * @throws IOException if an error occurs creating the ZIP File + */ + @BeforeTest + public void setup() throws IOException { + hugeZipFile = File.createTempFile("hugeZip", ".zip", new File(".")); + hugeZipFile.deleteOnExit(); + long startTime = System.currentTimeMillis(); + try (ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(hugeZipFile)))) { + for (int dirN = 0; dirN < DIR_COUNT; dirN++) { + String dirName = UUID.randomUUID() + "/"; + for (int fileN = 0; fileN < ENTRIES_IN_DIR; fileN++) { + ZipEntry entry = new ZipEntry(dirName + UUID.randomUUID()); + zip.putNextEntry(entry); + zip.closeEntry(); // all files are empty + } + if ((dirN + 1) % 1000 == 0) { + System.out.printf("%s / %s of entries written, file size is %sMb (%ss)%n", + (dirN + 1) * ENTRIES_IN_DIR, DIR_COUNT * ENTRIES_IN_DIR, hugeZipFile.length() / 1024 / 1024, + (System.currentTimeMillis() - startTime) / 1000); + } + } + } + } + + /** + * Validates that the ZipException is thrown when the ZipFile class + * is initialized with a zip file whose entries exceed the CEN limit. + */ + @Test + public void test() { + assertThrows(ZipException.class, () -> new ZipFile(hugeZipFile)); + } +} diff --git a/test/jdk/javax/accessibility/manual/ButtonDemo.html b/test/jdk/javax/accessibility/manual/ButtonDemo.html new file mode 100644 index 0000000000000000000000000000000000000000..c815fad3a9e2233ecc1791ea0ad87b00d9c7b4f6 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/ButtonDemo.html @@ -0,0 +1,80 @@ +<!-- +Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +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. +--> +<!DOCTYPE html> +<html> +<head> + <style> + table, th, td { + border: 1px solid black; +} + + </style> +</head> +<body> + + +<table> + <tr> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:5%;">S.No</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:25%;">Test</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:75%;">Scenario</th> + </tr> + <tr> + <td>1</td> + <td>Button Demo</td> + <td> + <ol> + <li> Tab until the Button Demo icon <img src="./resource/rbtn.png"> has focus. Press 'space' to + choose.<br> + <li> Tab until the "Button Demo" tab has focus. Press 'space'. Press 'tab'.<br> + <li> Use the arrow keys to navigate between "Buttons", "Radio Buttons", and "Check Boxes".<br> + <li> Tab to enter the demo pane. Tab & Shift-Tab to move between each button.<br> + <li> Press 'space' to trigger (i.e. "press") a button.<br> + <li> Repeat steps 1 through 5 for the <b>Radio Button</b> & <b>Check Boxes</b> tabs.<br> + </ol> + </td> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"><b>Expected Result</b></td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + <ol> + <li>Verify that as you navigate, the focus is shown, e.g.</li> + <img src="./resource/btn.png"> + <li>As you press 'space' to trigger each button, verify that you see each button visually depress. + e.g.: + </li> + <img src="./resource/dep.png"> + </ol> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"><b>Note: actual component appearence may vary depending on look and + feel.</b></td> + </tr> +</table> +</body> +</html> + diff --git a/test/jdk/javax/accessibility/manual/ButtonDemo.java b/test/jdk/javax/accessibility/manual/ButtonDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..0c352ebf906b587f4987cacefa8d2f152e8f21e4 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/ButtonDemo.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 +@key headful +@summary manual test for accessibility button demo +@run main/manual SwingSetTest ButtonDemo +*/ diff --git a/test/jdk/javax/accessibility/manual/ComboBoxDemo.html b/test/jdk/javax/accessibility/manual/ComboBoxDemo.html new file mode 100644 index 0000000000000000000000000000000000000000..aeb6e8f681a87294c95cfb6781c9ffbbd72417b5 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/ComboBoxDemo.html @@ -0,0 +1,75 @@ +<!-- +Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +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. +--> +<!DOCTYPE html> +<html> +<head> + <style> + table, th, td { + border: 1px solid black; +} + + </style> +</head> +<body> + + +<table> + <tr> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:5%;">S.No</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:25%;">Test</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:75%;">Scenario</th> + </tr> + <tr> + <td>1</td> + <td>ComboBox Demo</td> + <td> + <ol> + <li> Tab until ComboBox icon<img src="./resource/cmb.png"> has focus. Press 'Space' to choose.</li> + <li>Tab until the "ComboBox Demo" tab has focus. Press 'space'. Press 'tab'.</li> + <li> Use Tab and Shift-Tab to move between the four ComboBox widgets. + <li>Use the space and down arrow keys to bring up the drop-down list.</li> + <li> Use the up and down arrows to navigate up and down the list.</li> + <li>Use the 'space' key to make a the selection.</li> + <li> Repeat 4,5 but hit Esc key to cancel the drop-down.</li> + </ol> + </td> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"><b>Expected Result</b></td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + <ol> + <li>Verify that space and down arrow bring up the drop-down list.</li> + <img src="./resource/list.png"> + <li>Verify that up and down arrows move up and down the list.</li> + <li>Verify that 'space' makes the selection (the drop-down list should collapse).</li> + </ol> + </td> + </tr> +</table> +</body> +</html> + + \ No newline at end of file diff --git a/test/jdk/javax/accessibility/manual/ComboBoxDemo.java b/test/jdk/javax/accessibility/manual/ComboBoxDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..0522d3caa77f650c919e0847832915c52c14ce50 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/ComboBoxDemo.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 +@key headful +@summary manual test for accessibility button demo +@run main/manual SwingSetTest ComboBoxDemo +*/ diff --git a/test/jdk/javax/accessibility/manual/DemoSelection.html b/test/jdk/javax/accessibility/manual/DemoSelection.html new file mode 100644 index 0000000000000000000000000000000000000000..7f9a28b05a9cd1241953d2c253eb9a7d08343ce1 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/DemoSelection.html @@ -0,0 +1,66 @@ +<!-- +Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +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. +--> +<!DOCTYPE html> +<html> +<head> + <style> + table, th, td { + border: 1px solid black; +} + + </style> +</head> +<body> + + +<table> + <tr> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:5%;">S.No</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:25%;">Test</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:75%;">Scenario</th> + </tr> + <tr> + <td>1</td> + <td>Demo Selection</td> + <td>Move between demos with 'tab' and 'shift-tab', and left and right arrows. Type 'space' to activate a demo. + <img src="./resource/dms.png"> + </td> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"><b>Expected Result</b></td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + Verify that there is visible focus as you tab (or arrow) between demo icons. Typing 'space' should change + the selected demo. + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"><b>Note: actual component appearence may vary depending on look and + feel.</b></td> + </tr> +</table> +</body> +</html> + diff --git a/test/jdk/javax/accessibility/manual/DemoSelection.java b/test/jdk/javax/accessibility/manual/DemoSelection.java new file mode 100644 index 0000000000000000000000000000000000000000..f3e31aa88ecf6c93a1616edc51113868040b3291 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/DemoSelection.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 +@key headful +@summary manual test for accessibility button demo +@run main/manual SwingSetTest DemoSelection +*/ diff --git a/test/jdk/javax/accessibility/manual/OptionPaneDemo.html b/test/jdk/javax/accessibility/manual/OptionPaneDemo.html new file mode 100644 index 0000000000000000000000000000000000000000..23693043b5d21b7911f8c99060358e731e95ff26 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/OptionPaneDemo.html @@ -0,0 +1,78 @@ +<!-- +Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +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. +--> +<!DOCTYPE html> +<html> +<head> + <style> + table, th, td { + border: 1px solid black; +} + + </style> +</head> +<body> + + +<table> + <tr> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:5%;">S.No</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:25%;">Test</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:75%;">Scenario</th> + </tr> + <tr> + <td>1</td> + <td>OptionPane Demo</td> + <td> + <ol> + <li>Tab until the OptionPane icon <img src="./resource/op.png">has focus. Press 'space' to choose. + <li>Tab until the "OptionPane Demo" tab has focus. Press 'space'. Press 'tab'. The 'Show Input Dialog' + button should have focus. + <li>Press 'space'. An Input dialog should pop up. Type some text, and hit return. The dialog should + change to a Message dialog with text saying "That was a pretty good movie!" Press return. + <li>Bring up the dialog again (space). Press 'esc' and confirm that the dialog goes away without the + Message from above. + <li>Press Tab to move down through the buttons, and select "Component Dialog Example" (press space). A + dialog should appear. Tab to ensure that you can navigate through all the components:<br> + a. Textfield<br> + b. ComboBox<br> + c. All 4 buttons: "Cancel", "Probably", "Maybe", "No", "Yes".<br> + d. Press 'esc' to cancel the dialog.<br> + </ol> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + <b>Expected Result</b> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + When a popup window is created, focus must be on the popup window; when the window is closed, focus must + return to the previous focus point. + </td> + </tr> +</table> +</body> +</html> + + \ No newline at end of file diff --git a/test/jdk/javax/accessibility/manual/OptionPaneDemo.java b/test/jdk/javax/accessibility/manual/OptionPaneDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..42d3bade5297d2c094ff7084b4abc39e3ef3a361 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/OptionPaneDemo.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 +@key headful +@summary manual test for accessibility button demo +@run main/manual SwingSetTest OptionPaneDemo +*/ + diff --git a/test/jdk/javax/accessibility/manual/README.md b/test/jdk/javax/accessibility/manual/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3b96515c6326f34dac82c0521cca8cfd74f3ce07 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/README.md @@ -0,0 +1,79 @@ +<!-- +Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +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. +--> + +# Manual javax.accessibility test suite + +## Configure environment + +### Swing Set 2 + +Prepare an appropriate version of Swing Set 2 from JDK demos. + +### Acessibility frameworks + +Testing can be performed without an accessibility framework or with one of these frameworks: + +1. Windows + 1. JAWS + 2. NVDA +2. Mac OS X + 1. Voice over + +## Executing a test run + +* Start the required accessibility framework, if necessary +* Swing Set 2 jar default location is +<code><tested jdk>/demo/jfc/SwingSet2/SwingSet2.jar</code> +* To override Swing Set 2 jar use <code>SWINGSET2_JAR</code> environment variable: + + + jtreg ... -e:SWINGSET2_JAR=<file location> -m .../javax/accessibility/manual/... + + +## Performing tests + +When a test a started, a UI appears consisting of two frames: test framework frame and Swing Set 2 frame. Test framework +frame will contain a name of the test in the title and detailed instructions. + +1. Follow the test instructions +2. If everything goes as expected + 1. Push "Pass" + 2. UI for this test closes +3. If something goes not accordding to the instructions: + 1. Push "Fail" + 2. A screenshot is taken automatically + 3. Describe the problem + 4. Retake the screenshot, if necessary + 1. Interract with the Swing Set 2 UI to make it showing the failure. Hit "Retake screenshot" + 2. If to demonstrate the failure the UI need to be in a state which prevents using test framework UI, such as model dialogs need to be opened or menu expanded + 1. Enter delay (in seconds) + 2. Push "Retake screenshot" + 3. Prepare the UI + 4. Wait for the screenshot to be retaken + 5. Push "Fail" button again + 6. Screenshot and the description are saved for further analysis + 7. Test UI closes + +**Wasning: Do not close any window directly, all windows will be closed once the test is finished as passed or failed.** + +**Note: Keyboard navigation is supported throughout the test framework UI.** diff --git a/test/jdk/javax/accessibility/manual/SwingSetTest.java b/test/jdk/javax/accessibility/manual/SwingSetTest.java new file mode 100644 index 0000000000000000000000000000000000000000..33bc2ff430a50f34d977ef39a8d73ac0a39feade --- /dev/null +++ b/test/jdk/javax/accessibility/manual/SwingSetTest.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +import lib.ManualTestFrame; +import lib.TestResult; + +import javax.imageio.ImageIO; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.util.function.Supplier; + +import static java.io.File.separator; + +public class SwingSetTest { + + public static void main(String[] args) throws IOException, InterruptedException, + ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + System.out.println("test image " + System.getenv("TEST_IMAGE_DIR")); + Supplier<TestResult> resultSupplier = ManualTestFrame.showUI(args[0], + "Wait for SwingSet2 to load, follow the instructions, select pass or fail. " + + "Do not close windows manually.", + SwingSetTest.class.getResource(args[0] + ".html")); + String swingSetJar = System.getenv("SWINGSET2_JAR"); + if (swingSetJar == null) { + swingSetJar = "file://" + System.getProperty("java.home") + + separator + "demo" + + separator + "jfc" + + separator + "SwingSet2" + + separator + "SwingSet2.jar"; + } + System.out.println("Loading SwingSet2 from " + swingSetJar); + ClassLoader ss = new URLClassLoader(new URL[]{new URL(swingSetJar)}); + ss.loadClass("SwingSet2").getMethod("main", String[].class).invoke(null, (Object)new String[0]); + //this will block until user decision to pass or fail the test + TestResult result = resultSupplier.get(); + if (result != null) { + System.err.println("Failure reason: \n" + result.getFailureDescription()); + if (result.getScreenCapture() != null) { + File screenDump = new File(System.getProperty("test.classes") + separator + args[0] + ".png"); + System.err.println("Saving screen image to " + screenDump.getAbsolutePath()); + ImageIO.write(result.getScreenCapture(), "png", screenDump); + } + Throwable e = result.getException(); + if (e != null) { + throw new RuntimeException(e); + } else { + if (!result.getStatus()) throw new RuntimeException("Test failed!"); + } + } else { + throw new RuntimeException("No result returned!"); + } + } +} \ No newline at end of file diff --git a/test/jdk/javax/accessibility/manual/TableDemo.html b/test/jdk/javax/accessibility/manual/TableDemo.html new file mode 100644 index 0000000000000000000000000000000000000000..1f0b821b410c0e4979dd7dba1b735399d1e3fafa --- /dev/null +++ b/test/jdk/javax/accessibility/manual/TableDemo.html @@ -0,0 +1,81 @@ +<!-- +Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +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. +--> +<!DOCTYPE html> +<html> +<head> + <style> + table, th, td { + border: 1px solid black; +} + + </style> +</head> +<body> + + +<table> + <tr> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:5%;">S.No</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:25%;">Test</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:75%;">Scenario</th> + </tr> + <tr> + <td>1</td> + <td>Table Demo (tests table navigation, as well as textfield input)</td> + <td> + <ol> + <li>Tab until the Table icon <img src="./resource/tbld.png"> has focus. Press 'space' to choose. + <li>Tab until the "Table Demo" tab has focus. Press 'space'. Press 'tab'. "Reordering allowed" should + have focus. + <li>Tab to the Printing/Header textfield. Verify that you can type in some text. + <li>Continue tabbing until focus moves to the table. The table should show focus. + <li>Press the down arrow. "Mike Albers" should have focus. + <li>Use the right and left arrow keys to navigate between cells. + <li>Set focus to a text cell (e.g. someone's first name). Press space to edit. Type some text. Hit + 'enter' and verify the text has been changed. After editing a text cell and hitting 'enter', the + focus could remain on the current cell or go to the next line. + <li>Press the 'Page Up' and 'Page Down' keys (if available on your keyboard); verify that the Table + scrolls up and down, page by page. + <ol><br> + <img src="./resource/tbl.png"> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + <b>Expected Result</b> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + See above test description. + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"><b>Note: actual component appearence may vary depending on look and + feel.</b></td> + </tr> +</table> +</body> +</html> + + \ No newline at end of file diff --git a/test/jdk/javax/accessibility/manual/TableDemo.java b/test/jdk/javax/accessibility/manual/TableDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..ff56bcec4e8dcff58c69d4a67d369d2f0f3a5499 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/TableDemo.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 +@key headful +@summary manual test for accessibility button demo +@run main/manual SwingSetTest TableDemo +*/ diff --git a/test/jdk/javax/accessibility/manual/TabsDemo.html b/test/jdk/javax/accessibility/manual/TabsDemo.html new file mode 100644 index 0000000000000000000000000000000000000000..06a055d0229374d4a4a0c6bf8fd99a4b354366a6 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/TabsDemo.html @@ -0,0 +1,67 @@ +<!-- +Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +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. +--> +<!DOCTYPE html> +<html> +<head> + <style> + table, th, td { + border: 1px solid black; +} + + </style> +</head> +<body> + + +<table> + <tr> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:5%;">S.No</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:25%;">Test</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:75%;">Scenario</th> + </tr> + <tr> + <td>1</td> + <td>Tabs within demos (tests table navigation, as well as textfield input)</td> + <td> + Continue tabbing to enter a demo's pane. When the top demo tabs have focus, the left and right arrow keys + move between tabs.<br> + <img src="./resource/ifm.png"> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + <b>Expected Result</b> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + Verify that the selected tab changes, e.g. between 'Internal Frame Demo' and "Source Code'. + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"><b>Note: actual component appearence may vary depending on look and + feel.</b></td> + </tr> +</table> +</body> +</html> \ No newline at end of file diff --git a/test/jdk/javax/accessibility/manual/TabsDemo.java b/test/jdk/javax/accessibility/manual/TabsDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..35fad6abf825fd504b6cf4d5bc520a6566d77d9c --- /dev/null +++ b/test/jdk/javax/accessibility/manual/TabsDemo.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 +@key headful +@summary manual test for accessibility button demo +@run main/manual SwingSetTest TabsDemo +*/ + diff --git a/test/jdk/javax/accessibility/manual/TreeDemo.html b/test/jdk/javax/accessibility/manual/TreeDemo.html new file mode 100644 index 0000000000000000000000000000000000000000..c418b3e54048850e42dfc79bac00cb9336dd51a5 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/TreeDemo.html @@ -0,0 +1,65 @@ +<!-- +Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +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. +--> +<!DOCTYPE html> +<html> +<head> + <style> + table, th, td { + border: 1px solid black; +} + + </style> +</head> +<body> + + +<table> + <tr> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:5%;">S.No</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:25%;">Test</th> + <th style="background-color:rgb(204,255,255); font-weight:bold; width:75%;">Scenario</th> + </tr> + <tr> + <td>1</td> + <td>Tree Demo</td> + <td> + Tab until the Tree icon <img src="./resource/tree.png"> has focus. Press 'space' to choose. + Tab until the "Tree Demo" tab has focus. Press 'space'. Press 'tab'. Press the down arrow. "Music" should + have focus. + Navigate up and down the tree using the up and down arrow keys. + Expand and collapse folders using the right and left arrow keys. + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + <b>Expected Result</b> + </td> + </tr> + <tr> + <td style="Width:100%;" colspan="3"> + See above test description. + </td> + </tr> +</table> +</body> +</html> \ No newline at end of file diff --git a/test/jdk/javax/accessibility/manual/TreeDemo.java b/test/jdk/javax/accessibility/manual/TreeDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..1f38f9e9f73b8e10261e27cc59252c9d03ba7927 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/TreeDemo.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 +@key headful +@summary manual test for accessibility button demo +@run main/manual SwingSetTest TreeDemo +*/ diff --git a/test/jdk/javax/accessibility/manual/lib/DescriptionPane.java b/test/jdk/javax/accessibility/manual/lib/DescriptionPane.java new file mode 100644 index 0000000000000000000000000000000000000000..bdd0e23e78896a556d9b80fb3792d01d0bc4f9f3 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/lib/DescriptionPane.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package lib; + +import javax.swing.JEditorPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.io.IOException; +import java.net.URL; + +/** + * Displays instructions provided through a URL. + */ +class DescriptionPane extends JPanel { + + DescriptionPane(URL instructions) throws IOException { + JEditorPane editorPane = new JEditorPane(); + editorPane.setFocusable(false); + editorPane.setContentType("text/html"); + editorPane.setPage(instructions); + editorPane.setEditable(false); + + JScrollPane esp = new JScrollPane(editorPane); + esp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + esp.setPreferredSize(new Dimension(250, 350)); + + setLayout(new BorderLayout()); + + add(esp); + } +} diff --git a/test/jdk/javax/accessibility/manual/lib/FailureReasonPane.java b/test/jdk/javax/accessibility/manual/lib/FailureReasonPane.java new file mode 100644 index 0000000000000000000000000000000000000000..b1cfc0d32cbba7e87280237a0efdf9894f87873b --- /dev/null +++ b/test/jdk/javax/accessibility/manual/lib/FailureReasonPane.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package lib; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.util.function.Consumer; + +import static java.awt.BorderLayout.CENTER; +import static java.awt.BorderLayout.NORTH; + +/** + * Allows to enter reason for the test failure. + */ +class FailureReasonPane extends JPanel { + + private final JTextArea text; + + FailureReasonPane(Consumer<String> listener) { + setLayout(new BorderLayout(10, 10)); + add(new JLabel("Failure reason:"), NORTH); + text = new JTextArea(3, 10); + text.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + listener.accept(text.getText()); + } + + @Override + public void removeUpdate(DocumentEvent e) { + listener.accept(text.getText()); + } + + @Override + public void changedUpdate(DocumentEvent e) { + listener.accept(text.getText()); + } + }); + add(text, CENTER); + } + + public String getReason() { + return text.getText(); + } + + public void requestFocus() { + text.requestFocus(); + } +} diff --git a/test/jdk/javax/accessibility/manual/lib/ManualTestFrame.java b/test/jdk/javax/accessibility/manual/lib/ManualTestFrame.java new file mode 100644 index 0000000000000000000000000000000000000000..57117790b57980e25e4bf653c76eb3f0e13cb654 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/lib/ManualTestFrame.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package lib; + +import javax.swing.BorderFactory; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import javax.swing.JTextArea; +import javax.swing.border.BevelBorder; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import static java.awt.BorderLayout.*; +import static javax.swing.SwingUtilities.invokeAndWait; + +/** + * A frame which can be used to display manual test descriptions as well as, in case of a failure, + * enter failure reason and capture the screen. + */ +public class ManualTestFrame extends JFrame { + + private boolean alreadyFailed = false; + + private ManualTestFrame(String testName, String headerText, URL instructions, Consumer<TestResult> listener) throws IOException { + + super(testName); + + JLabel statusLabel = new JLabel("Follow test description, select \"Pass\" or \"Fail\""); + statusLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + PassFailPane[] passFail = new PassFailPane[1]; + FailureReasonPane failureReason = new FailureReasonPane(reason -> { + passFail[0].setFailEnabled(!reason.isEmpty()); + }); + ScreenImagePane image = new ScreenImagePane(e -> { + listener.accept(new TestResult(e)); + dispose(); + }); + + JPanel failureInfoPane = new JPanel(); + failureInfoPane.setLayout(new GridLayout(1, 2, 10, 10)); + failureInfoPane.add(failureReason); + failureInfoPane.add(image); + failureInfoPane.setVisible(false); + + JPanel main = new JPanel(); + main.setLayout(new BorderLayout(10, 10)); + DescriptionPane description = new DescriptionPane(instructions); + main.add(description, CENTER); + passFail[0] = new PassFailPane((status) -> { + if (status) { + listener.accept(new TestResult()); + dispose(); + } else { + if (!alreadyFailed) { + alreadyFailed = true; + split.setDividerLocation(.5); + failureInfoPane.setVisible(true); + pack(); + image.capture(); + failureReason.requestFocus(); + statusLabel.setText("Enter failure reason, re-take screenshot, push \"Fail\""); + } else { + listener.accept(new TestResult(failureReason.getReason(), image.getImage())); + dispose(); + } + } + }); + main.add(passFail[0], SOUTH); + + split.setLeftComponent(main); + split.setRightComponent(failureInfoPane); + split.setDividerLocation(1.); + + getContentPane().setLayout(new BorderLayout()); + + if (headerText != null) { + JTextArea warningLabel = new JTextArea(headerText); + warningLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); + warningLabel.setEditable(false); + warningLabel.setFocusable(false); + getContentPane().add(warningLabel, NORTH); + } + + getContentPane().add(statusLabel, SOUTH); + getContentPane().add(split, CENTER); + + setPreferredSize(new Dimension(800, 600)); + pack(); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + setVisible(true); + } + + /** + * Show a test control frame which allows a user to either pass or fail the test. + * @param testName + * @param headerText + * @param instructions + * @return Returning supplier blocks till the test is passed or failed by the user. + * @throws InterruptedException + * @throws InvocationTargetException + */ + public static Supplier<TestResult> showUI(String testName, String headerText, URL instructions) + throws InterruptedException, InvocationTargetException { + AtomicReference<TestResult> resultContainer = new AtomicReference<>(); + CountDownLatch latch = new CountDownLatch(1); + invokeAndWait(() -> { + try { + new ManualTestFrame(testName, headerText, instructions, (status) -> { + resultContainer.set(status); + latch.countDown(); + }); + } catch (IOException e) { + resultContainer.set(new TestResult(e)); + e.printStackTrace(); + } + }); + return () -> { + try { + latch.await(); + } catch (InterruptedException e) { + return new TestResult(e); + } + return resultContainer.get(); + }; + } + +} diff --git a/test/jdk/javax/accessibility/manual/lib/PassFailPane.java b/test/jdk/javax/accessibility/manual/lib/PassFailPane.java new file mode 100644 index 0000000000000000000000000000000000000000..0cc99353ef199819d77c0e950e3195f723b4da8c --- /dev/null +++ b/test/jdk/javax/accessibility/manual/lib/PassFailPane.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package lib; + +import javax.swing.JButton; +import javax.swing.JPanel; +import java.awt.HeadlessException; +import java.io.IOException; +import java.util.function.Consumer; + +/** + * Allows to chose if a test fails or passes. It is a multi-use component. A chosen answer can be confirmed later + * upon providing additional information. + */ +class PassFailPane extends JPanel { + private final Consumer<Boolean> listener; + + private final JButton btnPass = new JButton("Pass"); + private final JButton btnFail = new JButton("Fail"); + + /** + * @param listener gets called with true (pass) or false (fail). + * @throws HeadlessException + */ + PassFailPane(Consumer<Boolean> listener) + throws HeadlessException, IOException { + this.listener = listener; + + add(btnPass); + add(btnFail); + + btnPass.requestFocus(); + + btnPass.addActionListener((e) -> { + disableButtons(); + listener.accept(true); + }); + + btnFail.addActionListener((e) -> { + disableButtons(); + listener.accept(false); + }); + } + + private void disableButtons() { + btnFail.setEnabled(false); + btnPass.setEnabled(false); + } + + public void setFailEnabled(boolean enabled) { + btnFail.setEnabled(enabled); + } + +} diff --git a/test/jdk/javax/accessibility/manual/lib/ScreenImagePane.java b/test/jdk/javax/accessibility/manual/lib/ScreenImagePane.java new file mode 100644 index 0000000000000000000000000000000000000000..1d35b740dad9c49cc168e89021d94b015cbd9bd1 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/lib/ScreenImagePane.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package lib; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.text.NumberFormat; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import static java.awt.BorderLayout.CENTER; +import static java.awt.BorderLayout.NORTH; +import static java.lang.String.format; +import static javax.swing.SwingUtilities.invokeAndWait; +import static javax.swing.SwingUtilities.invokeLater; + +/** + * Allows ti take screenshot, possible with a delay to preapare the UI. + */ +class ScreenImagePane extends JPanel { + private final JPanel imagePanel; + private final JLabel imageLabel; + private final AtomicReference<BufferedImage> image = new AtomicReference<>(); + private final Rectangle screenRect; + private final JFormattedTextField delayField; + private final Consumer<Throwable> exceptionHandler; + + /** + * + * @param handler should an exception appear on other threads + */ + ScreenImagePane(Consumer<Throwable> handler) { + exceptionHandler = handler; + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + screenRect = new Rectangle(0, 0, screenSize.width, screenSize.height); + JPanel controls = new JPanel(); + delayField = new JFormattedTextField(NumberFormat.getNumberInstance()); + delayField.setText("0"); + delayField.setColumns(3); + JButton capture = new JButton("Retake screenshot"); + controls.add(new JLabel("in ")); + controls.add(delayField); + controls.add(new JLabel(" seconds ")); + controls.add(capture); + capture.addActionListener((e) -> capture()); + imagePanel = new JPanel(); + imageLabel = new JLabel(); + imagePanel.add(imageLabel); + + setLayout(new BorderLayout()); + add(controls, NORTH); + add(imagePanel, CENTER); + } + + public void capture() { + new Thread(() -> { + try { + int delay = Integer.parseInt(delayField.getText()); + invokeAndWait(() -> imageLabel.setIcon(null)); + while (delay > 0) { + String message = format("Retaking screenshot in %d seconds", delay); + invokeLater(() -> imageLabel.setText(message)); + delay--; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } + BufferedImage image = new Robot().createScreenCapture(screenRect); + ScreenImagePane.this.image.set(image); + int newWidth = imagePanel.getWidth(); + int newHeight = imagePanel.getHeight(); + float xratio = (float) newWidth / (float) image.getWidth(); + float yratio = (float) newHeight / (float) image.getHeight(); + if (xratio < yratio) { + newHeight = (int) (image.getHeight() * xratio); + } else { + newWidth = (int) (image.getWidth() * yratio); + } + Image scaled = image.getScaledInstance(newWidth, newHeight, Image.SCALE_FAST); + invokeAndWait(() -> { + imageLabel.setText(null); + imageLabel.setIcon(new ImageIcon(scaled)); + }); + } catch (Throwable e) { + exceptionHandler.accept(e); + } + }).start(); + } + + public BufferedImage getImage() { + return image.get(); + } +} diff --git a/test/jdk/javax/accessibility/manual/lib/TestResult.java b/test/jdk/javax/accessibility/manual/lib/TestResult.java new file mode 100644 index 0000000000000000000000000000000000000000..42e5c72a49e6e85aeb6dcfcf88f8f40f0cd37315 --- /dev/null +++ b/test/jdk/javax/accessibility/manual/lib/TestResult.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package lib; + +import java.awt.image.BufferedImage; + +public final class TestResult { + private final boolean status; + private final String failureDescription; + private final BufferedImage screenCapture; + private final Throwable exception; + + /** + * Failed due to an exception. + */ + public TestResult(Throwable exception) { + status = false; + failureDescription = exception.getMessage(); + screenCapture = null; + this.exception = exception; + } + + /** + * Failed by used decision. + */ + public TestResult(String description, BufferedImage capture) { + status = false; + failureDescription = description; + screenCapture = capture; + exception = null; + } + + /** + * Passed. + */ + public TestResult() { + this.status = true; + failureDescription = null; + screenCapture = null; + exception = null; + } + + /** + * true - pass, false - no pass. + */ + public boolean getStatus() { + return status; + } + + public String getFailureDescription() { + return failureDescription; + } + + public BufferedImage getScreenCapture() { + return screenCapture; + } + + public Throwable getException() {return exception;} +} diff --git a/test/jdk/javax/accessibility/manual/resource/btn.png b/test/jdk/javax/accessibility/manual/resource/btn.png new file mode 100644 index 0000000000000000000000000000000000000000..0523db95125a121f77cbc2918a38b5937bb9a368 Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/btn.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/cmb.png b/test/jdk/javax/accessibility/manual/resource/cmb.png new file mode 100644 index 0000000000000000000000000000000000000000..02d989660c06976f12e982ad726f3a82d3014981 Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/cmb.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/dep.png b/test/jdk/javax/accessibility/manual/resource/dep.png new file mode 100644 index 0000000000000000000000000000000000000000..89d15e2b5dbde4c621ed8b6611f89f1a87ab7648 Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/dep.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/dms.png b/test/jdk/javax/accessibility/manual/resource/dms.png new file mode 100644 index 0000000000000000000000000000000000000000..63809383c5e7aa7a1595b4ed2dbaaeea3567d7bd Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/dms.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/hc.jpg b/test/jdk/javax/accessibility/manual/resource/hc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..773ca040dcb8439dcbb23ea6dc42dcd30d0154d1 Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/hc.jpg differ diff --git a/test/jdk/javax/accessibility/manual/resource/if.png b/test/jdk/javax/accessibility/manual/resource/if.png new file mode 100644 index 0000000000000000000000000000000000000000..3c978d685eb325db0809048d882fe2c9c1b75888 Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/if.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/ifm.png b/test/jdk/javax/accessibility/manual/resource/ifm.png new file mode 100644 index 0000000000000000000000000000000000000000..483ae7c76e33c94c56cd0914a59e75926274d598 Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/ifm.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/list.png b/test/jdk/javax/accessibility/manual/resource/list.png new file mode 100644 index 0000000000000000000000000000000000000000..1e026e83b2b2111de4c1018a5bad977c4d2e520d Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/list.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/op.png b/test/jdk/javax/accessibility/manual/resource/op.png new file mode 100644 index 0000000000000000000000000000000000000000..82ff0253d6eb107b46e81ceab768ac3f2e13f882 Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/op.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/rbtn.png b/test/jdk/javax/accessibility/manual/resource/rbtn.png new file mode 100644 index 0000000000000000000000000000000000000000..807f29b58c14b69d2140ddbf5346d414cdd9fabb Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/rbtn.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/tbl.png b/test/jdk/javax/accessibility/manual/resource/tbl.png new file mode 100644 index 0000000000000000000000000000000000000000..f2eef6a2fb47cbb6be93d50926e32faa2a9db97a Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/tbl.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/tbld.png b/test/jdk/javax/accessibility/manual/resource/tbld.png new file mode 100644 index 0000000000000000000000000000000000000000..8e2a3b77d1a2387f57054bed52f0d663ad278ac0 Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/tbld.png differ diff --git a/test/jdk/javax/accessibility/manual/resource/tree.png b/test/jdk/javax/accessibility/manual/resource/tree.png new file mode 100644 index 0000000000000000000000000000000000000000..9e7f1daa06466e7dd30e675ef5a9d95defb0606c Binary files /dev/null and b/test/jdk/javax/accessibility/manual/resource/tree.png differ diff --git a/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java b/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java index f5455cc918e172f3460cc2ef3003b3fb9b311d3c..fbb62441e1c053db6ff335a4647fa0ab98bbda6a 100644 --- a/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java +++ b/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /* * @test - * @bug 8211806 + * @bug 8211806 8277881 * @summary TLS 1.3 handshake server name indication is missing on a session resume * @run main/othervm ResumeTLS13withSNI */ @@ -338,6 +338,9 @@ public class ResumeTLS13withSNI { // Get the legacy session length and skip that many bytes int sessIdLen = Byte.toUnsignedInt(resCliHello.get()); + if (sessIdLen == 0) { + throw new Exception("SessionID field empty"); + } resCliHello.position(resCliHello.position() + sessIdLen); // Skip over all the cipher suites diff --git a/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java b/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java new file mode 100644 index 0000000000000000000000000000000000000000..20ebc144088767036b1a1913eec91f886c2d5276 --- /dev/null +++ b/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * 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 8806542 + * @summary Trailing dot in hostname causes TLS handshake to fail + * @library /javax/net/ssl/templates + * @run main/othervm -Djdk.net.hosts.file=hostsForExample EndingDotHostname + */ + +import javax.net.ssl.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class EndingDotHostname { + public static void main(String[] args) throws Exception { + System.setProperty("jdk.net.hosts.file", "hostsForExample"); + (new EndingDotHostname()).run(); + } + + public void run() throws Exception { + bootUp(); + } + + // ================================================= + // Stuffs to boot up the client-server mode testing. + private Thread serverThread = null; + private volatile Exception serverException = null; + private volatile Exception clientException = null; + + // Is the server ready to serve? + protected final CountDownLatch serverCondition = new CountDownLatch(1); + + // Is the client ready to handshake? + protected final CountDownLatch clientCondition = new CountDownLatch(1); + + // What's the server port? Use any free port by default + protected volatile int serverPort = 0; + + // Boot up the testing, used to drive remainder of the test. + private void bootUp() throws Exception { + Exception startException = null; + try { + startServer(); + startClient(); + } catch (Exception e) { + startException = e; + } + + // Wait for other side to close down. + if (serverThread != null) { + serverThread.join(); + } + + // The test is pretty much over. Which side threw an exception? + Exception local = clientException; + Exception remote = serverException; + + Exception exception = null; + + // Check various exception conditions. + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + // If there was an exception *AND* a startException, output it. + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! + } + + private void startServer() { + serverThread = new Thread(() -> { + try { + doServerSide(); + } catch (Exception e) { + // Our server thread just died. Release the client, + // if not active already... + serverException = e; + } + }); + + serverThread.start(); + } + + private void startClient() { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + + protected void doServerSide() throws Exception { + // kick off the server side service + SSLContext context = SSLExampleCert.createServerSSLContext(); + SSLServerSocketFactory sslssf = context.getServerSocketFactory(); + + SSLServerSocket sslServerSocket = + (SSLServerSocket)sslssf.createServerSocket(); + sslServerSocket.bind(new InetSocketAddress( + InetAddress.getLoopbackAddress(), 0)); + serverPort = sslServerSocket.getLocalPort(); + + // Signal the client, the server is ready to accept connection. + serverCondition.countDown(); + + // Try to accept a connection in 30 seconds. + SSLSocket sslSocket; + try { + sslServerSocket.setSoTimeout(30000); + sslSocket = (SSLSocket)sslServerSocket.accept(); + } catch (SocketTimeoutException ste) { + // Ignore the test case if no connection within 30 seconds. + System.out.println( + "No incoming client connection in 30 seconds. " + + "Ignore in server side."); + return; + } finally { + sslServerSocket.close(); + } + + // handle the connection + try { + // Is it the expected client connection? + // + // Naughty test cases or third party routines may try to + // connection to this server port unintentionally. In + // order to mitigate the impact of unexpected client + // connections and avoid intermittent failure, it should + // be checked that the accepted connection is really linked + // to the expected client. + boolean clientIsReady = + clientCondition.await(30L, TimeUnit.SECONDS); + + if (clientIsReady) { + // Run the application in server side. + runServerApplication(sslSocket); + } else { // Otherwise, ignore + // We don't actually care about plain socket connections + // for TLS communication testing generally. Just ignore + // the test if the accepted connection is not linked to + // the expected client or the client connection timeout + // in 30 seconds. + System.out.println( + "The client is not the expected one or timeout. " + + "Ignore in server side."); + } + } finally { + sslSocket.close(); + } + } + + // Define the server side application of the test for the specified socket. + protected void runServerApplication(SSLSocket socket) throws Exception { + // here comes the test logic + InputStream sslIS = socket.getInputStream(); + OutputStream sslOS = socket.getOutputStream(); + + sslIS.read(); + sslOS.write(85); + sslOS.flush(); + } + + protected void doClientSide() throws Exception { + // Wait for server to get started. + // + // The server side takes care of the issue if the server cannot + // get started in 90 seconds. The client side would just ignore + // the test case if the serer is not ready. + boolean serverIsReady = + serverCondition.await(90L, TimeUnit.SECONDS); + if (!serverIsReady) { + System.out.println( + "The server is not ready yet in 90 seconds. " + + "Ignore in client side."); + return; + } + + SSLContext context = SSLExampleCert.createClientSSLContext(); + SSLSocketFactory sslsf = context.getSocketFactory(); + + try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket( + "www.example.com.", serverPort)) { + // OK, here the client and server get connected. + SSLParameters sslParameters = sslSocket.getSSLParameters(); + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslSocket.setSSLParameters(sslParameters); + + // Signal the server, the client is ready to communicate. + clientCondition.countDown(); + + // There is still a chance in theory that the server thread may + // wait client-ready timeout and then quit. The chance should + // be really rare so we don't consider it until it becomes a + // real problem. + + // Run the application in client side. + runClientApplication(sslSocket); + } + } + + // Define the client side application of the test for the specified socket. + protected void runClientApplication(SSLSocket socket) throws Exception { + InputStream sslIS = socket.getInputStream(); + OutputStream sslOS = socket.getOutputStream(); + + sslOS.write(280); + sslOS.flush(); + sslIS.read(); + } +} + diff --git a/test/jdk/javax/net/ssl/TLS/TestJSSE.java b/test/jdk/javax/net/ssl/TLS/TestJSSE.java index 2c5a2c6274d9d38079fa4d065a2ddf8c3dc145f8..29631064011df583680f1511a8314dd1c6d155eb 100644 --- a/test/jdk/javax/net/ssl/TLS/TestJSSE.java +++ b/test/jdk/javax/net/ssl/TLS/TestJSSE.java @@ -21,12 +21,13 @@ * questions. */ +import java.net.InetAddress; import java.security.Provider; import java.security.Security; public class TestJSSE { - private static final String LOCAL_IP = "127.0.0.1"; + private static final String LOCAL_IP = InetAddress.getLoopbackAddress().getHostAddress(); public static void main(String... args) throws Exception { // reset the security property to make sure that the algorithms diff --git a/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java b/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java index 2207749302d909dfb53f44af6ad43e4f37b598fd..21416f0aaef21dcf0a2f16cf34314e6df5900bd5 100644 --- a/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java +++ b/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.io.OutputStream; +import java.net.InetAddress; import java.security.cert.Certificate; import javax.net.ssl.KeyManager; @@ -52,7 +53,8 @@ class JSSEClient extends CipherTest.Client { new TrustManager[] { CipherTest.trustManager }, CipherTest.secureRandom); SSLSocketFactory factory = (SSLSocketFactory)sslContext.getSocketFactory(); - socket = (SSLSocket)factory.createSocket("127.0.0.1", CipherTest.serverPort); + socket = (SSLSocket)factory.createSocket( + InetAddress.getLoopbackAddress().getHostAddress(), CipherTest.serverPort); socket.setSoTimeout(CipherTest.TIMEOUT); socket.setEnabledCipherSuites(new String[] { params.cipherSuite.name() }); socket.setEnabledProtocols(new String[] { params.protocol.name }); diff --git a/test/jdk/javax/net/ssl/templates/SSLExampleCert.java b/test/jdk/javax/net/ssl/templates/SSLExampleCert.java new file mode 100644 index 0000000000000000000000000000000000000000..bc8a1fdb2e9046896f493121635d47db45a77cd8 --- /dev/null +++ b/test/jdk/javax/net/ssl/templates/SSLExampleCert.java @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.*; +import java.net.InetAddress; +import java.security.KeyFactory; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; + +// A template to use "www.example.com" as the server name. The caller should +// set a virtual hosts file with System Property, "jdk.net.hosts.file". This +// class will map the loopback address to "www.example.com", and write to +// the specified hosts file. +public enum SSLExampleCert { + // Version: 3 (0x2) + // Serial Number: 15223159159760931473 (0xd34386999cc8ca91) + // Signature Algorithm: sha256WithRSAEncryption + // Issuer: C=US, ST=California, O=Example, OU=Test + // Validity + // Not Before: Jan 26 04:50:29 2022 GMT + // Not After : Feb 25 04:50:29 2022 GMT + // Subject: C=US, ST=California, O=Example, OU=Test + // Public Key Algorithm: rsaEncryption + CA_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDXDCCAkSgAwIBAgIJANNDhpmcyMqRMA0GCSqGSIb3DQEBCwUAMEMxCzAJBgNV + BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRAwDgYDVQQKDAdFeGFtcGxlMQ0w + CwYDVQQLDARUZXN0MB4XDTIyMDEyNjA0NTAyOVoXDTIyMDIyNTA0NTAyOVowQzEL + MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNVBAoMB0V4YW1w + bGUxDTALBgNVBAsMBFRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB + AQDnOL2hB/GYyYziXo/ppxi7V1LfMMLeHt0lZbYlrmNxUlln4naI4B4Lkg75eb1Y + DgC7MZQd5nKijK9Dkq52Z2zLxaqBYnLxKJ36qKPqbtTL3I8mfUvVEeNIDN/8YTAt + suIEQi54dNtQVrB4YReMdnUq+xCKLAfEio4QLEQr7KtyCBXHZpM7RYRT0giQFvDU + 2kls9lFLeqKXgocnA7VpoL0V12hpxDeJoRm1szf0M5YXGJumQLaE5qM/+P2OOhw/ + T+xkupy2GF02s6FBXkH7NrFIjtuBSaVhSvCG/N7njWSn339thr3kiPEaCS4KSH5E + E6FEazxZQrTCbkQQ+v3y1pS1AgMBAAGjUzBRMA8GA1UdEwEB/wQFMAMBAf8wHQYD + VR0OBBYEFMFw2FWUvwZx3FJjm1G9TujCjAJSMB8GA1UdIwQYMBaAFMFw2FWUvwZx + 3FJjm1G9TujCjAJSMA0GCSqGSIb3DQEBCwUAA4IBAQCJsJjeYcT/GtKp64C+9KCi + Vgw/WnBZwbosSFZmqyID8aAnAxaGMkZ2B2pUZHTtCkBf6d9c0tuWb5yF8npV77sE + bZqeNg2GU7EvH3WPgPbQVT7+Qb+WbY3EEPgJHLytch61Rm/TRQ3OqD0B+Gs7YjAU + fEspmk1JJ6DWuXX13SHoGWgVnO7rXBnCJaGnGpONtggG4oO5hrwnMzQZKh5eZDhC + 7tkNPqVDoLv+QqnFk8q6k8hhxnVf+aw56IdsebN+9Bi+Lv6OQ+stKUo/u/RTW2z1 + odCOwc8DPF3jbacJsOmLhl3ciuWGOckx9KCvaBeTTgkPdLQH1gpNha2tnqgxUXmC + -----END CERTIFICATE-----""", + + """ + MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnOL2hB/GYyYzi + Xo/ppxi7V1LfMMLeHt0lZbYlrmNxUlln4naI4B4Lkg75eb1YDgC7MZQd5nKijK9D + kq52Z2zLxaqBYnLxKJ36qKPqbtTL3I8mfUvVEeNIDN/8YTAtsuIEQi54dNtQVrB4 + YReMdnUq+xCKLAfEio4QLEQr7KtyCBXHZpM7RYRT0giQFvDU2kls9lFLeqKXgocn + A7VpoL0V12hpxDeJoRm1szf0M5YXGJumQLaE5qM/+P2OOhw/T+xkupy2GF02s6FB + XkH7NrFIjtuBSaVhSvCG/N7njWSn339thr3kiPEaCS4KSH5EE6FEazxZQrTCbkQQ + +v3y1pS1AgMBAAECggEBAJQAKLkTWZx/njMjbiCT+Wuo6H2+O21r+ge/BAk4h6R4 + nou1VEQmmHS1h+o992mOhP9NK867vDK5tFGfaRaW+vevzYTF3GbqpbxVB56+VG0s + /2AWoVx/96gdvZ1RJEKMFsm9BvvJaLwS0SAsnaMmC7d4Ps0Cg/JU8bv+aaBn/BGf + TWiofYWeUk6llco4kO9H2APxUVzlaUUU/cPAJqX7XktnhDCI9/esuVg7nVR0XxOF + GDrV/jdqSYmSbp4aTRXgI9nwxOmlKiGgevTrCUXl3/KaJxZekllVjushY1VVzgbY + K5R4bcN5MXMmFdgF9DTEW72RqEfg9iXqyhYbZp3Q/UECgYEA/yiaJd0w2HS22HSg + o4dJ072WbyR3qUqQmPbSUn9hBQTJAz1eX3cci8u4oawo/S+jN38b/DfpSg3eIMLB + vnXW3wZtodpJnFaweKd3yUaSF2r9vZRHJgfPfe67VbruEOF6BsCjTq/deGeNnGeH + /IDVn9WtSeRX/bv/s5YHvGaHGGUCgYEA5/vugmilOBq979EqksCG/7EQHSOoEukO + J/aunDyEwz+BMEHOEW7tDMUefdiSfnGXSW+ZTmpmvc+aLk37Xuo34jpugK5ayUFY + iYVgiqdnygGiBevBM2o0O/parQkAGEB8GPButrYItUzubUgXnuw+EdMiXGnpjJaK + S3dPYJEHvhECgYEAjqIIwV/LPUTJLWjMn30yBN43KLvu9ECNYiSfX6R6/I43O8tj + ZOQ1nePsutt9MkMd7xjr8OrkSxRDdnbITQqcaaGzSUW33mALV/btnCMJ6XNSklZA + C39UOuZn7D2JdQBF8V5gK81ddUAVxjeNqdXvFOEidGrj0R/1iVM10dhSbo0CgYBk + P8GtR02Gtj+4P/qW2m48VqbxALSkH2SHrpl8WMbCnVHVqcpETFxSNWjc11dPHwVS + rdBhS6fEhM9LDVYAiVTHBZs1LqN67ys0mpfCs18ts5Dx4BRohI+4D5NZzVbmJA+8 + s0IU4QtYVbt/LDVQ7yRPjZ7+sqJDp9ZxkEiUIXhoEQKBgQCPG2f8BhsCYNAOV60F + hJVjhDdf59Mia3B2J9SSnrg6Tl2rWB7GPP19TiSPFS6Sn95mWrMjZ2ZuOXtCYV4H + +hmu87AV2CXFhW5c588cajXMT92GFVMSXdE1OHRzDjhpH+/ll8SnmQa7sXmEV36+ + sawd7mwcB9IEi562wglADxBUCA== + """), + + // Version: 3 (0x2) + // Serial Number: 14845986384898254166 (0xce0789f5ac256556) + // Signature Algorithm: sha1WithRSAEncryption + // Issuer: C=US, ST=California, O=Example, OU=Test + // Validity + // Not Before: Jan 26 04:50:29 2022 GMT + // Not After : Feb 25 04:50:29 2022 GMT + // Subject: C=US, ST=California, O=Example, OU=Test, CN=www.example.com + // Public Key Algorithm: rsaEncryption + SERVER_EXAMPLE_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDjDCCAnSgAwIBAgIJAM4HifWsJWVWMA0GCSqGSIb3DQEBBQUAMEMxCzAJBgNV + BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRAwDgYDVQQKDAdFeGFtcGxlMQ0w + CwYDVQQLDARUZXN0MB4XDTIyMDEyNjA0NTAyOVoXDTIyMDIyNTA0NTAyOVowXTEL + MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNVBAoMB0V4YW1w + bGUxDTALBgNVBAsMBFRlc3QxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIw + DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK/i4bVSAF6/aFHyzrFAON8Uwn2a + Q9jFoAMowUkH6+PCexlt4wCOEMVH9IQPa1yzeVlkYRqHggz3i6aVYvd27Q+c6vOF + FuRegWdJusyEuoXd5nwxSGiZZMLmFQswODSPmucroCG+Tq9RKY5oEKiRP8tUDqyn + eE52PaeSR2Q6mng7BM5Llj7amVgimO3jlH2AWLLpHNTkc3j/M1QrLFV2PqN4dpxT + OeFuVWzpfTWJSH+9Kq4u/zBMbYl8ON7DSgJAzc2BOw8VPIYIK6JIw6IDbLn4dIQf + GikdgHKB2K6EDOc9LuX6UqQQODDFU88muAyPgpGfUQjxKZeUoTqoAFyisI0CAwEA + AaNpMGcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUQqf/4nqluVMZ8huD3I5FNqLXTqAw + HwYDVR0jBBgwFoAUwXDYVZS/BnHcUmObUb1O6MKMAlIwGgYDVR0RBBMwEYIPd3d3 + LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQBl8FJD98fJh/0KY+3LtZDW + CQZDeBSfnpq4milrvHH+gcOCaKYlB9702tAQ6rL1c1dLz/Lpw1x7EYvO8XIwXMRc + DZghf8EJ6wMpZbLVLAQLCTggiB65XPwmhUoMvgVRVLYoXT3ozmNPt7P+ZURisqem + 0/xVVfxqmHw9Hb4DNlc7oZDgOK7IrqriaBK6Amsu3m2eThsvkwTdJfeFG3ZdV6x5 + mbaGZDMt/wgWIqyq5CZNpXPaFRH7KM4zhcoqXvFAoq9jxWOuBkJUUx5EHaxGhhPw + SMgE1yl4O+N7GJmF/WMR5zp2LGKMqJ3vwLPv6QNkUmLwB5ZLYJ8E2dpj6DjQWa7X + -----END CERTIFICATE-----""", + + """ + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv4uG1UgBev2hR + 8s6xQDjfFMJ9mkPYxaADKMFJB+vjwnsZbeMAjhDFR/SED2tcs3lZZGEah4IM94um + lWL3du0PnOrzhRbkXoFnSbrMhLqF3eZ8MUhomWTC5hULMDg0j5rnK6Ahvk6vUSmO + aBCokT/LVA6sp3hOdj2nkkdkOpp4OwTOS5Y+2plYIpjt45R9gFiy6RzU5HN4/zNU + KyxVdj6jeHacUznhblVs6X01iUh/vSquLv8wTG2JfDjew0oCQM3NgTsPFTyGCCui + SMOiA2y5+HSEHxopHYBygdiuhAznPS7l+lKkEDgwxVPPJrgMj4KRn1EI8SmXlKE6 + qABcorCNAgMBAAECggEBAJb2SvfP7BVmf+lmV9V249lE/jHECFu0M8TCZDOEowiX + 0gRfdqjxRp+tRMdcXK/yM0Nwjo+wowTyK2DNc2YnIw11h4uAPcfA/ZxjgfssKNPh + Q4Rw4E826W8HACTcPEGQyEmF/ik4KFz9coeR9kpYcMLZ4MZ77xyZDA4Z1UDHs/Fg + egrd4k35fxIFOavsjNuekMIjZlyQ2xU1a11QDBrZAu/pjITXXulg4jCxLbeNOOPs + hH+Sx+jnsVV7qIBNwulzxEdpb3+NkWIMmOQK4HOSeHgjRVvSXXBPgYadMaP/Bzvx + AwJ9WeLZg7KWHE03aOc7CSMoyHfmhXx3gD8icGpSq8ECgYEA3TWGBSgny/wket+V + 65ldWjp4NOKHbLPtBdL9ygIO+1bGfLl5srCxUWHBYdcWCXKuB5ALCBu0hMY+TlwF + s/BzZmvVW7RLAEZZ3Q5HpawDlr9j8Kenm4X2Mqh0MSkmwIDRDHF8jRXAvWIzcBiS + +rPZm2CMZpznUSE4X+GrvTSCBbkCgYEAy4yJ58wNUavj/tR8KySn5ygPABFZ1Uoy + pIyabm18Oe3gCl5UulBskoN0WreTKnA4r9jGlnrgeuu5WfMK53AZKbC+YduZixW4 + QFuJBSMbFCBDt4nkhkMMR7VcV4jIqaOK7qNrs7ubGTZhsG8wj6/WWdCp3Avnx1rS + WCCoYNhAK3UCgYADaLnCBpZmbGJbimqTEPABXflQR1Vy9WrnthK3NETq1rGEZo9b + k6GH8Yu7aEcsqhnIgA3LeDHWAgAf0Qc9eK0unObS3Ppy7KKh54BvKzF690QhB1Rr + 7yqWKUZxI4M3YETYfj8/JWCtCoBkb9yEBJWL8Xb4dd6Sv4JQ5/dvmQmP8QKBgBX+ + 5+Aeksnik060U36uBV7bW1OcjGKaFALoFsAcILJ53B4Ct5Eyo6jpf6dV8xdA7T9D + Y6JbQOrHkk4AD4uW94Ej0k7s1hjLjg+WVKYzdvejzO2GfyVrFWaiWIo1A8ohHCBR + lI/llAsTb1cLjOnaDIXEILbgqnlGfTh8vvVIKRcJAoGALF6Q1Ca2GIx4kJZ2/Az5 + qx89q95wQoWVHcJCA91g/GKg/bD0ZJMWEhhVH3QcnDOU7afRGKOPGdSSBdPQnspQ + 1OPpPjA3U5Mffy5PJ2bHTpPBeeHOzDO4Jt073zK3N81QovJzS8COoOwuGdcocURH + mFMnEtK7d+EK1C1NTWDyNzU= + """), + + + // Version: 3 (0x2) + // Serial Number: 14845986384898254167 (0xce0789f5ac256557) + // Signature Algorithm: sha1WithRSAEncryption + // Issuer: C=US, ST=California, O=Example, OU=Test + // Validity + // Not Before: Jan 26 04:50:29 2022 GMT + // Not After : Feb 25 04:50:29 2022 GMT + // Subject: C=US, ST=California, O=Example, OU=Test, CN=Do-Not-Reply + // Public Key Algorithm: rsaEncryption + CLIENT_EXAMPLE_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDkjCCAnqgAwIBAgIJAM4HifWsJWVXMA0GCSqGSIb3DQEBBQUAMEMxCzAJBgNV + BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRAwDgYDVQQKDAdFeGFtcGxlMQ0w + CwYDVQQLDARUZXN0MB4XDTIyMDEyNjA0NTAyOVoXDTIyMDIyNTA0NTAyOVowWjEL + MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNVBAoMB0V4YW1w + bGUxDTALBgNVBAsMBFRlc3QxFTATBgNVBAMMDERvLU5vdC1SZXBseTCCASIwDQYJ + KoZIhvcNAQEBBQADggEPADCCAQoCggEBAODbsCteHcAg3dktUO5fiPTytIahKZMg + U2h6h0+BT803tYcdN6WDHnLNlU/3iFnBMpyTwzWhYIftC9c/TIkXBAGfWl4HHQgc + x08NHPms0E+GF6CDthvHERSvRCBrIyVna0KIZPemBzUfeBeNdiqwsLvg+C5dqWu5 + YcILvL6GzTMvdMwJeEX+c2ZYHibqd8aZydWsT+IPVZnueDX6KTOnYvexLFIoid2a + 62FavnMWiPKnICertDDg+gHlN2XceW3tlYQwO+HMig4DH3u2x0SApOoM3y8k29Ew + Fn6wquSRomcbDiI8SEOeaBFenu6W0g24iaxIZfqEM52kPbQFdzqg+O0CAwEAAaNy + MHAwCQYDVR0TBAIwADAdBgNVHQ4EFgQU0t+I5iAfPq6C/I2CSvTKHGK6+2kwHwYD + VR0jBBgwFoAUwXDYVZS/BnHcUmObUb1O6MKMAlIwIwYDVR0RBBwwGoEYZG8tbm90 + LXJlcGx5QGV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQBqWk35XXpb3L+N + 7kPlNmSlhfamenVOVYxPBq/tSFpl728CV0OrGAy79awEFDvzhpbBg9Mz7HS/a7ax + f+lBbsAt1maWlsVSsaaJrmy3znl9CZiIg+ykZ5ZzLS5FkIbQ6LkzvxYZJ1JYCzXm + P/5+rbQyIvQaDGL23PmE7AB2Q0q+imt4b9HKs+SnI4XERyj8OF/kseRtILtP2ltV + r+3XgcBxwyU17CLwsHrjnQ8/1eGovBKzGAfUXeHBdzOuD3ZemjnqwlzQTf2TAkBP + OuMc8gr2Umc5tMtdiRUFPODO7DG7vB7LKEsJGKWLUtGbR+3S55lIcCF5NFZ//TNZ + 4x2GPOJ+ + -----END CERTIFICATE-----""", + + """ + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDg27ArXh3AIN3Z + LVDuX4j08rSGoSmTIFNoeodPgU/NN7WHHTelgx5yzZVP94hZwTKck8M1oWCH7QvX + P0yJFwQBn1peBx0IHMdPDRz5rNBPhhegg7YbxxEUr0QgayMlZ2tCiGT3pgc1H3gX + jXYqsLC74PguXalruWHCC7y+hs0zL3TMCXhF/nNmWB4m6nfGmcnVrE/iD1WZ7ng1 + +ikzp2L3sSxSKIndmuthWr5zFojypyAnq7Qw4PoB5Tdl3Hlt7ZWEMDvhzIoOAx97 + tsdEgKTqDN8vJNvRMBZ+sKrkkaJnGw4iPEhDnmgRXp7ultINuImsSGX6hDOdpD20 + BXc6oPjtAgMBAAECggEAKjqX900RoUeK4oKUNHBUtEvwg2g4+pyTjYeVaeULK6tO + uDVQghEB4uWhKQd/3/tcmfNWMfhAvMZT9vS4Vvavle5rdkU3upJNDBeWXX2LEaRJ + Q6f4x3a3Sn8v+DamvxuRFUmwTKItsFhcoW+7xYCxcFdrxKlqbATAy0SRCecfGoFw + 9pAsFIgIqLGQtV9V9fZWKdXIfLkH3venNImHt0n5pYadl4kZu0gNCmOGRO1MqB51 + bdAck3dBg22TE5+sZBIZmCjBAEbrc2RUQu5mAoDs8eeenxBlFYszWZxqM8BkJL5e + SqQkbc18E8Gzdx52xEx6BCLTq0MITKliKX4B2tsQsQKBgQD1DIvt13yg9LlyoiAb + Fc1zzKZQBPRgDUJCGzCPeC6AqbPUjoxvFAHxGNgmJXqAXwsqcs88qlSGAjk6ANAx + fHWUQ3UmkZjGvV0ru3rIPcXvS7isjzm/cbq1YZua6+ohFl4+hojc/iyUrOaCd9uY + V2zwrr+A0JJrlev72niEuAtEmwKBgQDq6CaLP79dHqAOIV43+SyX7KdwNkMMWIR7 + El6E/74V0IWOYWFXLmV4sX6BKi0ZBTFZ3wKwMTDqQBYD2/a7gq43HjzuWu+2dFhA + pCQumMOKNqcNS9NldqoxAiGLxC+JMhGGyf3RO0Ey9gdPnQuje3133Wce8WWaHHv2 + lD5BcmzdFwKBgQCCeca7wiPy07s2ZUqxAT/eq5XWP30a85RW/IEzsusXyMQepjPy + JPYPuInGbeg3F+QrGuxrQco1fFOaJbq0zq8QXYawHY/6KfPFCFMM8Y9FpczT3IME + A3tFfo5Kw9hq+6z8n8eZ26BDHXiy+Tysdchksrb20JdVv4LiG+ZVzGT7hwKBgG+b + Bp0IF4JFh6PPBLWxRBeWT2MH1Mkr0R2r945W91fj72BbMeU63Oj/42u4vx5xEiZx + xxQw+t2AvzTsMAicqOr1CdvxBoz4L+neUnZ1DApBtxKhIPnG7EtGiOuftToIuL0C + gP4EmhB9RbH0mk/83vqxDUptRGl4+QiJHB76H3DXAoGASGT6tfs1/92rGqe0COm3 + aHpelvW7Wwr9AuBumE7/ur/JWAAiM4pm6w7m5H5duYZtG3eWz1s+jvjy8jIPBIkN + RA2DoneC2J/tsRRNFBqZrOWon5Jv4dc9R79qR13B/Oqu8H6FYSB2oDyh67Csud3q + PRrz4o7UKM+HQ/obr1rUYqM= + """); + + final String keyAlgo; + final String certStr; + final String privateKeyStr; + + // Trusted certificate + private final static SSLExampleCert[] TRUSTED_CERTS = { + SSLExampleCert.CA_RSA + }; + + // Server certificate. + private final static SSLExampleCert[] SERVER_CERTS = { + SSLExampleCert.SERVER_EXAMPLE_RSA + }; + + // Client certificate. + private final static SSLExampleCert[] CLIENT_CERTS = { + SSLExampleCert.CLIENT_EXAMPLE_RSA + }; + + // Set "www.example.com" to loopback address. + static { + String hostsFileName = System.getProperty("jdk.net.hosts.file"); + String loopbackHostname = + InetAddress.getLoopbackAddress().getHostAddress() + + " " + "www.example.com www.example.com.\n"; + try (FileWriter writer= new FileWriter(hostsFileName, false)) { + writer.write(loopbackHostname); + } catch (IOException ioe) { + // ignore + } + } + + SSLExampleCert(String keyAlgo, String certStr, String privateKeyStr) { + this.keyAlgo = keyAlgo; + this.certStr = certStr; + this.privateKeyStr = privateKeyStr; + } + + public static SSLContext createClientSSLContext() throws Exception { + return createSSLContext(TRUSTED_CERTS, CLIENT_CERTS); + } + + public static SSLContext createServerSSLContext() throws Exception { + return createSSLContext(TRUSTED_CERTS, SERVER_CERTS); + } + + private static SSLContext createSSLContext( + SSLExampleCert[] trustedCerts, + SSLExampleCert[] endEntityCerts) throws Exception { + char[] passphrase = "passphrase".toCharArray(); + + // Generate certificate from cert string. + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + // Import the trusted certs. + KeyStore ts = null; // trust store + if (trustedCerts != null && trustedCerts.length != 0) { + ts = KeyStore.getInstance("PKCS12"); + ts.load(null, null); + + Certificate[] trustedCert = new Certificate[trustedCerts.length]; + for (int i = 0; i < trustedCerts.length; i++) { + try (ByteArrayInputStream is = new ByteArrayInputStream( + trustedCerts[i].certStr.getBytes())) { + trustedCert[i] = cf.generateCertificate(is); + } + + ts.setCertificateEntry("trusted-cert-" + + trustedCerts[i].name(), trustedCert[i]); + } + } + + // Import the key materials. + KeyStore ks = null; // trust store + if (endEntityCerts != null && endEntityCerts.length != 0) { + ks = KeyStore.getInstance("PKCS12"); + ks.load(null, null); + + for (SSLExampleCert endEntityCert : endEntityCerts) { + // generate the private key. + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder() + .decode(endEntityCert.privateKeyStr)); + KeyFactory kf = + KeyFactory.getInstance( + endEntityCert.keyAlgo); + PrivateKey priKey = kf.generatePrivate(priKeySpec); + + // generate certificate chain + Certificate keyCert; + try (ByteArrayInputStream is = new ByteArrayInputStream( + endEntityCert.certStr.getBytes())) { + keyCert = cf.generateCertificate(is); + } + + Certificate[] chain = new Certificate[]{keyCert}; + + // import the key entry. + ks.setKeyEntry("end-entity-cert-" + + endEntityCert.name(), + priKey, passphrase, chain); + } + } + + // Create an SSLContext object. + TrustManagerFactory tmf = + TrustManagerFactory.getInstance("PKIX"); + tmf.init(ts); + + SSLContext context = SSLContext.getInstance("TLS"); + if (endEntityCerts != null && endEntityCerts.length != 0) { + KeyManagerFactory kmf = + KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, passphrase); + + context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + } else { + context.init(null, tmf.getTrustManagers(), null); + } + + return context; + } +} diff --git a/test/jdk/javax/print/PrintServiceLookup/FlushCustomClassLoader.java b/test/jdk/javax/print/PrintServiceLookup/FlushCustomClassLoader.java index 6e0a25a69d0a56beb09b5edb5186f50475b1e29f..4ec95fb75354e0e83651a5ec089e90d67e0be58b 100644 --- a/test/jdk/javax/print/PrintServiceLookup/FlushCustomClassLoader.java +++ b/test/jdk/javax/print/PrintServiceLookup/FlushCustomClassLoader.java @@ -34,6 +34,9 @@ import javax.print.PrintServiceLookup; * @test * @bug 8273831 * @summary Tests custom class loader cleanup + * @library /javax/swing/regtesthelpers + * @build Util + * @run main/timeout=60/othervm -mx32m FlushCustomClassLoader */ public final class FlushCustomClassLoader { @@ -42,12 +45,8 @@ public final class FlushCustomClassLoader { int attempt = 0; while (loader.get() != null) { - if (++attempt > 10) { - throw new RuntimeException("Too many attempts: " + attempt); - } - System.gc(); - Thread.sleep(1000); - System.out.println("Not freed, attempt: " + attempt); + Util.generateOOME(); + System.out.println("Not freed, attempt: " + attempt++); } } diff --git a/test/jdk/javax/print/attribute/StreamServiceAttributeTest.java b/test/jdk/javax/print/attribute/StreamServiceAttributeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..093bbfd747cb0333f5f8b9376c17772eb0b55ca2 --- /dev/null +++ b/test/jdk/javax/print/attribute/StreamServiceAttributeTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 4884570 + * @summary Attribute support reporting should be consistent +*/ + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +import javax.print.DocFlavor; +import javax.print.StreamPrintService; +import javax.print.StreamPrintServiceFactory; +import javax.print.attribute.Attribute; +import javax.print.attribute.standard.Chromaticity; +import javax.print.attribute.standard.Media; +import javax.print.attribute.standard.OrientationRequested; +import javax.print.attribute.standard.SheetCollate; +import javax.print.attribute.standard.Sides; + +public class StreamServiceAttributeTest { + + private static boolean allSupported = true; + private static Class[] attrClasses = { + Chromaticity.class, + Media.class, + OrientationRequested.class, + SheetCollate.class, + Sides.class, + }; + + public static void main(String args[]) { + + StreamPrintServiceFactory[] fact = + StreamPrintServiceFactory.lookupStreamPrintServiceFactories( + null, null); + + if (fact.length == 0) { + return; + } + OutputStream out = new ByteArrayOutputStream(); + StreamPrintService sps = fact[0].getPrintService(out); + for (Class<? extends Attribute> ac : attrClasses) { + test(sps, ac); + } + + if (!allSupported) { + throw new RuntimeException("Inconsistent support reported"); + } + } + + private static void test(StreamPrintService sps, + Class<? extends Attribute> ac) { + if (!sps.isAttributeCategorySupported(ac)) { + return; + } + DocFlavor[] dfs = sps.getSupportedDocFlavors(); + for (DocFlavor f : dfs) { + Attribute[] attrs = (Attribute[]) + sps.getSupportedAttributeValues(ac, f, null); + if (attrs == null) { + continue; + } + for (Attribute a : attrs) { + if (!sps.isAttributeValueSupported(a, f, null)) { + allSupported = false; + System.out.println("Unsupported : " + f + " " + a); + } + } + } + } +} diff --git a/test/jdk/javax/sound/sampled/Clip/DataPusherThreadCheck.java b/test/jdk/javax/sound/sampled/Clip/DataPusherThreadCheck.java new file mode 100644 index 0000000000000000000000000000000000000000..733a317ab37cebeac6ab265310e5295997a476b6 --- /dev/null +++ b/test/jdk/javax/sound/sampled/Clip/DataPusherThreadCheck.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED; +import static javax.sound.sampled.AudioSystem.NOT_SPECIFIED; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import java.applet.AudioClip; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; + +/* + * @test + * @key headful + * @bug 8279673 + * @summary Verify no NPE creating threads + * @run main/othervm DataPusherThreadCheck + */ +public class DataPusherThreadCheck { + + public static void main(String[] args) throws Exception { + // Prepare the audio file + File file = new File("audio.wav"); + try { + AudioFormat format = + new AudioFormat(PCM_SIGNED, 44100, 8, 1, 1, 44100, false); + int dataSize = 6000*1000 * format.getFrameSize(); + InputStream in = new ByteArrayInputStream(new byte[dataSize]); + AudioInputStream audioStream = new AudioInputStream(in, format, NOT_SPECIFIED); + AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, file); + } catch (Exception ignored) { + return; // the test is not applicable + } + try { + checkThread(file); + } finally { + Files.delete(file.toPath()); + } + } + + private static void checkThread(File file) throws Exception { + AudioClip clip = (AudioClip) file.toURL().getContent(); + clip.loop(); + try { + Thread.sleep(2000); + } catch (InterruptedException ignored) { + } + boolean found = isDataPushedThreadExist(); + clip.stop(); + if (!found) { + throw new RuntimeException("Thread 'DataPusher' isn't found"); + } + } + + private static boolean isDataPushedThreadExist() { + for (Thread t : Thread.getAllStackTraces().keySet()) { + if (t.getName().equals("DataPusher")) { + return true; + } + } + return false; + } + +} diff --git a/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java b/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java index b63973229a209642cbe8fa5fa5833614afe5caa4..c93715d8087a8642988c6e17be08c158809a438e 100644 --- a/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java +++ b/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ import javax.swing.JCheckBox; /* * @test * @key headful - * @bug 8216358 + * @bug 8216358 8279586 * @summary [macos] The focus is invisible when tab to "Image Radio Buttons" and "Image CheckBoxes" * @library ../../regtesthelpers/ * @build Util @@ -51,8 +51,12 @@ public class ImageCheckboxTest { BufferedImage.TYPE_INT_ARGB); BufferedImage imageFocus = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB); + BufferedImage imageFocusNotPainted = new BufferedImage(100, 50, + BufferedImage.TYPE_INT_ARGB); + CustomCheckBox checkbox = new CustomCheckBox("Test", new MyIcon(Color.GREEN)); + checkbox.setFocusPainted(true); checkbox.setSize(100, 50); checkbox.setFocused(false); checkbox.paint(imageNoFocus.createGraphics()); @@ -64,6 +68,17 @@ public class ImageCheckboxTest { ImageIO.write(imageNoFocus, "png", new File("imageNoFocus.png")); throw new Exception("Changing focus is not visualized"); } + + checkbox.setFocusPainted(false); + checkbox.paint(imageFocusNotPainted.createGraphics()); + + if (!Util.compareBufferedImages(imageFocusNotPainted, imageNoFocus)) { + ImageIO.write(imageFocusNotPainted, "png", + new File("imageFocusNotPainted.png")); + ImageIO.write(imageFocus, "png", new File("imageFocus.png")); + ImageIO.write(imageNoFocus, "png", new File("imageNoFocus.png")); + throw new Exception("setFocusPainted(false) is ignored"); + } } class MyIcon implements Icon { diff --git a/test/jdk/javax/swing/JFileChooser/8277463/UNCFileChooserTest.java b/test/jdk/javax/swing/JFileChooser/8277463/UNCFileChooserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..738b5da762edada9faa13f6774b6c60a86c99ca7 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/8277463/UNCFileChooserTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277463 + @requires (os.family == "windows") + @summary JFileChooser with Metal L&F doesn't show non-canonical UNC path in - Look in + @run main/manual UNCFileChooserTest +*/ + +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.WindowConstants; +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class UNCFileChooserTest { + private static volatile CountDownLatch countDownLatch; + private static JFrame instructionFrame; + private static JFrame testFrame; + private static volatile boolean testPassed = false; + + private static boolean validatePlatform() { + String osName = System.getProperty("os.name"); + if (osName == null) { + throw new RuntimeException("Name of the current OS could not be" + + " retrieved."); + } + return osName.startsWith("Windows"); + } + + private static void createInstructionUI() throws Exception { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + String instructions = + "1. Enter the non-canonical UNC path of the directory to test\n" + + "example: \\\\pc-name\\dir\\..\n" + + "2. An \"Open File\" file chooser dialog pops up\n" + + "3. Check the \"Look in\" Combobox at the top for quickly changing directory is not empty\n" + + "4. Close the file chooser Dialog\n" + + "5. If the \"Look in\" Combobox is not empty then press PASS else press FAIL\n"; + instructionFrame = new JFrame("InstructionFrame"); + JTextArea textArea = new JTextArea(instructions); + textArea.setEditable(false); + final JButton passButton = new JButton("PASS"); + passButton.addActionListener((e) -> { + testPassed = true; + instructionFrame.dispose(); + countDownLatch.countDown(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.addActionListener((e) -> { + instructionFrame.dispose(); + countDownLatch.countDown(); + }); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + instructionFrame.setDefaultCloseOperation( + WindowConstants.DISPOSE_ON_CLOSE); + instructionFrame.setBounds(0,0,500,500); + instructionFrame.add(mainPanel); + instructionFrame.pack(); + instructionFrame.setVisible(true); + } + + private static void showOpenDialog() throws Exception { + String path = JOptionPane.showInputDialog(testFrame, "Enter the non-canonical UNC path of the directory to test.\nexample: \\\\pc-name\\dir\\.."); + if (path == null) { + throw new RuntimeException("Enter the directory path to test."); + } + new JFileChooser(path).showOpenDialog(null); + } + + public static void main(String[] args) throws Exception { + if (!validatePlatform()) { + System.out.println("This test is only for MS Windows OS."); + return; + } + countDownLatch = new CountDownLatch(1); + UNCFileChooserTest uncFileChooserTest = + new UNCFileChooserTest(); + + uncFileChooserTest.createInstructionUI(); + uncFileChooserTest.showOpenDialog(); + countDownLatch.await(15, TimeUnit.MINUTES); + + if(!testPassed) { + throw new RuntimeException("Test failed!"); + } + } +} diff --git a/test/jdk/javax/swing/JFileChooser/FileSystemView/ShellFolderStackOverflow.java b/test/jdk/javax/swing/JFileChooser/FileSystemView/ShellFolderStackOverflow.java new file mode 100644 index 0000000000000000000000000000000000000000..52bc51bd3f6d1242005ca456d64d76dcd6a39da3 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/FileSystemView/ShellFolderStackOverflow.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277299 + * @requires (os.family == "windows") + * @summary STACK_OVERFLOW in Java_sun_awt_shell_Win32ShellFolder2_getIconBits + * @run main/othervm -Xss320k ShellFolderStackOverflow + */ +import javax.swing.UIManager; + +public class ShellFolderStackOverflow { + public static void main(final String... args) throws Exception { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + // With default stack size for 32-bit VM next call will cause VM crash + UIManager.getIcon("Tree.openIcon"); + } +} diff --git a/test/jdk/javax/swing/JInternalFrame/8020708/bug8020708.java b/test/jdk/javax/swing/JInternalFrame/8020708/bug8020708.java index efd13ff768680e536696719131b35452787776d6..8f78178ada62ec971628c779396b84db6ea1c98b 100644 --- a/test/jdk/javax/swing/JInternalFrame/8020708/bug8020708.java +++ b/test/jdk/javax/swing/JInternalFrame/8020708/bug8020708.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ import javax.swing.UIManager; * @summary NLS: mnemonics missing in SwingSet2/JInternalFrame demo * @library ../../regtesthelpers * @build Util - * @run main bug8020708 + * @run main/timeout=300 bug8020708 */ public class bug8020708 { @@ -68,6 +68,7 @@ public class bug8020708 { public static void main(String[] args) throws Exception { for (Locale locale : SUPPORTED_LOCALES) { + System.out.println("locale: " + locale); for (String laf : LOOK_AND_FEELS) { Locale.setDefault(locale); if (!installLookAndFeel(laf)) { @@ -80,7 +81,7 @@ public class bug8020708 { static void testInternalFrameMnemonic(Locale locale) throws Exception { Robot robot = new Robot(); - robot.setAutoDelay(250); + robot.setAutoDelay(100); robot.setAutoWaitForIdle(true); SwingUtilities.invokeAndWait(new Runnable() { @@ -142,6 +143,7 @@ public class bug8020708 { UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels(); for (UIManager.LookAndFeelInfo info : infos) { if (info.getClassName().contains(lafName)) { + System.out.println("LookAndFeel: " + info.getClassName()); UIManager.setLookAndFeel(info.getClassName()); return true; } diff --git a/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java b/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java new file mode 100644 index 0000000000000000000000000000000000000000..cff2ea73c93164824b0db0e0979e3e1d70d3a5d8 --- /dev/null +++ b/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +/* + * @test + * @key headful + * @bug 8280913 + * @summary Check whether the default button is honored when <Enter> key is pressed. + * @run main DefaultButtonTest + */ +public class DefaultButtonTest { + private volatile boolean buttonPressed; + private JFrame frame; + + public static void main(String[] s) throws Exception { + DefaultButtonTest test = new DefaultButtonTest(); + test.runTest(); + } + + private static void setLookAndFeel(String lafName) { + try { + UIManager.setLookAndFeel(lafName); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Ignoring Unsupported L&F: " + lafName); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + + private void createUI() { + frame = new JFrame("Default Button Test"); + JPanel panel = new JPanel(); + panel.add(new JTextField("Text field")); + JButton button1 = new JButton("Default"); + button1.addActionListener(e -> buttonPressed = true); + panel.add(button1); + panel.add(new JButton("Button2")); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.getRootPane().setDefaultButton(button1); + frame.setVisible(true); + } + + public void runTest() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + try { + buttonPressed = false; + String lafName = laf.getClassName(); + System.out.println("Testing L&F: " + lafName); + SwingUtilities.invokeAndWait(() -> { + setLookAndFeel(lafName); + createUI(); + }); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.waitForIdle(); + + if (buttonPressed) { + System.out.println("Test Passed for L&F: " + lafName); + } else { + throw new RuntimeException("Test Failed, Default Button not pressed for L&F: " + lafName); + } + } finally { + SwingUtilities.invokeAndWait(this::disposeFrame); + } + } + } +} diff --git a/test/jdk/javax/swing/JTree/4908142/bug4908142.java b/test/jdk/javax/swing/JTree/4908142/bug4908142.java index 671af8abd2db5f4af0522edbc1068c03876aef77..784feda153d676a6083193ee5529bb90638ebb3f 100644 --- a/test/jdk/javax/swing/JTree/4908142/bug4908142.java +++ b/test/jdk/javax/swing/JTree/4908142/bug4908142.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,6 +60,7 @@ public class bug4908142 { }); robot.waitForIdle(); + robot.delay(1000); SwingUtilities.invokeAndWait(new Runnable() { @@ -70,12 +71,14 @@ public class bug4908142 { }); robot.waitForIdle(); - + robot.delay(500); robot.keyPress(KeyEvent.VK_A); robot.keyRelease(KeyEvent.VK_A); + robot.waitForIdle(); robot.keyPress(KeyEvent.VK_A); robot.keyRelease(KeyEvent.VK_A); + robot.waitForIdle(); robot.keyPress(KeyEvent.VK_D); robot.keyRelease(KeyEvent.VK_D); robot.waitForIdle(); @@ -114,6 +117,7 @@ public class bug4908142 { JScrollPane sp = new JScrollPane(tree); fr.getContentPane().add(sp); + fr.setLocationRelativeTo(null); fr.setSize(200, 200); fr.setVisible(true); } diff --git a/test/jdk/javax/xml/crypto/dsig/BadXPointer.java b/test/jdk/javax/xml/crypto/dsig/BadXPointer.java new file mode 100644 index 0000000000000000000000000000000000000000..ba985b6c568893e9bcdfc5728751efa535c6dc21 --- /dev/null +++ b/test/jdk/javax/xml/crypto/dsig/BadXPointer.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; +import jdk.test.lib.security.XMLUtils; + +import javax.xml.crypto.URIReferenceException; +import javax.xml.crypto.dsig.XMLSignatureException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.spec.ECGenParameterSpec; + +/** + * @test + * @bug 8278186 + * @summary reject malformed xpointer(id('a')) gracefully + * @library /test/lib + * @modules java.xml.crypto + */ +public class BadXPointer { + + public static void main(String[] args) throws Exception { + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC"); + kpg.initialize(new ECGenParameterSpec("secp256r1")); + KeyPair kp = kpg.generateKeyPair(); + + var signer = XMLUtils.signer(kp.getPrivate(), kp.getPublic()); + var doc = XMLUtils.string2doc("<root/>"); + + // No enclosing ' for id + Utils.runAndCheckException( + () -> signer.signEnveloping(doc, "a", "#xpointer(id('a))"), + ex -> Asserts.assertTrue(ex instanceof XMLSignatureException + && ex.getCause() instanceof URIReferenceException + && ex.getMessage().contains("Could not find a resolver"), + ex.toString())); + } +} diff --git a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java index db2140d223ef0bffc29d821fa1db26eb04a26cdb..df3e773388aa7d2781c0ede220eb4ba3fc169360 100644 --- a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java @@ -226,10 +226,10 @@ public class Byte128VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index) { - int i = 0; + static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3444,13 +3444,16 @@ public class Byte128VectorTests extends AbstractVectorTest { byte[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - av.withLane(0, (byte)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (byte)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (byte)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (byte)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(byte a) { return bits(a)==0; @@ -5512,7 +5515,7 @@ public class Byte128VectorTests extends AbstractVectorTest { static void maskFromToLongByte128VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5614,5 +5617,12 @@ public class Byte128VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueByte128VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java index b980f61df8c4e77218188b19b048b8881f834c36..85da0f82e811c38630de167d29655ddf613ecbb5 100644 --- a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java @@ -226,10 +226,10 @@ public class Byte256VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index) { - int i = 0; + static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3444,13 +3444,16 @@ public class Byte256VectorTests extends AbstractVectorTest { byte[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - av.withLane(0, (byte)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (byte)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (byte)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (byte)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(byte a) { return bits(a)==0; @@ -5512,7 +5515,7 @@ public class Byte256VectorTests extends AbstractVectorTest { static void maskFromToLongByte256VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5614,5 +5617,12 @@ public class Byte256VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueByte256VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java index 2ec4e8b2c539ec20c13edef959c1164406756337..d7659d868717ef83c74939c7a5b79cd3cf980312 100644 --- a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java @@ -24,7 +24,7 @@ /* * @test * @modules jdk.incubator.vector - * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Byte512VectorTests + * @run testng/othervm/timeout=240 -ea -esa -Xbatch -XX:-TieredCompilation Byte512VectorTests */ // -- This file was mechanically generated: Do not edit! -- // @@ -226,10 +226,10 @@ public class Byte512VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index) { - int i = 0; + static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3444,13 +3444,16 @@ public class Byte512VectorTests extends AbstractVectorTest { byte[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - av.withLane(0, (byte)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (byte)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (byte)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (byte)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(byte a) { return bits(a)==0; @@ -5512,7 +5515,7 @@ public class Byte512VectorTests extends AbstractVectorTest { static void maskFromToLongByte512VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5614,5 +5617,12 @@ public class Byte512VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueByte512VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java index 7ca7543a992a4701f8986694cfc712cc09006ee5..cc8c2e1c24c500c527e312f0306d7bed89b528fc 100644 --- a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java @@ -226,10 +226,10 @@ public class Byte64VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index) { - int i = 0; + static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3444,13 +3444,16 @@ public class Byte64VectorTests extends AbstractVectorTest { byte[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - av.withLane(0, (byte)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (byte)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (byte)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (byte)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(byte a) { return bits(a)==0; @@ -5512,7 +5515,7 @@ public class Byte64VectorTests extends AbstractVectorTest { static void maskFromToLongByte64VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5614,5 +5617,12 @@ public class Byte64VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueByte64VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java index 422dd249a8d4ca1580bd175f0b85ffc8e9fbf141..eb438cb20426f7e248c8ff5c034d342171b33ca1 100644 --- a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java @@ -24,7 +24,7 @@ /* * @test * @modules jdk.incubator.vector - * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation ByteMaxVectorTests + * @run testng/othervm/timeout=240 -ea -esa -Xbatch -XX:-TieredCompilation ByteMaxVectorTests */ // -- This file was mechanically generated: Do not edit! -- // @@ -231,10 +231,10 @@ public class ByteMaxVectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index) { - int i = 0; + static void assertInsertArraysEquals(byte[] r, byte[] a, byte element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3449,13 +3449,16 @@ public class ByteMaxVectorTests extends AbstractVectorTest { byte[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - av.withLane(0, (byte)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (byte)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (byte)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (byte)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(byte a) { return bits(a)==0; @@ -5603,5 +5606,12 @@ public class ByteMaxVectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueByteMaxVectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Double128VectorTests.java b/test/jdk/jdk/incubator/vector/Double128VectorTests.java index a2dd0d44720a91bd5f24a1fe3748af3030df1a6b..646570f3752e2c4ad9eeaf15bf35d321b2e1e50c 100644 --- a/test/jdk/jdk/incubator/vector/Double128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double128VectorTests.java @@ -226,10 +226,10 @@ public class Double128VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(double[] r, double[] a, double element, int index) { - int i = 0; + static void assertInsertArraysEquals(double[] r, double[] a, double element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2457,13 +2457,16 @@ public class Double128VectorTests extends AbstractVectorTest { double[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - av.withLane(0, (double)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (double)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (double)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (double)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(double a) { return bits(a)==0; @@ -4891,7 +4894,7 @@ public class Double128VectorTests extends AbstractVectorTest { static void maskFromToLongDouble128VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -4993,5 +4996,12 @@ public class Double128VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueDouble128VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Double256VectorTests.java b/test/jdk/jdk/incubator/vector/Double256VectorTests.java index c7be717ef5f72851f3055b43038904b53deb1fbc..a7d0a2c0b9f7b75c9856e1653c3a539f0a17a72a 100644 --- a/test/jdk/jdk/incubator/vector/Double256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double256VectorTests.java @@ -226,10 +226,10 @@ public class Double256VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(double[] r, double[] a, double element, int index) { - int i = 0; + static void assertInsertArraysEquals(double[] r, double[] a, double element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2457,13 +2457,16 @@ public class Double256VectorTests extends AbstractVectorTest { double[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - av.withLane(0, (double)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (double)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (double)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (double)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(double a) { return bits(a)==0; @@ -4891,7 +4894,7 @@ public class Double256VectorTests extends AbstractVectorTest { static void maskFromToLongDouble256VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -4993,5 +4996,12 @@ public class Double256VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueDouble256VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Double512VectorTests.java b/test/jdk/jdk/incubator/vector/Double512VectorTests.java index ed7a2e470cb5660fbbafdfa4d9700bb7a32a69a1..26a699454bc8a30f4b06a9c0907e8e856e6261a3 100644 --- a/test/jdk/jdk/incubator/vector/Double512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double512VectorTests.java @@ -226,10 +226,10 @@ public class Double512VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(double[] r, double[] a, double element, int index) { - int i = 0; + static void assertInsertArraysEquals(double[] r, double[] a, double element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2457,13 +2457,16 @@ public class Double512VectorTests extends AbstractVectorTest { double[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - av.withLane(0, (double)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (double)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (double)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (double)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(double a) { return bits(a)==0; @@ -4891,7 +4894,7 @@ public class Double512VectorTests extends AbstractVectorTest { static void maskFromToLongDouble512VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -4993,5 +4996,12 @@ public class Double512VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueDouble512VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Double64VectorTests.java b/test/jdk/jdk/incubator/vector/Double64VectorTests.java index 20e70d70cc0ed35495cd85a7189c98623a596aaf..017889f8b9ac1bcaa4dc673d329ade14a7cb60fd 100644 --- a/test/jdk/jdk/incubator/vector/Double64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double64VectorTests.java @@ -226,10 +226,10 @@ public class Double64VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(double[] r, double[] a, double element, int index) { - int i = 0; + static void assertInsertArraysEquals(double[] r, double[] a, double element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2457,13 +2457,16 @@ public class Double64VectorTests extends AbstractVectorTest { double[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - av.withLane(0, (double)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (double)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (double)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (double)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(double a) { return bits(a)==0; @@ -4891,7 +4894,7 @@ public class Double64VectorTests extends AbstractVectorTest { static void maskFromToLongDouble64VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -4993,5 +4996,12 @@ public class Double64VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueDouble64VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java index ee136b9b32bbf33d955770d57ea37d8b861f7a8f..c4eb2b2182bf34039d75e44e60cf4234ed10c632 100644 --- a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java @@ -231,10 +231,10 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(double[] r, double[] a, double element, int index) { - int i = 0; + static void assertInsertArraysEquals(double[] r, double[] a, double element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2462,13 +2462,16 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { double[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - av.withLane(0, (double)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (double)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (double)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (double)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(double a) { return bits(a)==0; @@ -4982,5 +4985,12 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueDoubleMaxVectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Float128VectorTests.java b/test/jdk/jdk/incubator/vector/Float128VectorTests.java index 7e01f848864c754af9e486744ba0b87d64066dde..b3e7b05d2a259cab2a1d6676ed28d89eddd579d2 100644 --- a/test/jdk/jdk/incubator/vector/Float128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float128VectorTests.java @@ -226,10 +226,10 @@ public class Float128VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(float[] r, float[] a, float element, int index) { - int i = 0; + static void assertInsertArraysEquals(float[] r, float[] a, float element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2467,13 +2467,16 @@ public class Float128VectorTests extends AbstractVectorTest { float[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - av.withLane(0, (float)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (float)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (float)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (float)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(float a) { return bits(a)==0; @@ -4869,7 +4872,7 @@ public class Float128VectorTests extends AbstractVectorTest { static void maskFromToLongFloat128VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -4971,5 +4974,12 @@ public class Float128VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueFloat128VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Float256VectorTests.java b/test/jdk/jdk/incubator/vector/Float256VectorTests.java index 3ff38daa0a8c671f4ff4ea6ec00c0178aa607b1f..120fc4cabd212e9bb10fde78a649238ad4cd737d 100644 --- a/test/jdk/jdk/incubator/vector/Float256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float256VectorTests.java @@ -226,10 +226,10 @@ public class Float256VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(float[] r, float[] a, float element, int index) { - int i = 0; + static void assertInsertArraysEquals(float[] r, float[] a, float element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2467,13 +2467,16 @@ public class Float256VectorTests extends AbstractVectorTest { float[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - av.withLane(0, (float)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (float)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (float)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (float)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(float a) { return bits(a)==0; @@ -4869,7 +4872,7 @@ public class Float256VectorTests extends AbstractVectorTest { static void maskFromToLongFloat256VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -4971,5 +4974,12 @@ public class Float256VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueFloat256VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Float512VectorTests.java b/test/jdk/jdk/incubator/vector/Float512VectorTests.java index e7d9e3fa53212c58083c63e686d188a6f66dbd4c..75fbccaed27903366fd00f864eb2a1729a5674be 100644 --- a/test/jdk/jdk/incubator/vector/Float512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float512VectorTests.java @@ -226,10 +226,10 @@ public class Float512VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(float[] r, float[] a, float element, int index) { - int i = 0; + static void assertInsertArraysEquals(float[] r, float[] a, float element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2467,13 +2467,16 @@ public class Float512VectorTests extends AbstractVectorTest { float[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - av.withLane(0, (float)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (float)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (float)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (float)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(float a) { return bits(a)==0; @@ -4869,7 +4872,7 @@ public class Float512VectorTests extends AbstractVectorTest { static void maskFromToLongFloat512VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -4971,5 +4974,12 @@ public class Float512VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueFloat512VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Float64VectorTests.java b/test/jdk/jdk/incubator/vector/Float64VectorTests.java index e4c646623bb93b219abde2ece7c25f7da218acb1..dbe87867b9aecc24604cd038b5d3bb8978ceba0d 100644 --- a/test/jdk/jdk/incubator/vector/Float64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float64VectorTests.java @@ -226,10 +226,10 @@ public class Float64VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(float[] r, float[] a, float element, int index) { - int i = 0; + static void assertInsertArraysEquals(float[] r, float[] a, float element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2467,13 +2467,16 @@ public class Float64VectorTests extends AbstractVectorTest { float[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - av.withLane(0, (float)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (float)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (float)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (float)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(float a) { return bits(a)==0; @@ -4869,7 +4872,7 @@ public class Float64VectorTests extends AbstractVectorTest { static void maskFromToLongFloat64VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -4971,5 +4974,12 @@ public class Float64VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueFloat64VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java index 23f01dcdb95ba05917fc601d39e5330e92b196db..5d3e65b765b6bf73a6344ab6272b381f47cd2406 100644 --- a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java @@ -231,10 +231,10 @@ public class FloatMaxVectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(float[] r, float[] a, float element, int index) { - int i = 0; + static void assertInsertArraysEquals(float[] r, float[] a, float element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -2472,13 +2472,16 @@ public class FloatMaxVectorTests extends AbstractVectorTest { float[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - av.withLane(0, (float)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (float)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (float)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (float)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(float a) { return bits(a)==0; @@ -4960,5 +4963,12 @@ public class FloatMaxVectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueFloatMaxVectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Int128VectorTests.java b/test/jdk/jdk/incubator/vector/Int128VectorTests.java index 0493494d1c02f2b25fce70cdd62fae6b297a87d8..d23295f5b4e2d5cc68492835092a5ddd793181f9 100644 --- a/test/jdk/jdk/incubator/vector/Int128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int128VectorTests.java @@ -226,10 +226,10 @@ public class Int128VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(int[] r, int[] a, int element, int index) { - int i = 0; + static void assertInsertArraysEquals(int[] r, int[] a, int element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3409,13 +3409,16 @@ public class Int128VectorTests extends AbstractVectorTest { int[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - av.withLane(0, (int)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (int)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (int)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (int)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(int a) { return bits(a)==0; @@ -5466,7 +5469,7 @@ public class Int128VectorTests extends AbstractVectorTest { static void maskFromToLongInt128VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5568,5 +5571,12 @@ public class Int128VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueInt128VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Int256VectorTests.java b/test/jdk/jdk/incubator/vector/Int256VectorTests.java index 9b1872f33d1e09a731afd5ce033e5095016147a4..f6bc1f7fd4c59887df9deb9b0025d66ff8bc8d13 100644 --- a/test/jdk/jdk/incubator/vector/Int256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int256VectorTests.java @@ -226,10 +226,10 @@ public class Int256VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(int[] r, int[] a, int element, int index) { - int i = 0; + static void assertInsertArraysEquals(int[] r, int[] a, int element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3409,13 +3409,16 @@ public class Int256VectorTests extends AbstractVectorTest { int[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - av.withLane(0, (int)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (int)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (int)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (int)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(int a) { return bits(a)==0; @@ -5466,7 +5469,7 @@ public class Int256VectorTests extends AbstractVectorTest { static void maskFromToLongInt256VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5568,5 +5571,12 @@ public class Int256VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueInt256VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Int512VectorTests.java b/test/jdk/jdk/incubator/vector/Int512VectorTests.java index 52dcf43e31b5411a967be4c7d89c30fe6eb6e9e7..7f5ce407da61feffbd070b92da2e70a9baa37e16 100644 --- a/test/jdk/jdk/incubator/vector/Int512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int512VectorTests.java @@ -226,10 +226,10 @@ public class Int512VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(int[] r, int[] a, int element, int index) { - int i = 0; + static void assertInsertArraysEquals(int[] r, int[] a, int element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3409,13 +3409,16 @@ public class Int512VectorTests extends AbstractVectorTest { int[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - av.withLane(0, (int)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (int)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (int)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (int)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(int a) { return bits(a)==0; @@ -5466,7 +5469,7 @@ public class Int512VectorTests extends AbstractVectorTest { static void maskFromToLongInt512VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5568,5 +5571,12 @@ public class Int512VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueInt512VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Int64VectorTests.java b/test/jdk/jdk/incubator/vector/Int64VectorTests.java index 9d9fffcf246e8d29eaae382ce379c5ad3a10c86c..6da8ecf04e4d8c8cd96b9348e771faf641152576 100644 --- a/test/jdk/jdk/incubator/vector/Int64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int64VectorTests.java @@ -226,10 +226,10 @@ public class Int64VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(int[] r, int[] a, int element, int index) { - int i = 0; + static void assertInsertArraysEquals(int[] r, int[] a, int element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3409,13 +3409,16 @@ public class Int64VectorTests extends AbstractVectorTest { int[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - av.withLane(0, (int)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (int)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (int)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (int)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(int a) { return bits(a)==0; @@ -5466,7 +5469,7 @@ public class Int64VectorTests extends AbstractVectorTest { static void maskFromToLongInt64VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5568,5 +5571,12 @@ public class Int64VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueInt64VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java index d226226cac269527fca667b4d291c0542724c53b..0e59f7f0ed548740bbb543d14e4d35493812ccd8 100644 --- a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java @@ -231,10 +231,10 @@ public class IntMaxVectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(int[] r, int[] a, int element, int index) { - int i = 0; + static void assertInsertArraysEquals(int[] r, int[] a, int element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3414,13 +3414,16 @@ public class IntMaxVectorTests extends AbstractVectorTest { int[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - av.withLane(0, (int)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (int)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (int)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (int)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(int a) { return bits(a)==0; @@ -5557,5 +5560,12 @@ public class IntMaxVectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueIntMaxVectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Long128VectorTests.java b/test/jdk/jdk/incubator/vector/Long128VectorTests.java index 03d163a8a4c607fc752e0d51cb23c774c9d84b9e..ebd7acb104dc2814a9d49314808f1c4ba08a9c71 100644 --- a/test/jdk/jdk/incubator/vector/Long128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long128VectorTests.java @@ -183,10 +183,10 @@ public class Long128VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(long[] r, long[] a, long element, int index) { - int i = 0; + static void assertInsertArraysEquals(long[] r, long[] a, long element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3431,13 +3431,16 @@ public class Long128VectorTests extends AbstractVectorTest { long[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - av.withLane(0, (long)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (long)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (long)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (long)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(long a) { return bits(a)==0; @@ -5350,7 +5353,7 @@ public class Long128VectorTests extends AbstractVectorTest { static void maskFromToLongLong128VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5452,5 +5455,12 @@ public class Long128VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueLong128VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Long256VectorTests.java b/test/jdk/jdk/incubator/vector/Long256VectorTests.java index 91a41519bb43610d527da5b8b6bdf802be6e16d6..5065745e5f82fd02c8fd9f4d75cf959cbc1f1b76 100644 --- a/test/jdk/jdk/incubator/vector/Long256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long256VectorTests.java @@ -183,10 +183,10 @@ public class Long256VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(long[] r, long[] a, long element, int index) { - int i = 0; + static void assertInsertArraysEquals(long[] r, long[] a, long element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3431,13 +3431,16 @@ public class Long256VectorTests extends AbstractVectorTest { long[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - av.withLane(0, (long)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (long)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (long)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (long)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(long a) { return bits(a)==0; @@ -5350,7 +5353,7 @@ public class Long256VectorTests extends AbstractVectorTest { static void maskFromToLongLong256VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5452,5 +5455,12 @@ public class Long256VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueLong256VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Long512VectorTests.java b/test/jdk/jdk/incubator/vector/Long512VectorTests.java index 53fa4592fc64baac7da7628fd71f57a4e6a14545..dd0c71e1dbc44caa8482e31020df5b6b669031ad 100644 --- a/test/jdk/jdk/incubator/vector/Long512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long512VectorTests.java @@ -183,10 +183,10 @@ public class Long512VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(long[] r, long[] a, long element, int index) { - int i = 0; + static void assertInsertArraysEquals(long[] r, long[] a, long element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3431,13 +3431,16 @@ public class Long512VectorTests extends AbstractVectorTest { long[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - av.withLane(0, (long)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (long)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (long)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (long)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(long a) { return bits(a)==0; @@ -5350,7 +5353,7 @@ public class Long512VectorTests extends AbstractVectorTest { static void maskFromToLongLong512VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5452,5 +5455,12 @@ public class Long512VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueLong512VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Long64VectorTests.java b/test/jdk/jdk/incubator/vector/Long64VectorTests.java index c8f9c31e4994e537091dbd7042f8abed9a398fee..919f6ef0f6a0be0046afcd7a777fc914e5428125 100644 --- a/test/jdk/jdk/incubator/vector/Long64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long64VectorTests.java @@ -183,10 +183,10 @@ public class Long64VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(long[] r, long[] a, long element, int index) { - int i = 0; + static void assertInsertArraysEquals(long[] r, long[] a, long element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3431,13 +3431,16 @@ public class Long64VectorTests extends AbstractVectorTest { long[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - av.withLane(0, (long)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (long)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (long)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (long)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(long a) { return bits(a)==0; @@ -5350,7 +5353,7 @@ public class Long64VectorTests extends AbstractVectorTest { static void maskFromToLongLong64VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5452,5 +5455,12 @@ public class Long64VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueLong64VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java index e5cd61eca7477ddd1bf44d4b04913946ca3e295e..443de01cdb4f9205c4809ecf5b38e299aa881838 100644 --- a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java @@ -188,10 +188,10 @@ public class LongMaxVectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(long[] r, long[] a, long element, int index) { - int i = 0; + static void assertInsertArraysEquals(long[] r, long[] a, long element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3436,13 +3436,16 @@ public class LongMaxVectorTests extends AbstractVectorTest { long[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - av.withLane(0, (long)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (long)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (long)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (long)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(long a) { return bits(a)==0; @@ -5441,5 +5444,12 @@ public class LongMaxVectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueLongMaxVectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Short128VectorTests.java b/test/jdk/jdk/incubator/vector/Short128VectorTests.java index 88eca9e1d9a0fe31357661d7150a5a9a7557655a..2e50b940b0ee352e23e75c1d8f790d89a9505048 100644 --- a/test/jdk/jdk/incubator/vector/Short128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short128VectorTests.java @@ -226,10 +226,10 @@ public class Short128VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(short[] r, short[] a, short element, int index) { - int i = 0; + static void assertInsertArraysEquals(short[] r, short[] a, short element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3434,13 +3434,16 @@ public class Short128VectorTests extends AbstractVectorTest { short[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - av.withLane(0, (short)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (short)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (short)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (short)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(short a) { return bits(a)==0; @@ -5491,7 +5494,7 @@ public class Short128VectorTests extends AbstractVectorTest { static void maskFromToLongShort128VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5593,5 +5596,12 @@ public class Short128VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueShort128VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Short256VectorTests.java b/test/jdk/jdk/incubator/vector/Short256VectorTests.java index bc33a302cec9357d5df243c3bb4dbf750482a18d..67fc08c619495c548a9cd21f4ded8b948157dea2 100644 --- a/test/jdk/jdk/incubator/vector/Short256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short256VectorTests.java @@ -226,10 +226,10 @@ public class Short256VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(short[] r, short[] a, short element, int index) { - int i = 0; + static void assertInsertArraysEquals(short[] r, short[] a, short element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3434,13 +3434,16 @@ public class Short256VectorTests extends AbstractVectorTest { short[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - av.withLane(0, (short)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (short)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (short)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (short)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(short a) { return bits(a)==0; @@ -5491,7 +5494,7 @@ public class Short256VectorTests extends AbstractVectorTest { static void maskFromToLongShort256VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5593,5 +5596,12 @@ public class Short256VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueShort256VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Short512VectorTests.java b/test/jdk/jdk/incubator/vector/Short512VectorTests.java index b33134d622534369d61eea65111ec7cbbce048b6..63bc3709481bb971b2f5087c5c1d0603d2045b32 100644 --- a/test/jdk/jdk/incubator/vector/Short512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short512VectorTests.java @@ -226,10 +226,10 @@ public class Short512VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(short[] r, short[] a, short element, int index) { - int i = 0; + static void assertInsertArraysEquals(short[] r, short[] a, short element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3434,13 +3434,16 @@ public class Short512VectorTests extends AbstractVectorTest { short[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - av.withLane(0, (short)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (short)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (short)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (short)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(short a) { return bits(a)==0; @@ -5491,7 +5494,7 @@ public class Short512VectorTests extends AbstractVectorTest { static void maskFromToLongShort512VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5593,5 +5596,12 @@ public class Short512VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueShort512VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/Short64VectorTests.java b/test/jdk/jdk/incubator/vector/Short64VectorTests.java index af7dd74ac0e39d78f5d4383cdc8b550071a814be..8c05159737d2da22b2d06bb8e995c9dc394f2459 100644 --- a/test/jdk/jdk/incubator/vector/Short64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short64VectorTests.java @@ -226,10 +226,10 @@ public class Short64VectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(short[] r, short[] a, short element, int index) { - int i = 0; + static void assertInsertArraysEquals(short[] r, short[] a, short element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3434,13 +3434,16 @@ public class Short64VectorTests extends AbstractVectorTest { short[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - av.withLane(0, (short)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (short)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (short)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (short)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(short a) { return bits(a)==0; @@ -5491,7 +5494,7 @@ public class Short64VectorTests extends AbstractVectorTest { static void maskFromToLongShort64VectorTestsSmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } @DataProvider @@ -5593,5 +5596,12 @@ public class Short64VectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueShort64VectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java index 04681e6985dab62805a50cdb1212a55be84c7665..b196aad5218e6ca809ce24387fe138908c2a4dd0 100644 --- a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java @@ -231,10 +231,10 @@ public class ShortMaxVectorTests extends AbstractVectorTest { } } - static void assertInsertArraysEquals(short[] r, short[] a, short element, int index) { - int i = 0; + static void assertInsertArraysEquals(short[] r, short[] a, short element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { @@ -3439,13 +3439,16 @@ public class ShortMaxVectorTests extends AbstractVectorTest { short[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - av.withLane(0, (short)4).intoArray(r, i); + av.withLane((j++ & (SPECIES.length()-1)), (short)(65535+i)).intoArray(r, i); } } - assertInsertArraysEquals(r, a, (short)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, (short)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } static boolean testIS_DEFAULT(short a) { return bits(a)==0; @@ -5582,5 +5585,12 @@ public class ShortMaxVectorTests extends AbstractVectorTest { VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrueShortMaxVectorTestsSmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } } diff --git a/test/jdk/jdk/incubator/vector/VectorReshapeTests.java b/test/jdk/jdk/incubator/vector/VectorReshapeTests.java index 5db3577f36e5bf2b4966126e0e55e4ebbdae9f15..36306706037317a4c639983d4eb272ae41222dd0 100644 --- a/test/jdk/jdk/incubator/vector/VectorReshapeTests.java +++ b/test/jdk/jdk/incubator/vector/VectorReshapeTests.java @@ -39,7 +39,7 @@ import jdk.incubator.vector.VectorSpecies; * @test * @modules jdk.incubator.vector * @modules java.base/jdk.internal.vm.annotation - * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED + * @run testng/othervm/timeout=240 --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED * -XX:-TieredCompilation VectorReshapeTests */ diff --git a/test/jdk/jdk/incubator/vector/templates/Kernel-With-Op.template b/test/jdk/jdk/incubator/vector/templates/Kernel-With-Op.template index 11bdbf234cf415bf91898eae57044e1c0b06bdce..95d74b848601224f9294a67fe3bf23f1cbadecc7 100644 --- a/test/jdk/jdk/incubator/vector/templates/Kernel-With-Op.template +++ b/test/jdk/jdk/incubator/vector/templates/Kernel-With-Op.template @@ -2,9 +2,9 @@ $type$[] r = fr.apply(SPECIES.length()); for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); - av.withLane(0, ($type$)4).intoArray(r, i); + av.withLane((j++ \& (SPECIES.length()-1)), ($type$)(65535+i)).intoArray(r, i); } } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Miscellaneous.template b/test/jdk/jdk/incubator/vector/templates/Unit-Miscellaneous.template index a75a6842bd316fe558854d1fe6dda651453c5a06..d72ce5bd0858d8061f3d457fa92d28b0d13d99e8 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Miscellaneous.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-Miscellaneous.template @@ -499,7 +499,7 @@ static void maskFromToLong$vectorteststype$SmokeTest(long inputLong) { var vmask = VectorMask.fromLong(SPECIES, inputLong); long outputLong = vmask.toLong(); - Assert.assertEquals(outputLong, inputLong & (((1L << (SPECIES.length() - 1)) << 1) - 1)); + Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length())))))); } #end[!MaxBit] @@ -602,3 +602,10 @@ VectorSpecies species = av.species().withShape(vsh); assert(species.equals(SPECIES)); } + + @Test + static void MaskAllTrue$vectorteststype$SmokeTest() { + for (int ic = 0; ic < INVOC_COUNT; ic++) { + Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length())); + } + } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-With-Op.template b/test/jdk/jdk/incubator/vector/templates/Unit-With-Op.template index cb44361c094a73612b2b602f7efdac0ba696b20d..c41bd05f20e69b0f1809f16829f78e7e951d7974 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-With-Op.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-With-Op.template @@ -2,5 +2,8 @@ @Test(dataProvider = "$type$UnaryOpProvider") static void with$vectorteststype$(IntFunction<$type$ []> fa) { [[KERNEL]] - assertInsertArraysEquals(r, a, ($type$)4, 0); + + for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) { + assertInsertArraysEquals(r, a, ($type$)(65535+i), (j++ & (SPECIES.length()-1)), i , i + SPECIES.length()); + } } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-header.template b/test/jdk/jdk/incubator/vector/templates/Unit-header.template index 0cbb3447340b2a05fe81089e9be17150d3455466..f73d697e2a703e7d15f8256f487788b4e3ac42d4 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-header.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-header.template @@ -257,10 +257,10 @@ public class $vectorteststype$ extends AbstractVectorTest { } } - static void assertInsertArraysEquals($type$[] r, $type$[] a, $type$ element, int index) { - int i = 0; + static void assertInsertArraysEquals($type$[] r, $type$[] a, $type$ element, int index, int start, int end) { + int i = start; try { - for (; i < a.length; i += 1) { + for (; i < end; i += 1) { if(i%SPECIES.length() == index) { Assert.assertEquals(r[i], element); } else { diff --git a/test/jdk/jdk/jfr/api/consumer/TestHiddenMethod.java b/test/jdk/jdk/jfr/api/consumer/TestHiddenMethod.java index 7a5bf1e42c42f6c38577a3e17dc4161501dc1acc..f1eeac58362d12f12fc01516bd8382ac1a3e929a 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestHiddenMethod.java +++ b/test/jdk/jdk/jfr/api/consumer/TestHiddenMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,10 +51,10 @@ import jdk.test.lib.jfr.Events; */ public final class TestHiddenMethod { - public static void main(String[] args) throws Throwable { - try (Recording recording = new Recording()) { - recording.enable(MyEvent.class).withThreshold(Duration.ofMillis(0)); - recording.start(); + // Must call in separate thread because JTREG uses reflection + // to invoke main method, which uses hidden methods. + public static class TestThread extends Thread { + public void run() { // doPrivileged calls a method that has the @Hidden // annotation AccessController.doPrivileged(new PrivilegedAction<Void>() { @@ -65,8 +65,19 @@ public final class TestHiddenMethod { return null; } }); + MyEvent event = new MyEvent(); event.commit(); + } + } + + public static void main(String[] args) throws Throwable { + try (Recording recording = new Recording()) { + recording.enable(MyEvent.class).withThreshold(Duration.ofMillis(0)); + recording.start(); + Thread t = new TestThread(); + t.start(); + t.join(); recording.stop(); List<RecordedEvent> events = Events.fromRecording(recording); @@ -78,9 +89,7 @@ public final class TestHiddenMethod { System.out.println("visibleEvent:" + visibleEvent); assertTrue(hasHiddenStackFrame(hiddenEvent), "No hidden frame in hidden event: " + hiddenEvent); - - // Temporary disable this test until JDK-8272064 is resolved. - // assertFalse(hasHiddenStackFrame(visibleEvent), "Hidden frame in visible event: " + visibleEvent); + assertFalse(hasHiddenStackFrame(visibleEvent), "Hidden frame in visible event: " + visibleEvent); } } diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedFullStackTrace.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedFullStackTrace.java index 1487d2e0258f1f7516d306a6e748273db0562734..6993fe3100178c4b909566160c7e7cd13f665fb8 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedFullStackTrace.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedFullStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,7 +119,7 @@ public class TestRecordedFullStackTrace { if (!isEventFound[i]) { // no assertion, let's retry. // Could be race condition, i.e safe point during Thread.sleep - System.out.println("Falied to validate all threads, will retry."); + System.out.println("Failed to validate all threads, will retry."); return false; } } diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMCrash.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMCrash.java index 3c6620b8caf4f32ef452231736993d2be0eff134..c1594462a80305b6b97af1e5ab1638b576ac6d12 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMCrash.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMCrash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ import jdk.jfr.consumer.EventStream; * @library /test/lib /test/jdk * @modules jdk.jfr jdk.attach java.base/jdk.internal.misc * - * @run main/othervm jdk.jfr.api.consumer.streaming.TestJVMCrash + * @run main/othervm -Dsun.tools.attach.attachTimeout=100000 jdk.jfr.api.consumer.streaming.TestJVMCrash */ public class TestJVMCrash { diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java index c4bdfdf6402d60f45dbd010ef0b30a250ee3f408..5b30a52e4b757f5ea9c91902b0f64c7aa0d768a1 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ import jdk.jfr.consumer.EventStream; * @library /test/lib /test/jdk * @modules jdk.jfr jdk.attach java.base/jdk.internal.misc * - * @run main/othervm jdk.jfr.api.consumer.streaming.TestJVMExit + * @run main/othervm -Dsun.tools.attach.attachTimeout=100000 jdk.jfr.api.consumer.streaming.TestJVMExit */ public class TestJVMExit { diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java index 4190d97eaaf3dabaf6798692024b0d2a8368d8ee..4515ae9832a01452c287a754cfee258486e7d9b1 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java @@ -23,8 +23,12 @@ package jdk.jfr.api.consumer.streaming; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Comparator; +import java.util.List; +import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -34,6 +38,7 @@ import jdk.jfr.FlightRecorder; import jdk.jfr.Name; import jdk.jfr.Recording; import jdk.jfr.consumer.EventStream; +import jdk.jfr.consumer.RecordingFile; import jdk.jfr.consumer.RecordingStream; /** @@ -65,7 +70,8 @@ public class TestLatestEvent { CountDownLatch beginChunks = new CountDownLatch(1); try (RecordingStream r = new RecordingStream()) { - r.onEvent("MakeChunks", event-> { + r.setMaxSize(1_000_000_000); + r.onEvent("MakeChunks", event -> { System.out.println(event); beginChunks.countDown(); }); @@ -100,13 +106,25 @@ public class TestLatestEvent { // This latch ensures thatNotLatest has been // flushed and a new valid position has been written // to the chunk header - notLatestEvent.await(80, TimeUnit.SECONDS); + boolean timeout = notLatestEvent.await(80, TimeUnit.SECONDS); if (notLatestEvent.getCount() != 0) { + System.out.println("timeout = " + timeout); + Path repo = Path.of(System.getProperty("jdk.jfr.repository")); + System.out.println("repo = " + repo); + List<Path> files = new ArrayList<>(Files.list(repo).toList()); + files.sort(Comparator.comparing(Path::toString)); + for (Path f : files) { + System.out.println("------------"); + System.out.println("File: " + f); + for (var event : RecordingFile.readAllEvents(f)) { + System.out.println(event); + } + } Recording rec = FlightRecorder.getFlightRecorder().takeSnapshot(); Path p = Paths.get("error-not-latest.jfr").toAbsolutePath(); rec.dump(p); System.out.println("Dumping repository as a file for inspection at " + p); - throw new Exception("Timeout 80 s. Expected 6 event, but got " + notLatestEvent.getCount()); + throw new Exception("Timeout 80 s. Expected 6 event, but got " + (6 - notLatestEvent.getCount())); } try (EventStream s = EventStream.openRepository()) { diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java index b41b6779ac88312e5454f9711390a161e2ce3633..80f060633ccf117442be7bd1ea29110bbbeb2cbc 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java @@ -126,7 +126,7 @@ public class TestG1ParallelPhases { // since we can not reliably guarantee that they occur (or not). Set<String> optPhases = of( // The following two phases only occur on evacuation failure. - "RemoveSelfForwardingPtr", + "RestoreRetainedRegions", "RestorePreservedMarks", "OptScanHR", diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java index 730a3b700c6e80bc960efa444a4bba60fea65e99..d98fdb76e92bad3a2b965ddd9baa18e765627c16 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,8 @@ public class TestGCCauseWithG1ConcurrentMark { String testID = "G1ConcurrentMark"; String[] vmFlags = {"-XX:+UseG1GC", "-XX:+ExplicitGCInvokesConcurrent"}; String[] gcNames = {GCHelper.gcG1New, GCHelper.gcG1Old, GCHelper.gcG1Full}; - String[] gcCauses = {"G1 Evacuation Pause", "G1 Preventive Collection", "G1 Compaction Pause", "System.gc()"}; + String[] gcCauses = {"GCLocker Initiated GC", "G1 Evacuation Pause", "G1 Preventive Collection", + "G1 Compaction Pause", "System.gc()"}; GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses); } } diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java index 67650dc3ba8a3d24161af3ab835df2e90793ed7b..737b94aa197977bd94bea05301b1821dce2b1e8f 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,8 @@ public class TestGCCauseWithG1FullCollection { String testID = "G1FullCollection"; String[] vmFlags = {"-XX:+UseG1GC"}; String[] gcNames = {GCHelper.gcG1New, GCHelper.gcG1Old, GCHelper.gcG1Full}; - String[] gcCauses = {"G1 Evacuation Pause", "G1 Preventive Collection", "G1 Compaction Pause", "System.gc()"}; + String[] gcCauses = {"GCLocker Initiated GC", "G1 Evacuation Pause", "G1 Preventive Collection", + "G1 Compaction Pause", "System.gc()"}; GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses); } } diff --git a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java index 3306f5c0d31fb313b4297b91c1103bffb765e320..b9f23ebed86229834a8c6dceeac3f167ae88ae5f 100644 --- a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java +++ b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,7 @@ public class TestFullStackTrace { if(!isEventFound[i]) { // no assertion, let's retry. // Could be race condition, i.e safe point during Thread.sleep - System.out.println("Falied to validate all threads, will retry."); + System.out.println("Failed to validate all threads, will retry."); return false; } } diff --git a/test/jdk/jdk/jfr/event/runtime/TestFinalizerStatisticsEvent.java b/test/jdk/jdk/jfr/event/runtime/TestFinalizerStatisticsEvent.java index ecec7c383fb7bc46fa9dc6bf9c3f9f420dce7030..8256a62b5712b62dce068da4ae9742003990ec12 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestFinalizerStatisticsEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestFinalizerStatisticsEvent.java @@ -34,17 +34,20 @@ import jdk.test.lib.jfr.TestClassLoader; /** * @test + * @bug 8266936 8276422 * @summary The test verifies that classes overriding finalize() are represented as events. * @key jfr * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -Xlog:class+unload,finalizer -Xmx16m jdk.jfr.event.runtime.TestFinalizerStatisticsEvent + * @run main/othervm -Xlog:class+unload,finalizer -Xmx16m --finalization=disabled jdk.jfr.event.runtime.TestFinalizerStatisticsEvent disabled */ public final class TestFinalizerStatisticsEvent { private final static String TEST_CLASS_NAME = "jdk.jfr.event.runtime.TestFinalizerStatisticsEvent$TestClassOverridingFinalize"; private final static String TEST_CLASS_UNLOAD_NAME = "jdk.jfr.event.runtime.TestFinalizerStatisticsEvent$TestClassUnloadOverridingFinalize"; private final static String EVENT_PATH = EventNames.FinalizerStatistics; + private static boolean disabled = false; // Declare as public static to prevent the compiler from optimizing away all unread writes public static TestClassLoader unloadableClassLoader; @@ -52,6 +55,10 @@ public final class TestFinalizerStatisticsEvent { public static Object overridingInstance; public static void main(String[] args) throws Throwable { + if (args.length > 0 && "disabled".equals(args[0])) { + disabled = true; + System.out.println("Testing with finalization disabled"); + } Recording recording1 = new Recording(); recording1.enable(EVENT_PATH); Recording recording2 = new Recording(); @@ -69,8 +76,12 @@ public final class TestFinalizerStatisticsEvent { recording1.stop(); // rotation writes an event for TEST_CLASS_NAME into recording1 which now has 4 events reflecting this test case (3 chunks + 1 unload) try { - verify(recording2); - verify(recording1); + if (disabled) { + verifyDisabled(recording1); + } else { + verifyEnabled(recording2); + verifyEnabled(recording1); + } } finally { recording2.close(); @@ -84,7 +95,8 @@ public final class TestFinalizerStatisticsEvent { System.gc(); } - private static void verify(Recording recording) throws Throwable { + /* Verify correct operation with finalization enabled */ + private static void verifyEnabled(Recording recording) throws Throwable { boolean foundTestClassName = false; boolean foundTestClassUnloadName = false; List<RecordedEvent> events = Events.fromRecording(recording); @@ -108,6 +120,19 @@ public final class TestFinalizerStatisticsEvent { Asserts.assertTrue(foundTestClassUnloadName, "The class: " + TEST_CLASS_UNLOAD_NAME + " overriding finalize() is not found"); } + /* Verify no jdk.FinalizerStatistics events with finalization disabled */ + private static void verifyDisabled(Recording recording) throws Throwable { + int f10nEvents = 0; + List<RecordedEvent> events = Events.fromRecording(recording); + for (RecordedEvent event : events) { + System.out.println("Event:" + event); + if ("jdk.FinalizerStatistics".equals(event.getEventType().getName())) { + f10nEvents++; + } + } + Asserts.assertEquals(f10nEvents, 0, "Finalization disabled, but recorded " + f10nEvents + " jdk.FinalizerStatistics events"); + } + static public class TestClassOverridingFinalize { public boolean finalized = false; diff --git a/test/jdk/jdk/jfr/javaagent/EventEmitterAgent.java b/test/jdk/jdk/jfr/javaagent/EventEmitterAgent.java index 5a4cd4f534f5f372804a6e67a52b1dc0ba231661..ee829a412ed7470f76a31aee6a948af513f0f96c 100644 --- a/test/jdk/jdk/jfr/javaagent/EventEmitterAgent.java +++ b/test/jdk/jdk/jfr/javaagent/EventEmitterAgent.java @@ -24,6 +24,7 @@ package jdk.jfr.javaagent; import java.lang.instrument.Instrumentation; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -31,6 +32,7 @@ import jdk.jfr.Configuration; import jdk.jfr.Event; import jdk.jfr.Name; import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordingFile; import jdk.test.lib.Asserts; import jdk.test.lib.jfr.EventNames; @@ -38,7 +40,7 @@ import jdk.test.lib.jfr.EventNames; // Java agent that emits events public class EventEmitterAgent { - private static final long EVENTS = 150_000; + private static final long EVENTS = 15_000; private static final Path DUMP_PATH = Paths.get("dump.jfr").toAbsolutePath(); // Called when agent is loaded from command line @@ -88,10 +90,21 @@ public class EventEmitterAgent { } public static void validateRecording() throws Exception { - long testEventCount = RecordingFile.readAllEvents(DUMP_PATH) - .stream() - .filter(e -> e.getEventType().getName().equals("Test")) - .count(); + long testEventCount = 0; + try (RecordingFile rf = new RecordingFile(DUMP_PATH)) { + while (rf.hasMoreEvents()) { + RecordedEvent e = rf.readEvent(); + switch (e.getEventType().getName()) { + case "Test": + testEventCount++; + break; + case "jdk.DataLoss": + System.out.println(e); + break; + } + } + } + System.out.println("File size: " + Files.size(DUMP_PATH)); Asserts.assertEquals(testEventCount, EVENTS, "Mismatch in TestEvent count"); } } diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java index a43e0da065abd3c28990cc7c06fd979bab2a4ddd..aa76f5014831bf267dff77fb53f982c230f4fea7 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java @@ -52,7 +52,6 @@ public class TestJcmdConfigure { private static final String GLOBAL_BUFFER_SIZE = "globalbuffersize"; private static final String THREAD_BUFFER_SIZE = "thread_buffer_size"; private static final String MAX_CHUNK_SIZE = "maxchunksize"; - private static final String SAMPLE_THREADS = "samplethreads"; private static final String UNSUPPORTED_OPTION = "unsupportedoption"; private static final String REPOSITORYPATH_1 = "." + File.pathSeparator + "repo1"; @@ -80,8 +79,6 @@ public class TestJcmdConfigure { test(GLOBAL_BUFFER_SIZE, 6); test(THREAD_BUFFER_SIZE, 5); test(MAX_CHUNK_SIZE, 14 * 1000 * 1000); - test(SAMPLE_THREADS, false); - test(SAMPLE_THREADS, true); testNegative(UNSUPPORTED_OPTION, 100000); testNegative(MAX_CHUNK_SIZE, -500); @@ -125,7 +122,6 @@ public class TestJcmdConfigure { case GLOBAL_BUFFER_SIZE: return Options.getGlobalBufferSize(); case THREAD_BUFFER_SIZE: return Options.getThreadBufferSize(); case MAX_CHUNK_SIZE: return Options.getMaxChunkSize(); - case SAMPLE_THREADS: return Options.getSampleThreads(); default: throw new RuntimeException("Unknown option " + name); } } diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigureReadOnly.java b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigureReadOnly.java new file mode 100644 index 0000000000000000000000000000000000000000..6ddf3a752342d04952ffda1df0933f226a2a88b4 --- /dev/null +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigureReadOnly.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.jcmd; + +import jdk.test.lib.process.OutputAnalyzer; + +/** + * @test + * @summary The test verifies JFR.configure command can only set certain options before JFR is started. + * @key jfr + * @requires vm.hasJFR + * @library /test/lib /test/jdk + * @run main/othervm jdk.jfr.jcmd.TestJcmdConfigureReadOnly + */ +public class TestJcmdConfigureReadOnly { + public static void main(String[] args) throws Exception { + // Set an option before initializing JFR. + OutputAnalyzer output = JcmdHelper.jcmd("JFR.configure", "stackdepth=" + 128); + output.shouldContain("Stack depth: 128"); + // JFR.start will initialize JFR. + output = JcmdHelper.jcmd("JFR.start"); + JcmdAsserts.assertRecordingHasStarted(output); + // Attempt to set a new value after JFR initialization. + output = JcmdHelper.jcmd("JFR.configure", "stackdepth=" + 256); + // After initialization, the option is considered read-only. + output.shouldContain("Stack depth: 128"); + } +} diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestMaxSize.java b/test/jdk/jdk/jfr/jmx/streaming/TestMaxSize.java index af7493212caed8d6a7732e18856d805c91436f05..7bf389c75ad8546565f927a2279f60a244aba627 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestMaxSize.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestMaxSize.java @@ -70,12 +70,17 @@ public class TestMaxSize { while (directorySize(dir) < 50_000_000) { emitEvents(500_000); } + System.out.println("Before setMaxSize(1_000_000)"); + fileCount(dir); e.setMaxSize(1_000_000); + System.out.println("After setMaxSize(1_000_000)"); long count = fileCount(dir); - if (count > 2) { - // Two chunks can happen when header of new chunk is written and previous - // chunk is not finalized. - throw new Exception("Expected only one or two chunks with setMaxSize(1_000_000). Found " + count); + if (count > 3) { + // Three files can happen when: + // File 1: Header of new chunk is written to disk + // File 2: Previous chunk is not yet finalized and added to list of DiskChunks + // File 3: Previous previous file is in the list of DiskChunks. + throw new Exception("Expected at most three chunks with setMaxSize(1_000_000). Found " + count); } finished.set(true); } @@ -94,21 +99,24 @@ public class TestMaxSize { System.out.println("Files:"); AtomicInteger count = new AtomicInteger(); Files.list(dir).forEach(p -> { - System.out.println(p); + System.out.println(p + " " + fileSize(p)); count.incrementAndGet(); }); return count.get(); } private static long directorySize(Path dir) throws IOException { - long p = Files.list(dir).mapToLong(f -> { - try { - return Files.size(f); - } catch (IOException e) { - return 0; - } - }).sum(); + long p = Files.list(dir).mapToLong(f -> fileSize(f)).sum(); System.out.println("Directory size: " + p); return p; } + + private static long fileSize(Path p) { + try { + return Files.size(p); + } catch (IOException e) { + System.out.println("Could not determine file size for " + p); + return 0; + } + } } diff --git a/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java b/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java index 3869509b2426ec6233eacd34f592453776f55b5d..5cd1f435bfd7e496eb9b96204ee3d3f0868c5797 100644 --- a/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java +++ b/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.List; import jdk.internal.misc.Unsafe; @@ -74,22 +75,42 @@ public class TestDumpOnCrash { } public static void main(String[] args) throws Exception { + // Test without dumppath test(CrasherIllegalAccess.class, "", true); test(CrasherIllegalAccess.class, "", false); test(CrasherHalt.class, "", true); test(CrasherHalt.class, "", false); + // Test with dumppath + Path dumppath = Files.createTempDirectory(null); + try { + test(CrasherIllegalAccess.class, "", true, dumppath.toString()); + test(CrasherIllegalAccess.class, "", false, dumppath.toString()); + test(CrasherHalt.class, "", true, dumppath.toString()); + test(CrasherHalt.class, "", false, dumppath.toString()); + } finally { + dumppath.toFile().delete(); + } + // Test is excluded until 8219680 is fixed // @ignore 8219680 // test(CrasherSig.class, "FPE", true); } private static void test(Class<?> crasher, String signal, boolean disk) throws Exception { + test(crasher, signal, disk, null); + } + + private static void test(Class<?> crasher, String signal, boolean disk, String dumppath) throws Exception { + test(crasher, signal, disk, dumppath, dumppath); + } + + private static void test(Class<?> crasher, String signal, boolean disk, String dumppath, String expectedPath) throws Exception { // The JVM may be in a state it can't recover from, so try three times // before concluding functionality is not working. for (int attempt = 0; attempt < ATTEMPTS; attempt++) { try { - verify(runProcess(crasher, signal, disk)); + verify(runProcess(crasher, signal, disk, dumppath), expectedPath); return; } catch (Exception e) { System.out.println("Attempt " + attempt + ". Verification failed:"); @@ -105,17 +126,19 @@ public class TestDumpOnCrash { throw new Exception(ATTEMPTS + " attempts with failure!"); } - private static long runProcess(Class<?> crasher, String signal, boolean disk) throws Exception { + private static long runProcess(Class<?> crasher, String signal, boolean disk, String dumppath) throws Exception { System.out.println("Test case for crasher " + crasher.getName()); - final String flightRecordingOptions = "dumponexit=true,disk=" + Boolean.toString(disk); - Process p = ProcessTools.createTestJvm( - "-Xmx64m", - "-XX:-CreateCoredumpOnCrash", - "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", - "-XX:StartFlightRecording:" + flightRecordingOptions, - crasher.getName(), - signal) - .start(); + List<String> options = new ArrayList<>(); + options.add("-Xmx64m"); + options.add("-XX:-CreateCoredumpOnCrash"); + options.add("--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED"); + options.add("-XX:StartFlightRecording:dumponexit=true,disk=" + Boolean.toString(disk)); + if (dumppath != null) { + options.add("-XX:FlightRecorderOptions=dumppath=" + dumppath); + } + options.add(crasher.getName()); + options.add(signal); + Process p = ProcessTools.createTestJvm(options).start(); OutputAnalyzer output = new OutputAnalyzer(p); System.out.println("========== Crasher process output:"); @@ -125,9 +148,10 @@ public class TestDumpOnCrash { return p.pid(); } - private static void verify(long pid) throws IOException { + private static void verify(long pid, String dumppath) throws IOException { String fileName = "hs_err_pid" + pid + ".jfr"; - Path file = Paths.get(fileName).toAbsolutePath().normalize(); + Path file = (dumppath == null) ? Paths.get(fileName) : Paths.get(dumppath, fileName); + file = file.toAbsolutePath().normalize(); Asserts.assertTrue(Files.exists(file), "No emergency jfr recording file " + file + " exists"); Asserts.assertNotEquals(Files.size(file), 0L, "File length 0. Should at least be some bytes"); diff --git a/test/jdk/jdk/jfr/tool/TestPrintXML.java b/test/jdk/jdk/jfr/tool/TestPrintXML.java index 4480c23c7887bda5b64d79a41abab71b0ac2eff1..dd53955e40174f859b1c9ab2fd5d26349e2355f2 100644 --- a/test/jdk/jdk/jfr/tool/TestPrintXML.java +++ b/test/jdk/jdk/jfr/tool/TestPrintXML.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; +import org.xml.sax.Locator; import org.xml.sax.helpers.DefaultHandler; import jdk.jfr.Timespan; @@ -105,7 +106,14 @@ public class TestPrintXML { System.out.println(); System.out.println("Was (XML)"); System.out.println("----------------------"); - System.out.println(xmlEvent); + if (xmlEvent.begin > 0 && xmlEvent.end > 0) { + String lines[] = xml.split("\\r?\\n"); + for (int i = xmlEvent.begin - 1; i < xmlEvent.end; i++) { + System.out.println(i + " " + lines[i]); + } + } else { + System.out.println("Could not locate XML position"); + } System.out.println(); throw new Exception("Event doesn't match"); } @@ -164,6 +172,8 @@ public class TestPrintXML { static class XMLEvent { String name; private Map<String, Object> values = new HashMap<>(); + private int begin = -1; + private int end = -1; XMLEvent(String name) { this.name = name; @@ -172,10 +182,15 @@ public class TestPrintXML { public static final class RecordingHandler extends DefaultHandler { + private Locator locator; private Stack<Object> objects = new Stack<>(); private Stack<SimpleEntry<String, String>> elements = new Stack<>(); private List<XMLEvent> events = new ArrayList<>(); + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + @Override public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { elements.push(new SimpleEntry<>(attrs.getValue("name"), attrs.getValue("index"))); @@ -187,7 +202,9 @@ public class TestPrintXML { switch (qName) { case "event": - objects.push(new XMLEvent(attrs.getValue("type"))); + XMLEvent event = new XMLEvent(attrs.getValue("type")); + event.begin = locator.getLineNumber(); + objects.push(event); break; case "struct": objects.push(new HashMap<String, Object>()); @@ -223,7 +240,9 @@ public class TestPrintXML { String name = element.getKey(); Object value = objects.pop(); if (objects.isEmpty()) { - events.add((XMLEvent) value); + XMLEvent event = (XMLEvent) value; + event.end = locator.getLineNumber(); + events.add(event); return; } if (value instanceof StringBuilder) { diff --git a/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java b/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java index fe59857879b3daeff8a19910de8a93bd46e2a9db..77f866e9fdfdff4bab60eacfd71f280e3bd3387e 100644 --- a/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java +++ b/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,15 +35,15 @@ import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.Map; -import java.util.Random; /** * @test * @summary Verify that the outputstream created for zip file entries, through the ZipFileSystem * works fine for varying sizes of the zip file entries - * @bug 8190753 8011146 + * @bug 8190753 8011146 8279536 * @run testng/timeout=300 ZipFSOutputStreamTest */ public class ZipFSOutputStreamTest { @@ -87,7 +87,9 @@ public class ZipFSOutputStreamTest { @Test(dataProvider = "zipFSCreationEnv") public void testOutputStream(final Map<String, ?> env) throws Exception { final byte[] chunk = new byte[1024]; - new Random().nextBytes(chunk); + // fill it with some fixed content (the fixed content will later on help ease + // the verification of the content written out) + Arrays.fill(chunk, (byte) 42); try (final FileSystem zipfs = FileSystems.newFileSystem(ZIP_FILE, env)) { // create the zip with varying sized entries for (final Map.Entry<String, Long> entry : ZIP_ENTRIES.entrySet()) { @@ -95,9 +97,12 @@ public class ZipFSOutputStreamTest { if (entryPath.getParent() != null) { Files.createDirectories(entryPath.getParent()); } + long start = System.currentTimeMillis(); try (final OutputStream os = Files.newOutputStream(entryPath)) { writeAsChunks(os, chunk, entry.getValue()); } + System.out.println("Wrote entry " + entryPath + " of bytes " + entry.getValue() + + " in " + (System.currentTimeMillis() - start) + " milli seconds"); } } // now verify the written content @@ -108,15 +113,15 @@ public class ZipFSOutputStreamTest { final byte[] buf = new byte[chunk.length]; int numRead; long totalRead = 0; + long start = System.currentTimeMillis(); while ((numRead = is.read(buf)) != -1) { totalRead += numRead; // verify the content - for (int i = 0, chunkoffset = (int) ((totalRead - numRead) % chunk.length); - i < numRead; i++, chunkoffset++) { - Assert.assertEquals(buf[i], chunk[chunkoffset % chunk.length], - "Unexpected content in " + entryPath); - } + Assert.assertEquals(Arrays.mismatch(buf, chunk), -1, + "Unexpected content in " + entryPath); } + System.out.println("Read entry " + entryPath + " of bytes " + totalRead + + " in " + (System.currentTimeMillis() - start) + " milli seconds"); Assert.assertEquals(totalRead, (long) entry.getValue(), "Unexpected number of bytes read from zip entry " + entryPath); } diff --git a/test/jdk/jdk/nio/zipfs/ZipFSTester.java b/test/jdk/jdk/nio/zipfs/ZipFSTester.java index 48244bfc46b06e824ca1cdb5e178a4e59f5f8a93..08c998ca221854bf84c51abe12bce026594857ea 100644 --- a/test/jdk/jdk/nio/zipfs/ZipFSTester.java +++ b/test/jdk/jdk/nio/zipfs/ZipFSTester.java @@ -73,7 +73,7 @@ import static java.nio.file.StandardCopyOption.*; * @test * @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596 * 7157656 8002390 7012868 7012856 8015728 8038500 8040059 8069211 - * 8131067 8034802 8210899 8273961 + * 8131067 8034802 8210899 8273961 8271079 * @summary Test Zip filesystem provider * @modules jdk.zipfs * @run main ZipFSTester diff --git a/test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java b/test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java index 5b912c239bd0104eaa6f6b385499af73432a2493..82505e24e6cfc7304743368ebb51cf1c00e70ec7 100644 --- a/test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java +++ b/test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8164389 8222440 + * @bug 8164389 8222440 8271079 * @summary walk entries in a multi-release jar file via jdk.zipfs * @modules jdk.jartool * jdk.zipfs @@ -146,4 +146,58 @@ public class JFSTester { throw new UncheckedIOException(x); } } + + @Test + public void testToUri() throws IOException { + // treat multi-release jar as unversioned + Map<String, String> env = new HashMap<>(); + Set<String> contents = doTestUri(env); + Set<String> expectedContents = Set.of( + "!/root/dir1/leaf1.txt", + "!/root/dir1/leaf2.txt", + "!/root/dir2/leaf3.txt", + "!/root/dir2/leaf4.txt" + ); + Assert.assertEquals(contents, expectedContents); + + // open file as multi-release for version 9 + env.put("multi-release", "9"); + contents = doTestUri(env); + expectedContents = Set.of( + "!/root/dir1/leaf1.txt", + "!/root/dir1/leaf2.txt", + "!/META-INF/versions/9/root/dir2/leaf3.txt", + "!/META-INF/versions/9/root/dir2/leaf4.txt", + "!/META-INF/versions/9/root/dir3/leaf5.txt", + "!/META-INF/versions/9/root/dir3/leaf6.txt" + ); + Assert.assertEquals(contents, expectedContents); + + // open file as multi-release for version 10 + env.put("multi-release", "10"); + contents = doTestUri(env); + expectedContents = Set.of( + "!/root/dir1/leaf1.txt", + "!/root/dir1/leaf2.txt", + "!/META-INF/versions/9/root/dir2/leaf3.txt", + "!/META-INF/versions/9/root/dir2/leaf4.txt", + "!/META-INF/versions/10/root/dir3/leaf5.txt", + "!/META-INF/versions/10/root/dir3/leaf6.txt" + ); + Assert.assertEquals(contents, expectedContents); + } + + private Set<String> doTestUri(Map<String,String> env) throws IOException { + Set<String> contents; + try (FileSystem fs = FileSystems.newFileSystem(jarURI, env)) { + Path root = fs.getPath("root"); + int prefix = root.toUri().toString().indexOf('!'); + contents = Files.walk(root) + .filter(p -> !Files.isDirectory(p)) + .map(p -> p.toUri().toString().substring(prefix)) + .sorted() + .collect(Collectors.toSet()); + } + return contents; + } } diff --git a/test/jdk/jdk/security/jarsigner/JarWithOneNonDisabledDigestAlg.java b/test/jdk/jdk/security/jarsigner/JarWithOneNonDisabledDigestAlg.java new file mode 100644 index 0000000000000000000000000000000000000000..899500672ad4d56bc3be1f119f52b2b3bb7f5561 --- /dev/null +++ b/test/jdk/jdk/security/jarsigner/JarWithOneNonDisabledDigestAlg.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8278851 + * @summary Check that jar entry with at least one non-disabled digest + * algorithm in manifest is treated as signed + * @modules java.base/sun.security.tools.keytool + * @library /test/lib + * @build jdk.test.lib.util.JarUtils + * jdk.test.lib.security.SecurityUtils + * @run main/othervm JarWithOneNonDisabledDigestAlg + */ + +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.CodeSigner; +import java.security.KeyStore; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.zip.ZipFile; +import jdk.security.jarsigner.JarSigner; + +import jdk.test.lib.util.JarUtils; +import jdk.test.lib.security.SecurityUtils; + +public class JarWithOneNonDisabledDigestAlg { + + private static final String PASS = "changeit"; + private static final String TESTFILE1 = "testfile1"; + private static final String TESTFILE2 = "testfile2"; + + public static void main(String[] args) throws Exception { + SecurityUtils.removeFromDisabledAlgs("jdk.jar.disabledAlgorithms", + List.of("SHA1")); + Files.write(Path.of(TESTFILE1), TESTFILE1.getBytes()); + JarUtils.createJarFile(Path.of("unsigned.jar"), Path.of("."), + Path.of(TESTFILE1)); + + genkeypair("-alias SHA1 -sigalg SHA1withRSA"); + genkeypair("-alias SHA256 -sigalg SHA256withRSA"); + + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + try (FileInputStream fis = new FileInputStream("keystore")) { + ks.load(fis, PASS.toCharArray()); + } + + // Sign JAR twice with same signer but different digest algorithms + // so that each entry in manifest file contains two digest values. + signJarFile(ks, "SHA1", "MD5", "unsigned.jar", "signed.jar"); + signJarFile(ks, "SHA1", "SHA1", "signed.jar", "signed2.jar"); + checkThatJarIsSigned("signed2.jar", false); + + // add another file to the JAR + Files.write(Path.of(TESTFILE2), "testFile2".getBytes()); + JarUtils.updateJarFile(Path.of("signed2.jar"), Path.of("."), + Path.of(TESTFILE2)); + + // Sign again with different signer (SHA256) and SHA-1 digestalg. + // TESTFILE1 should have two signers and TESTFILE2 should have one + // signer. + signJarFile(ks, "SHA256", "SHA1", "signed2.jar", "multi-signed.jar"); + + checkThatJarIsSigned("multi-signed.jar", true); + } + + private static KeyStore.PrivateKeyEntry getEntry(KeyStore ks, String alias) + throws Exception { + + return (KeyStore.PrivateKeyEntry) + ks.getEntry(alias, + new KeyStore.PasswordProtection(PASS.toCharArray())); + } + + private static void genkeypair(String cmd) throws Exception { + cmd = "-genkeypair -keystore keystore -storepass " + PASS + + " -keypass " + PASS + " -keyalg rsa -dname CN=Duke " + cmd; + sun.security.tools.keytool.Main.main(cmd.split(" ")); + } + + private static void signJarFile(KeyStore ks, String alias, + String digestAlg, String inputFile, String outputFile) + throws Exception { + + JarSigner signer = new JarSigner.Builder(getEntry(ks, alias)) + .digestAlgorithm(digestAlg) + .signerName(alias) + .build(); + + try (ZipFile in = new ZipFile(inputFile); + FileOutputStream out = new FileOutputStream(outputFile)) { + signer.sign(in, out); + } + } + + private static void checkThatJarIsSigned(String jarFile, boolean multi) + throws Exception { + + try (JarFile jf = new JarFile(jarFile, true)) { + Enumeration<JarEntry> entries = jf.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (entry.isDirectory() || isSigningRelated(entry.getName())) { + continue; + } + InputStream is = jf.getInputStream(entry); + while (is.read() != -1); + CodeSigner[] signers = entry.getCodeSigners(); + if (signers == null) { + throw new Exception("JarEntry " + entry.getName() + + " is not signed"); + } else if (multi) { + if (entry.getName().equals(TESTFILE1) && + signers.length != 2) { + throw new Exception("Unexpected number of signers " + + "for " + entry.getName() + ": " + signers.length); + } else if (entry.getName().equals(TESTFILE2) && + signers.length != 1) { + throw new Exception("Unexpected number of signers " + + "for " + entry.getName() + ": " + signers.length); + } + } + } + } + } + + private static boolean isSigningRelated(String name) { + name = name.toUpperCase(Locale.ENGLISH); + if (!name.startsWith("META-INF/")) { + return false; + } + name = name.substring(9); + if (name.indexOf('/') != -1) { + return false; + } + return name.endsWith(".SF") + || name.endsWith(".DSA") + || name.endsWith(".RSA") + || name.endsWith(".EC") + || name.equals("MANIFEST.MF"); + } +} diff --git a/test/jdk/sun/net/www/B8185898.java b/test/jdk/sun/net/www/B8185898.java index a50c6f93c7e65cc1ebeeb6eec6cb0f0d30b78df4..cfa54e15a521c65e098671e620d71bd0b198c629 100644 --- a/test/jdk/sun/net/www/B8185898.java +++ b/test/jdk/sun/net/www/B8185898.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * 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 8185898 + * @bug 8185898 8163921 * @modules java.base/sun.net.www * @library /test/lib * @run main/othervm B8185898 @@ -143,32 +143,32 @@ public class B8185898 { // {{inputString1, expectedToString1, expectedPrint1}, {...}} String[][] strings = { {"HTTP/1.1 200 OK\r\n" - + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n\r\nfoooo", "pairs: {null: HTTP/1.1 200 OK}" - + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}" + + "{Accept: */*}" + "{Connection: keep-alive}" + "{Host: 127.0.0.1:12345}" + "{User-agent: Java/12}", - "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n\r\n"}, {"HTTP/1.1 200 OK\r\n" - + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n" + "X-Header:\r\n\r\n", "pairs: {null: HTTP/1.1 200 OK}" - + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}" + + "{Accept: */*}" + "{Connection: keep-alive}" + "{Host: 127.0.0.1:12345}" + "{User-agent: Java/12}" + "{X-Header: }", - "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n" diff --git a/test/jdk/sun/security/ec/OidInstance.java b/test/jdk/sun/security/ec/OidInstance.java new file mode 100644 index 0000000000000000000000000000000000000000..972c8e1026a5031588b41785fbc01d76adbaab79 --- /dev/null +++ b/test/jdk/sun/security/ec/OidInstance.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8279801 + * @summary EC KeyFactory and KeyPairGenerator do not have aliases for OID format + * @modules java.base/sun.security.util + * jdk.crypto.ec + */ + +import sun.security.util.KnownOIDs; + +import java.security.AlgorithmParameters; +import java.security.KeyFactory; +import java.security.KeyPairGenerator; + +public class OidInstance { + public static void main(String[] args) throws Exception { + String oid = KnownOIDs.EC.value(); + KeyFactory.getInstance(oid, "SunEC"); + KeyPairGenerator.getInstance(oid, "SunEC"); + AlgorithmParameters.getInstance(oid, "SunEC"); + } +} diff --git a/test/jdk/sun/security/krb5/auto/Context.java b/test/jdk/sun/security/krb5/auto/Context.java index ed8bab0e3d6aee79b117a94fbf7df8ad3a02da77..c18dbe9690fc8690fc5ba86929ddde7a61093016 100644 --- a/test/jdk/sun/security/krb5/auto/Context.java +++ b/test/jdk/sun/security/krb5/auto/Context.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -207,13 +207,26 @@ public class Context { */ public static Context fromUserKtab(Subject s, String user, String ktab, boolean storeKey) throws Exception { + return fromUserKtab(s, user, ktab, false, storeKey); + } + + /** + * Logins with username/keytab as a client. + */ + public static Context fromUserKtabAsClient( + String user, String ktab, boolean storeKey) throws Exception { + return fromUserKtab(new Subject(), user, ktab, true, storeKey); + } + + private static Context fromUserKtab(Subject s, + String user, String ktab, boolean isInitiator, boolean storeKey) throws Exception { Context out = new Context(); out.name = user; out.s = s; Krb5LoginModule krb5 = new Krb5LoginModule(); Map<String, String> map = new HashMap<>(); - map.put("isInitiator", "false"); + map.put("isInitiator", Boolean.toString(isInitiator)); map.put("doNotPrompt", "true"); map.put("useTicketCache", "false"); map.put("useKeyTab", "true"); diff --git a/test/jdk/sun/security/krb5/auto/HttpsCB.java b/test/jdk/sun/security/krb5/auto/HttpsCB.java new file mode 100644 index 0000000000000000000000000000000000000000..a65aa5d024117be0563b90dbd08022ce7dfe1998 --- /dev/null +++ b/test/jdk/sun/security/krb5/auto/HttpsCB.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8279842 + * @modules java.base/sun.security.util + * java.security.jgss/sun.security.jgss + * java.security.jgss/sun.security.jgss.krb5 + * java.security.jgss/sun.security.jgss.krb5.internal + * java.security.jgss/sun.security.krb5.internal:+open + * java.security.jgss/sun.security.krb5:+open + * java.security.jgss/sun.security.krb5.internal.ccache + * java.security.jgss/sun.security.krb5.internal.crypto + * java.security.jgss/sun.security.krb5.internal.ktab + * jdk.security.auth + * jdk.security.jgss + * jdk.httpserver + * @summary HTTPS Channel Binding support for Java GSS/Kerberos + * @library /test/lib + * @run main jdk.test.lib.FileInstaller TestHosts TestHosts + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=always HttpsCB true true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=never HttpsCB false true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=invalid HttpsCB false true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * HttpsCB false true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=domain:other.com HttpsCB false true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=domain:host.web.domain HttpsCB true true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=domain:*.web.domain HttpsCB true true + */ + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpPrincipal; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsExchange; +import com.sun.net.httpserver.HttpsServer; +import com.sun.security.auth.module.Krb5LoginModule; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.Proxy; +import java.net.Socket; +import java.net.URL; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Map; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509ExtendedTrustManager; +import javax.security.auth.Subject; + +import jdk.test.lib.Asserts; +import jdk.test.lib.net.SimpleSSLContext; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSManager; +import sun.security.jgss.GSSUtil; +import sun.security.jgss.krb5.internal.TlsChannelBindingImpl; +import sun.security.krb5.Config; +import sun.security.util.TlsChannelBinding; + +import java.util.Base64; +import java.util.concurrent.Callable; + +public class HttpsCB { + + final static String REALM_WEB = "WEB.DOMAIN"; + final static String KRB5_CONF = "web.conf"; + final static String KRB5_TAB = "web.ktab"; + + final static String WEB_USER = "web"; + final static char[] WEB_PASS = "webby".toCharArray(); + final static String WEB_HOST = "host.web.domain"; + final static String CONTENT = "Hello, World!"; + + static int webPort; + static URL cbtURL; + static URL normalURL; + + public static void main(String[] args) + throws Exception { + + boolean expectCBT = Boolean.parseBoolean(args[0]); + boolean expectNoCBT = Boolean.parseBoolean(args[1]); + + System.setProperty("sun.security.krb5.debug", "true"); + + KDC kdcw = KDC.create(REALM_WEB); + kdcw.addPrincipal(WEB_USER, WEB_PASS); + kdcw.addPrincipalRandKey("krbtgt/" + REALM_WEB); + kdcw.addPrincipalRandKey("HTTP/" + WEB_HOST); + + KDC.saveConfig(KRB5_CONF, kdcw, + "default_keytab_name = " + KRB5_TAB, + "[domain_realm]", + "", + ".web.domain="+REALM_WEB); + + System.setProperty("java.security.krb5.conf", KRB5_CONF); + Config.refresh(); + KDC.writeMultiKtab(KRB5_TAB, kdcw); + + // Write a customized JAAS conf file, so that any kinit cache + // will be ignored. + System.setProperty("java.security.auth.login.config", OneKDC.JAAS_CONF); + File f = new File(OneKDC.JAAS_CONF); + FileOutputStream fos = new FileOutputStream(f); + fos.write(( + "com.sun.security.jgss.krb5.initiate {\n" + + " com.sun.security.auth.module.Krb5LoginModule required;\n};\n" + ).getBytes()); + fos.close(); + + HttpServer h1 = httpd("Negotiate", + "HTTP/" + WEB_HOST + "@" + REALM_WEB, KRB5_TAB); + webPort = h1.getAddress().getPort(); + + cbtURL = new URL("https://" + WEB_HOST +":" + webPort + "/cbt"); + normalURL = new URL("https://" + WEB_HOST +":" + webPort + "/normal"); + + java.net.Authenticator.setDefault(new java.net.Authenticator() { + public PasswordAuthentication getPasswordAuthentication () { + return new PasswordAuthentication( + WEB_USER+"@"+REALM_WEB, WEB_PASS); + } + }); + + // Client-side SSLContext needs to ignore hostname mismatch + // and untrusted certificate. + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, new TrustManager[] { + new X509ExtendedTrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted(X509Certificate[] chain, + String authType, Socket socket) { } + public void checkServerTrusted(X509Certificate[] chain, + String authType, Socket socket) { } + public void checkClientTrusted(X509Certificate[] chain, + String authType, SSLEngine engine) { } + public void checkServerTrusted(X509Certificate[] chain, + String authType, SSLEngine engine) { } + public void checkClientTrusted(X509Certificate[] certs, + String authType) { } + public void checkServerTrusted(X509Certificate[] certs, + String authType) { } + } + }, null); + + Asserts.assertEQ(visit(sc, cbtURL), expectCBT); + Asserts.assertEQ(visit(sc, normalURL), expectNoCBT); + } + + static boolean visit(SSLContext sc, URL url) { + try { + HttpsURLConnection conn = (HttpsURLConnection) + url.openConnection(Proxy.NO_PROXY); + conn.setSSLSocketFactory(sc.getSocketFactory()); + BufferedReader reader; + reader = new BufferedReader(new InputStreamReader( + conn.getInputStream())); + return reader.readLine().equals(CONTENT); + } catch (IOException e) { + return false; + } + } + + static HttpServer httpd(String scheme, String principal, String ktab) + throws Exception { + MyHttpHandler h = new MyHttpHandler(); + HttpsServer server = HttpsServer.create(new InetSocketAddress(0), 0); + server.setHttpsConfigurator( + new HttpsConfigurator(new SimpleSSLContext().get())); + server.createContext("/", h).setAuthenticator( + new MyServerAuthenticator(scheme, principal, ktab)); + server.start(); + return server; + } + + static class MyHttpHandler implements HttpHandler { + public void handle(HttpExchange t) throws IOException { + t.sendResponseHeaders(200, 0); + t.getResponseBody().write(CONTENT.getBytes()); + t.close(); + } + } + + static class MyServerAuthenticator + extends com.sun.net.httpserver.Authenticator { + Subject s = new Subject(); + GSSManager m; + GSSCredential cred; + String scheme = null; + String reqHdr = "WWW-Authenticate"; + String respHdr = "Authorization"; + int err = HttpURLConnection.HTTP_UNAUTHORIZED; + + public MyServerAuthenticator(String scheme, + String principal, String ktab) throws Exception { + + this.scheme = scheme; + Krb5LoginModule krb5 = new Krb5LoginModule(); + Map<String, String> map = new HashMap<>(); + Map<String, Object> shared = new HashMap<>(); + + map.put("storeKey", "true"); + map.put("isInitiator", "false"); + map.put("useKeyTab", "true"); + map.put("keyTab", ktab); + map.put("principal", principal); + krb5.initialize(s, null, shared, map); + krb5.login(); + krb5.commit(); + m = GSSManager.getInstance(); + cred = Subject.callAs(s, new Callable<GSSCredential>() { + @Override + public GSSCredential call() throws Exception { + System.err.println("Creating GSSCredential"); + return m.createCredential( + null, + GSSCredential.INDEFINITE_LIFETIME, + MyServerAuthenticator.this.scheme + .equalsIgnoreCase("Negotiate") ? + GSSUtil.GSS_SPNEGO_MECH_OID : + GSSUtil.GSS_KRB5_MECH_OID, + GSSCredential.ACCEPT_ONLY); + } + }); + } + + @Override + public Result authenticate(HttpExchange exch) { + // The GSContext is stored in an HttpContext attribute named + // "GSSContext" and is created at the first request. + GSSContext c = null; + String auth = exch.getRequestHeaders().getFirst(respHdr); + try { + c = (GSSContext)exch.getHttpContext() + .getAttributes().get("GSSContext"); + if (auth == null) { // First request + Headers map = exch.getResponseHeaders(); + map.set (reqHdr, scheme); // Challenge! + c = Subject.callAs(s, () -> m.createContext(cred)); + // CBT is required for cbtURL + if (exch instanceof HttpsExchange sexch + && exch.getRequestURI().toString().equals("/cbt")) { + TlsChannelBinding b = TlsChannelBinding.create( + (X509Certificate) sexch.getSSLSession() + .getLocalCertificates()[0]); + c.setChannelBinding( + new TlsChannelBindingImpl(b.getData())); + } + exch.getHttpContext().getAttributes().put("GSSContext", c); + return new com.sun.net.httpserver.Authenticator.Retry(err); + } else { // Later requests + byte[] token = Base64.getMimeDecoder() + .decode(auth.split(" ")[1]); + token = c.acceptSecContext(token, 0, token.length); + Headers map = exch.getResponseHeaders(); + map.set (reqHdr, scheme + " " + Base64.getMimeEncoder() + .encodeToString(token).replaceAll("\\s", "")); + if (c.isEstablished()) { + return new com.sun.net.httpserver.Authenticator.Success( + new HttpPrincipal(c.getSrcName().toString(), "")); + } else { + return new com.sun.net.httpserver.Authenticator.Retry(err); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/test/jdk/sun/security/krb5/auto/IgnoreChannelBinding.java b/test/jdk/sun/security/krb5/auto/IgnoreChannelBinding.java index a9760dae9ad1bfdf92483fe5ca796628bd83f937..a393c299b70444261f2d507937024f0fd7d1b32c 100644 --- a/test/jdk/sun/security/krb5/auto/IgnoreChannelBinding.java +++ b/test/jdk/sun/security/krb5/auto/IgnoreChannelBinding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. * 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 6851973 8194486 + * @bug 6851973 8194486 8279520 * @summary ignore incoming channel binding if acceptor does not set one * @library /test/lib * @run main jdk.test.lib.FileInstaller TestHosts TestHosts @@ -33,6 +33,7 @@ import java.net.InetAddress; import org.ietf.jgss.ChannelBinding; import org.ietf.jgss.GSSException; +import org.ietf.jgss.Oid; import sun.security.jgss.GSSUtil; public class IgnoreChannelBinding { @@ -41,33 +42,38 @@ public class IgnoreChannelBinding { throws Exception { new OneKDC(null).writeJAASConf(); + test(GSSUtil.GSS_KRB5_MECH_OID); + test(GSSUtil.GSS_SPNEGO_MECH_OID); + } + + static void test(Oid mech) throws Exception { Context c = Context.fromJAAS("client"); Context s = Context.fromJAAS("server"); // All silent - c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); - s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + c.startAsClient(OneKDC.SERVER, mech); + s.startAsServer(mech); Context.handshake(c, s); // Initiator req, acceptor ignore - c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + c.startAsClient(OneKDC.SERVER, mech); c.x().setChannelBinding(new ChannelBinding( InetAddress.getByName("client.rabbit.hole"), InetAddress.getByName("host.rabbit.hole"), new byte[0] )); - s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + s.startAsServer(mech); Context.handshake(c, s); // Both req, and match - c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + c.startAsClient(OneKDC.SERVER, mech); c.x().setChannelBinding(new ChannelBinding( InetAddress.getByName("client.rabbit.hole"), InetAddress.getByName("host.rabbit.hole"), new byte[0] )); - s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + s.startAsServer(mech); s.x().setChannelBinding(new ChannelBinding( InetAddress.getByName("client.rabbit.hole"), InetAddress.getByName("host.rabbit.hole"), @@ -76,13 +82,13 @@ public class IgnoreChannelBinding { Context.handshake(c, s); // Both req, NOT match - c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + c.startAsClient(OneKDC.SERVER, mech); c.x().setChannelBinding(new ChannelBinding( InetAddress.getByName("client.rabbit.hole"), InetAddress.getByName("host.rabbit.hole"), new byte[0] )); - s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + s.startAsServer(mech); s.x().setChannelBinding(new ChannelBinding( InetAddress.getByName("client.rabbit.hole"), InetAddress.getByName("host.rabbit.hole"), @@ -96,8 +102,8 @@ public class IgnoreChannelBinding { } // Acceptor req, reject - c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); - s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + c.startAsClient(OneKDC.SERVER, mech); + s.startAsServer(mech); s.x().setChannelBinding(new ChannelBinding( InetAddress.getByName("client.rabbit.hole"), InetAddress.getByName("host.rabbit.hole"), diff --git a/test/jdk/sun/security/krb5/auto/tools/KtabSalt.java b/test/jdk/sun/security/krb5/auto/tools/KtabSalt.java new file mode 100644 index 0000000000000000000000000000000000000000..af504d5eab74cb81d12fdb5bda78c160ba04c539 --- /dev/null +++ b/test/jdk/sun/security/krb5/auto/tools/KtabSalt.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8279064 + * @summary New options for ktab to provide non-default salt + * @requires os.family == "windows" + * @library /test/lib + * @library /sun/security/krb5/auto + * @compile -XDignore.symbol.file KtabSalt.java + * @run main jdk.test.lib.FileInstaller ../TestHosts TestHosts + * @run main/othervm -Djdk.net.hosts.file=TestHosts KtabSalt + */ + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.Utils; +import jdk.test.lib.process.OutputAnalyzer; + +import javax.security.auth.login.LoginException; + +public class KtabSalt { + + public static void main(String[] args) throws Exception { + + OneKDC kdc = new OneKDC(null).writeJAASConf(); + kdc.addPrincipal("u1", "password".toCharArray(), + "this_is_my_salt", null); + + // Using password works + Context.fromUserPass("u1", "password".toCharArray(), true); + + // Using KDC's keytab works + kdc.writeKtab("ktab0"); + Context.fromUserKtabAsClient("u1", "ktab0", true); + + // Self-created keytab with default salt does not work + ktab("-a u1 password -k ktab1"); + Utils.runAndCheckException( + () -> Context.fromUserKtabAsClient("u1", "ktab1", true), + LoginException.class); + + // Self-creating keytab with specified salt works + ktab("-a u1 password -s this_is_my_salt -k ktab2"); + Context.fromUserKtabAsClient("u1", "ktab2", true); + + // Self-creating keytab with salt from KDC works + ktab("-a u1 password -f -k ktab3"); + Context.fromUserKtabAsClient("u1", "ktab3", true); + } + + static OutputAnalyzer ktab(String cmdLine) throws Exception { + String fullCmdLine = String.format( + "-J-Djava.security.krb5.conf=%s -J-Djdk.net.hosts.file=TestHosts %s", + OneKDC.KRB5_CONF, cmdLine); + return SecurityTools.ktab(fullCmdLine).shouldHaveExitValue(0); + } +} diff --git a/test/jdk/sun/security/krb5/tools/KtabCheck.java b/test/jdk/sun/security/krb5/tools/KtabCheck.java index 8924b70ec93cdc07c48f640bde2eb599590349f3..3b9c42ebff1a4e14b8ab1b2e2fc4f5e844258e0d 100644 --- a/test/jdk/sun/security/krb5/tools/KtabCheck.java +++ b/test/jdk/sun/security/krb5/tools/KtabCheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,31 +69,31 @@ public class KtabCheck { check(3,17,3,18,3,19,4,17,4,18,4,19,5,17,5,18,5,19); ktab("-a me mine -n 6 -append"); check(3,17,3,18,3,19,4,17,4,18,4,19,5,17,5,18,5,19,6,17,6,18,6,19); - ktab("-d me 3"); + ktab("-d me -f 3"); check(4,17,4,18,4,19,5,17,5,18,5,19,6,17,6,18,6,19); - ktab("-d me -e 17 6"); + ktab("-d me -f -e 17 6"); check(4,17,4,18,4,19,5,17,5,18,5,19,6,18,6,19); - ktab("-d me -e 19 6"); + ktab("-d me -f -e 19 6"); check(4,17,4,18,4,19,5,17,5,18,5,19,6,18); - ktab("-d me -e 17 5"); + ktab("-d me -f -e 17 5"); check(4,17,4,18,4,19,5,18,5,19,6,18); - ktab("-d me old"); + ktab("-d me -f old"); check(4,17,5,19,6,18); try { - ktab("-d me old"); + ktab("-d me -f old"); throw new Exception("Should fail"); } catch (Exception e) { // no-op } check(4,17,5,19,6,18); - ktab("-d me"); + ktab("-d me -f"); check(); } static void ktab(String s) throws Exception { File conf = new File(System.getProperty("test.src"), "onlythree.conf"); SecurityTools.ktab("-J-Djava.security.krb5.conf=" + conf - + " -k " + KEYTAB + " -f " + s).shouldHaveExitValue(0); + + " -k " + KEYTAB + " " + s).shouldHaveExitValue(0); } /** diff --git a/test/jdk/sun/security/pkcs11/Signature/LargeDSAKey.java b/test/jdk/sun/security/pkcs11/Signature/LargeDSAKey.java new file mode 100644 index 0000000000000000000000000000000000000000..a45a5ca47f544fefe11de334e9dede5dd2575c96 --- /dev/null +++ b/test/jdk/sun/security/pkcs11/Signature/LargeDSAKey.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.AlgorithmParameterGenerator; +import java.security.AlgorithmParameters; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.spec.DSAGenParameterSpec; +import java.security.spec.DSAParameterSpec; + +/* + * @test + * @bug 8271566 + * @library /test/lib .. + * @modules jdk.crypto.cryptoki + * @run main/othervm/timeout=30 LargeDSAKey + */ + +public final class LargeDSAKey extends PKCS11Test { + + private static final boolean enableDebug = false; + + private static final String knownText = + "Known text known text known text"; + + @Override + public void main(Provider p) throws Exception { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", p); + AlgorithmParameterGenerator dsaParGen = + AlgorithmParameterGenerator.getInstance("DSA"); + DSAGenParameterSpec dsaParGenSpec = + new DSAGenParameterSpec(2048, 256); + dsaParGen.init(dsaParGenSpec, new SecureRandom()); + AlgorithmParameters params = dsaParGen.generateParameters(); + DSAParameterSpec dsaParams = + params.getParameterSpec(DSAParameterSpec.class); + kpg.initialize(dsaParams); + KeyPair kp = kpg.generateKeyPair(); + doTestSignature(kp, p); + } + + private static void doTestSignature(KeyPair kp, Provider p) + throws Exception { + byte[] knownTextSig = null; + Signature s = Signature.getInstance("SHA1withDSA", p); + PrivateKey privKey = kp.getPrivate(); + PublicKey pubKey = kp.getPublic(); + if (enableDebug) { + System.out.println("Signature algorithm: " + s.getAlgorithm()); + System.out.println("Signature Provider: " + s.getProvider()); + System.out.println("Private key for signature: " + privKey); + System.out.println("Public key for signature: " + pubKey); + } + s.initSign(privKey); + s.update(knownText.getBytes()); + knownTextSig = s.sign(); + s.initVerify(pubKey); + s.update(knownText.getBytes()); + if (s.verify(knownTextSig) == false) { + throw new Exception("Could not verify signature"); + } + if (enableDebug) { + System.out.println("Signature verified"); + } + } + + public static void main(String[] args) throws Throwable { + main(new LargeDSAKey()); + System.out.println("TEST PASS - OK"); + } + +} diff --git a/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java b/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java index 07f07f788122dd3509cd9a0c3287830ff75bbc9a..2babc77e37a92ea55d3d5111bf66d216efa4d78d 100644 --- a/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java +++ b/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2021, Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java b/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java index da655c90a49ac07cb582548da42f864ce56972ed..a3a56c4feccb6bfb58464a33494fe8e91436c88a 100644 --- a/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java +++ b/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -462,7 +462,7 @@ public class KeytoolOpensslInteropTest { "pkcs12", "-in", "ksnormal", "-passin", "pass:changeit", "-info", "-nokeys", "-nocerts"); output1.shouldHaveExitValue(0) - .shouldContain("MAC: sha256, Iteration 10000") + .shouldContain("MAC:").shouldContain("sha256").shouldContain("Iteration 10000") .shouldContain("Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC," + " Iteration 10000, PRF hmacWithSHA256") .shouldContain("PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC," @@ -505,7 +505,7 @@ public class KeytoolOpensslInteropTest { "ksnewic", "-passin", "pass:changeit", "-info", "-nokeys", "-nocerts"); output1.shouldHaveExitValue(0) - .shouldContain("MAC: sha256, Iteration 5555") + .shouldContain("MAC:").shouldContain("sha256").shouldContain("Iteration 5555") .shouldContain("Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC," + " Iteration 7777, PRF hmacWithSHA256") .shouldContain("Shrouded Keybag: pbeWithSHA1And128BitRC4," diff --git a/test/jdk/sun/security/provider/PolicyParser/PrincipalExpansionError.java b/test/jdk/sun/security/provider/PolicyParser/PrincipalExpansionError.java index 8379fce402455bc376983285488c7fa09c386836..54eabc3a228737e5f1d3b6ae3ac1fbb7b0403eb4 100644 --- a/test/jdk/sun/security/provider/PolicyParser/PrincipalExpansionError.java +++ b/test/jdk/sun/security/provider/PolicyParser/PrincipalExpansionError.java @@ -110,7 +110,7 @@ public class PrincipalExpansionError { ("PrincipalExpansionError test failed (file not found)"); java.io.FileNotFoundException fnfe = (java.io.FileNotFoundException)e; - throw new SecurityException("PrincipalExpansionError" + + throw new SecurityException("PrincipalExpansionError " + "test failed (file not found)"); } else { // i don't know??? diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketShouldThrowSocketException.java b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketShouldThrowSocketException.java index 46cedd8f15ed868fe5b9f5773ff612efcfd43cec..410d0f46a88fed390ac6d9ceee019e0981e2ba1c 100644 --- a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketShouldThrowSocketException.java +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketShouldThrowSocketException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon and/or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/sun/security/ssl/X509KeyManager/NoGoodKey.java b/test/jdk/sun/security/ssl/X509KeyManager/NoGoodKey.java new file mode 100644 index 0000000000000000000000000000000000000000..71007010d8b83e13306a22f01c111bee7bd15552 --- /dev/null +++ b/test/jdk/sun/security/ssl/X509KeyManager/NoGoodKey.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8278560 + * @summary X509KeyManagerImpl::getAliases might return a good key with others + * @library /test/lib + * @modules java.base/sun.security.tools.keytool + * java.base/sun.security.util + * java.base/sun.security.x509 + */ +import jdk.test.lib.Asserts; +import sun.security.tools.keytool.CertAndKeyGen; +import sun.security.util.KnownOIDs; +import sun.security.util.ObjectIdentifier; +import sun.security.x509.CertificateExtensions; +import sun.security.x509.ExtendedKeyUsageExtension; +import sun.security.x509.X500Name; + +import java.io.*; +import java.security.*; +import java.security.cert.Certificate; +import java.util.Date; +import java.util.Vector; +import javax.net.ssl.*; + +public class NoGoodKey { + public static void main(String[] args) throws Exception { + + PrintStream oldErr = System.err; + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + CertificateExtensions exts = new CertificateExtensions(); + Vector<ObjectIdentifier> xku = new Vector<>(1); + xku.add(ObjectIdentifier.of(KnownOIDs.KP_TimeStamping)); + var ext = new ExtendedKeyUsageExtension(xku); + exts.set(ext.getId(), ext); + + KeyStore ks = KeyStore.getInstance("pkcs12"); + char[] pass = "password".toCharArray(); + ks.load(null, null); + + CertAndKeyGen ckg; + + // This is for the first keyType but wrong extendedKeyUsage + ckg = new CertAndKeyGen("EC", "SHA256withECDSA"); + ckg.generate("secp256r1"); + ks.setKeyEntry("a", ckg.getPrivateKey(), pass, new java.security.cert.Certificate[] + { ckg.getSelfCertificate(new X500Name("CN=user"), new Date(), 10000, exts) }); + + // This is for the 2nd keyType and is perfect + ckg = new CertAndKeyGen("RSA", "SHA256withRSA"); + ckg.generate(2048); + ks.setKeyEntry("b", ckg.getPrivateKey(), pass, new Certificate[] + { ckg.getSelfCertificate(new X500Name("CN=user"), 10000) }); + + try { + System.setProperty("javax.net.debug", "keymanager"); + System.setErr(new PrintStream(bout)); + var kmf = KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, pass); + var km = (X509ExtendedKeyManager) kmf.getKeyManagers()[0]; + + // b will be chosen anyway + Asserts.assertEQ(km.chooseClientAlias(new String[]{"EC", "RSA"}, null, null), "1.0.b"); + } finally { + System.setErr(oldErr); + } + + // make sure it's chosen as good matching key + String log = bout.toString(); + Asserts.assertFalse(log.contains("no good matching key found"), log); + } +} diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/CacertsLimit.java b/test/jdk/sun/security/ssl/X509TrustManagerImpl/CacertsLimit.java index e8a3871c5bb6819ce4d3e0e0fc6ff7791561d3e3..fc70b76735f7a25468038d2f1d3441f3b400e451 100644 --- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/CacertsLimit.java +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/CacertsLimit.java @@ -69,7 +69,7 @@ public class CacertsLimit { throw new Exception( "There are too many trusted CAs in cacerts. The " + "certificate_authorities extension cannot be used " + - "for TLS connections. Please rethink about the size" + + "for TLS connections. Please rethink about the size " + "of the cacerts, or have a release note for the " + "impacted behaviors"); } else if (sizeAccount > 0x4000) { diff --git a/test/jdk/sun/security/tools/keytool/TestSha1Usage.java b/test/jdk/sun/security/tools/keytool/TestSha1Usage.java new file mode 100644 index 0000000000000000000000000000000000000000..0cbece46e147d4ad26c65d829b42a908461ea170 --- /dev/null +++ b/test/jdk/sun/security/tools/keytool/TestSha1Usage.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8273236 + * @summary Test SHA1 usage SignedJAR + * @library /test/lib + */ + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestSha1Usage { + + static OutputAnalyzer kt(String cmd, String ks) throws Exception { + return SecurityTools.keytool("-storepass changeit " + cmd + + " -keystore " + ks); + } + + public static void main(String[] args) throws Exception { + + SecurityTools.keytool("-keystore ks -storepass changeit " + + "-genkeypair -keyalg rsa -alias ca -dname CN=CA " + + "-ext eku=codeSigning -sigalg SHA1withRSA") + .shouldContain("Warning:") + .shouldMatch("The generated certificate.*SHA1withRSA.*considered a security risk") + .shouldMatch("cannot be used to sign JARs") + .shouldHaveExitValue(0); + + kt("-genkeypair -keyalg rsa -alias e1 -dname CN=E1", "ks"); + kt("-certreq -alias e1 -file tmp.req", "ks"); + SecurityTools.keytool("-keystore ks -storepass changeit " + + "-gencert -alias ca -infile tmp.req -outfile tmp.cert") + .shouldContain("Warning:") + .shouldMatch("The issuer.*SHA1withRSA.*considered a security risk") + .shouldMatch("cannot be used to sign JARs") + .shouldHaveExitValue(0); + } +} diff --git a/test/jdk/sun/security/tools/keytool/fakegen/jdk.crypto.ec/sun/security/ec/ECKeyPairGenerator.java b/test/jdk/sun/security/tools/keytool/fakegen/jdk.crypto.ec/sun/security/ec/ECKeyPairGenerator.java index f688da1c63572cfdbeac5366d74d607799f8191c..50de12acf0671914eb90fbbcd42ee4ba42df51e8 100644 --- a/test/jdk/sun/security/tools/keytool/fakegen/jdk.crypto.ec/sun/security/ec/ECKeyPairGenerator.java +++ b/test/jdk/sun/security/tools/keytool/fakegen/jdk.crypto.ec/sun/security/ec/ECKeyPairGenerator.java @@ -71,7 +71,7 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi { break; default: throw new AssertionError("SunEC ECKeyPairGenerator" + - "has been patched. Key size " + keySize + + " has been patched. Key size " + keySize + " is not supported"); } ECParameterSpec ecParams = ECUtil.getECParameterSpec(null, keySize); diff --git a/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java index 6c16ec2d29369caf9c5de71afaba1b1b2c96c3dd..5dee1b863dc70fc2ddad99e3694f17ad6667b0d8 100644 --- a/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java +++ b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,21 +97,33 @@ public class JShellHeapDumpTest { launch(expectedMessage, Arrays.asList(toolArgs)); } - public static void printStackTraces(String file) throws IOException { + /* Returns false if the attempt should be retried. */ + public static boolean printStackTraces(String file, boolean allowRetry) throws IOException { try { String output = HprofReader.getStack(file, 0); // We only require JShellToolProvider to be in the output if we did the // short sleep. If we did not, the java process may not have executed far // enough along to even start the main thread. if (doSleep && !output.contains("JShellToolProvider")) { - throw new RuntimeException("'JShellToolProvider' missing from stdout/stderr"); + // This check will very rarely fail due to not be able to get the stack trace + // of the main thread do to it actively executing. See JDK-8269556. We retry once + // if that happens. This failure is so rare that this should be enough to make it + // extremely unlikely that we ever see this test fail again for this reason. + if (!allowRetry) { + throw new RuntimeException("'JShellToolProvider' missing from stdout/stderr"); + } else { + System.out.println("'JShellToolProvider' missing. Allow one retry."); + return true; // Allow one retry + } } } catch (Exception ex) { throw new RuntimeException("Test ERROR " + ex, ex); } + return false; } - public static void testHeapDump() throws IOException { + /* Returns false if the attempt should be retried. */ + public static boolean testHeapDump(boolean allowRetry) throws IOException { File hprofFile = new File("jhsdb.jmap.heap." + System.currentTimeMillis() + ".hprof"); if (hprofFile.exists()) { @@ -124,10 +136,12 @@ public class JShellHeapDumpTest { assertTrue(hprofFile.exists() && hprofFile.isFile(), "Could not create dump file " + hprofFile.getAbsolutePath()); - printStackTraces(hprofFile.getAbsolutePath()); + boolean retry = printStackTraces(hprofFile.getAbsolutePath(), allowRetry); System.out.println("hprof file size: " + hprofFile.length()); hprofFile.delete(); + + return retry; } public static void launchJshell() throws IOException { @@ -149,7 +163,7 @@ public class JShellHeapDumpTest { // Give jshell a chance to fully start up. This makes SA more stable for the jmap dump. try { if (doSleep) { - Thread.sleep(2000); + Thread.sleep(4000); } } catch (Exception e) { } @@ -166,7 +180,12 @@ public class JShellHeapDumpTest { } else if (args.length != 0) { throw new RuntimeException("Too many args: " + args.length); } - testHeapDump(); + + boolean retry = testHeapDump(true); + // In case of rare failure to find 'JShellToolProvider' in the output, allow one retry. + if (retry) { + testHeapDump(false); + } // The test throws RuntimeException on error. // IOException is thrown if Jshell can't start because of some bad diff --git a/test/jdk/sun/tools/jstatd/JstatdTest.java b/test/jdk/sun/tools/jstatd/JstatdTest.java index c603ed1096c471fbb77d99639dd230c222867eb0..9eb1ccb3748cb7d781b93ac058eeb99b46469652 100644 --- a/test/jdk/sun/tools/jstatd/JstatdTest.java +++ b/test/jdk/sun/tools/jstatd/JstatdTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ import jdk.test.lib.thread.ProcessThread; * <pre> * {@code * // start jstatd process - * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy + * jstatd -J-XX:+UsePerfData * * // run jps and verify its output * jps -J-XX:+UsePerfData hostname @@ -244,21 +244,16 @@ public final class JstatdTest { /** * Depending on test settings command line can look like: * - * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy - * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port - * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port -r rmiport - * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -n serverName - * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port -n serverName + * jstatd -J-XX:+UsePerfData + * jstatd -J-XX:+UsePerfData -p port + * jstatd -J-XX:+UsePerfData -p port -r rmiport + * jstatd -J-XX:+UsePerfData -n serverName + * jstatd -J-XX:+UsePerfData -p port -n serverName */ private String[] getJstatdCmd() throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstatd"); launcher.addVMArg("-XX:+UsePerfData"); - launcher.addVMArg("-Djava.security.manager=allow"); String testSrc = System.getProperty("test.src"); - File policy = new File(testSrc, "all.policy"); - assertTrue(policy.exists() && policy.isFile(), - "Security policy " + policy.getAbsolutePath() + " does not exist or not a file"); - launcher.addVMArg("-Djava.security.policy=" + policy.getAbsolutePath()); if (port != null) { addToolArg(launcher,"-p", port); } diff --git a/test/jdk/sun/tools/jstatd/all.policy b/test/jdk/sun/tools/jstatd/all.policy deleted file mode 100644 index e202e4e91b6c49790ef9b726e7cf9ef7eee18fb8..0000000000000000000000000000000000000000 --- a/test/jdk/sun/tools/jstatd/all.policy +++ /dev/null @@ -1,3 +0,0 @@ -grant { - permission java.security.AllPermission; -}; diff --git a/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java b/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c752ec4d63c2591263a2937f1b0d14fed2283553 --- /dev/null +++ b/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8275721 + * @modules jdk.localedata + * @summary Checks Chinese time zone names for `UTC` using CLDR are consistent + * @run testng/othervm -Djava.locale.providers=CLDR,COMPAT ChineseTimeZoneNameTest + * @run testng/othervm -Djava.locale.providers=CLDR ChineseTimeZoneNameTest + */ + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + +import static org.testng.Assert.assertEquals; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +@Test +public class ChineseTimeZoneNameTest { + + private static final Locale SIMPLIFIED_CHINESE = Locale.forLanguageTag("zh-Hans"); + private static final Locale TRADITIONAL_CHINESE = Locale.forLanguageTag("zh-Hant"); + private static final ZonedDateTime EPOCH_UTC = + ZonedDateTime.ofInstant(Instant.ofEpochSecond (0), ZoneId.of ("UTC")); + + @DataProvider(name="locales") + Object[][] data() { + return new Object[][] { + {Locale.CHINESE, SIMPLIFIED_CHINESE}, + {Locale.SIMPLIFIED_CHINESE, SIMPLIFIED_CHINESE}, + {Locale.forLanguageTag("zh-SG"), SIMPLIFIED_CHINESE}, + {Locale.forLanguageTag("zh-Hans-TW"), SIMPLIFIED_CHINESE}, + {Locale.forLanguageTag("zh-HK"), TRADITIONAL_CHINESE}, + {Locale.forLanguageTag("zh-MO"), TRADITIONAL_CHINESE}, + {Locale.TRADITIONAL_CHINESE, TRADITIONAL_CHINESE}, + {Locale.forLanguageTag("zh-Hant-CN"), TRADITIONAL_CHINESE}, + }; + } + + @Test(dataProvider="locales") + public void test_ChineseTimeZoneNames(Locale testLoc, Locale resourceLoc) { + assertEquals(DateTimeFormatter.ofPattern("z", testLoc).format(EPOCH_UTC), + DateTimeFormatter.ofPattern("z", resourceLoc).format(EPOCH_UTC)); + assertEquals(DateTimeFormatter.ofPattern("zzzz", testLoc).format(EPOCH_UTC), + DateTimeFormatter.ofPattern("zzzz", resourceLoc).format(EPOCH_UTC)); + } +} diff --git a/test/jdk/tools/jar/ReproducibleJar.java b/test/jdk/tools/jar/ReproducibleJar.java new file mode 100644 index 0000000000000000000000000000000000000000..ed5e2ed2ae3474af0dbde73cda80d9ba5bce2a53 --- /dev/null +++ b/test/jdk/tools/jar/ReproducibleJar.java @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 vm.bits == 64 + * @bug 8276766 + * @summary Test jar --date source date of entries and that jars are + * reproducible + * @modules jdk.jartool + * @run testng/othervm ReproducibleJar + */ + +import org.testng.Assert; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.testng.annotations.DataProvider; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.attribute.FileTime; +import java.util.Date; +import java.util.TimeZone; +import java.util.spi.ToolProvider; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.Instant; +import java.util.concurrent.TimeUnit; + +public class ReproducibleJar { + private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar") + .orElseThrow(() -> + new RuntimeException("jar tool not found") + ); + + // ZipEntry's mod date has 2 seconds precision: give extra time to + // allow for e.g. rounding/truncation and networked/samba drives. + private static final long PRECISION = 10000L; + + private static final TimeZone TZ = TimeZone.getDefault(); + private static final boolean DST = TZ.inDaylightTime(new Date()); + private static final String UNIX_2038_ROLLOVER_TIME = "2038-01-19T03:14:07Z"; + private static final Instant UNIX_2038_ROLLOVER = Instant.parse(UNIX_2038_ROLLOVER_TIME); + private static final File DIR_OUTER = new File("outer"); + private static final File DIR_INNER = new File(DIR_OUTER, "inner"); + private static final File FILE_INNER = new File(DIR_INNER, "foo.txt"); + private static final File JAR_FILE_SOURCE_DATE1 = new File("JarEntryTimeSourceDate1.jar"); + private static final File JAR_FILE_SOURCE_DATE2 = new File("JarEntryTimeSourceDate2.jar"); + + // Valid --date values for jar + @DataProvider + private Object[][] validSourceDates() { + return new Object[][]{ + {"1980-01-01T00:00:02+00:00"}, + {"1986-06-24T01:02:03+00:00"}, + {"2022-03-15T00:00:00+00:00"}, + {"2022-03-15T00:00:00+06:00"}, + {"2021-12-25T09:30:00-08:00[America/Los_Angeles]"}, + {"2021-12-31T23:59:59Z"}, + {"2024-06-08T14:24Z"}, + {"2026-09-24T16:26-05:00"}, + {"2038-11-26T06:06:06+00:00"}, + {"2098-02-18T00:00:00-08:00"}, + {"2099-12-31T23:59:59+00:00"} + }; + } + + // Invalid --date values for jar + @DataProvider + private Object[][] invalidSourceDates() { + return new Object[][]{ + {"1976-06-24T01:02:03+00:00"}, + {"1980-01-01T00:00:01+00:00"}, + {"2100-01-01T00:00:00+00:00"}, + {"2138-02-18T00:00:00-11:00"}, + {"2006-04-06T12:38:00"}, + {"2012-08-24T16"} + }; + } + + @BeforeMethod + public void runBefore() throws IOException { + runAfter(); + createOuterInnerDirs(); + } + + @AfterMethod + public void runAfter() { + cleanup(DIR_INNER); + cleanup(DIR_OUTER); + JAR_FILE_SOURCE_DATE1.delete(); + JAR_FILE_SOURCE_DATE2.delete(); + TimeZone.setDefault(TZ); + } + + /** + * Test jar tool with various valid --date <timestamps> + */ + @Test(dataProvider = "validSourceDates") + public void testValidSourceDate(String sourceDate) { + if (isInTransition()) return; + + // Test --date source date + Assert.assertEquals(JAR_TOOL.run(System.out, System.err, + "--create", + "--file", JAR_FILE_SOURCE_DATE1.getName(), + "--date", sourceDate, + DIR_OUTER.getName()), 0); + Assert.assertTrue(JAR_FILE_SOURCE_DATE1.exists()); + + // Extract JAR_FILE_SOURCE_DATE1 and check last modified values + Assert.assertEquals(JAR_TOOL.run(System.out, System.err, + "--extract", + "--file", JAR_FILE_SOURCE_DATE1.getName()), 0); + Assert.assertTrue(DIR_OUTER.exists()); + Assert.assertTrue(DIR_INNER.exists()); + Assert.assertTrue(FILE_INNER.exists()); + LocalDateTime expectedLdt = ZonedDateTime.parse(sourceDate, + DateTimeFormatter.ISO_DATE_TIME) + .withZoneSameInstant(ZoneOffset.UTC) + .toLocalDateTime(); + System.out.format("Checking jar entries local date time for --date %s, is %s%n", + sourceDate, expectedLdt); + long sourceDateEpochMillis = TimeUnit.MILLISECONDS.convert( + expectedLdt.toEpochSecond(ZoneId.systemDefault().getRules() + .getOffset(expectedLdt)), TimeUnit.SECONDS); + checkFileTime(DIR_OUTER.lastModified(), sourceDateEpochMillis); + checkFileTime(DIR_INNER.lastModified(), sourceDateEpochMillis); + checkFileTime(FILE_INNER.lastModified(), sourceDateEpochMillis); + } + + /** + * Test jar tool with various invalid --date <timestamps> + */ + @Test(dataProvider = "invalidSourceDates") + public void testInvalidSourceDate(String sourceDate) { + // Negative Tests --date out of range or wrong format source date + Assert.assertNotEquals(JAR_TOOL.run(System.out, System.err, + "--create", + "--file", JAR_FILE_SOURCE_DATE1.getName(), + "--date", sourceDate, + DIR_OUTER.getName()), 0); + } + + /** + * Test jar produces deterministic reproducible output + */ + @Test(dataProvider = "validSourceDates") + public void testJarsReproducible(String sourceDate) throws IOException { + // Test jars are reproducible across timezones + TimeZone tzAsia = TimeZone.getTimeZone("Asia/Shanghai"); + TimeZone tzLA = TimeZone.getTimeZone("America/Los_Angeles"); + TimeZone.setDefault(tzAsia); + Assert.assertEquals(JAR_TOOL.run(System.out, System.err, + "--create", + "--file", JAR_FILE_SOURCE_DATE1.getName(), + "--date", sourceDate, + DIR_OUTER.getName()), 0); + Assert.assertTrue(JAR_FILE_SOURCE_DATE1.exists()); + + try { + // Sleep 5 seconds to ensure jar timestamps might be different if they could be + Thread.sleep(5000); + } catch (InterruptedException ex) { + } + + TimeZone.setDefault(tzLA); + Assert.assertEquals(JAR_TOOL.run(System.out, System.err, + "--create", + "--file", JAR_FILE_SOURCE_DATE2.getName(), + "--date", sourceDate, + DIR_OUTER.getName()), 0); + Assert.assertTrue(JAR_FILE_SOURCE_DATE2.exists()); + + // Check jars are identical + Assert.assertEquals(Files.readAllBytes(JAR_FILE_SOURCE_DATE1.toPath()), + Files.readAllBytes(JAR_FILE_SOURCE_DATE2.toPath())); + } + + /** + * Create the standard directory structure used by the test: + * outer/ + * inner/ + * foo.txt + */ + static void createOuterInnerDirs() throws IOException { + Assert.assertTrue(DIR_OUTER.mkdir()); + Assert.assertTrue(DIR_INNER.mkdir()); + try (PrintWriter pw = new PrintWriter(FILE_INNER)) { + pw.println("hello, world"); + } + Assert.assertTrue(DIR_OUTER.exists()); + Assert.assertTrue(DIR_INNER.exists()); + Assert.assertTrue(FILE_INNER.exists()); + } + + /** + * Check the extracted and original millis since Epoch file times are + * within the zip precision time period. + */ + static void checkFileTime(long now, long original) { + if (isTimeSettingChanged()) { + return; + } + + if (Math.abs(now - original) > PRECISION) { + // If original time is after UNIX 2038 32bit rollover + // and the now time is exactly the rollover time, then assume + // running on a file system that only supports to 2038 (e.g.XFS) and pass test + if (FileTime.fromMillis(original).toInstant().isAfter(UNIX_2038_ROLLOVER) && + FileTime.fromMillis(now).toInstant().equals(UNIX_2038_ROLLOVER)) { + System.out.println("Checking file time after Unix 2038 rollover," + + " and extracted file time is " + UNIX_2038_ROLLOVER_TIME + ", " + + " Assuming restricted file system, pass file time check."); + } else { + throw new AssertionError("checkFileTime failed," + + " extracted to " + FileTime.fromMillis(now) + + ", expected to be close to " + FileTime.fromMillis(original)); + } + } + } + + /** + * Has the timezone or DST changed during the test? + */ + private static boolean isTimeSettingChanged() { + TimeZone currentTZ = TimeZone.getDefault(); + boolean currentDST = currentTZ.inDaylightTime(new Date()); + if (!currentTZ.equals(TZ) || currentDST != DST) { + System.out.println("Timezone or DST has changed during " + + "ReproducibleJar testcase execution. Test skipped"); + return true; + } else { + return false; + } + } + + /** + * Is the Zone currently within the transition change period? + */ + private static boolean isInTransition() { + var inTransition = false; + var date = new Date(); + var defZone = ZoneId.systemDefault(); + if (defZone.getRules().getTransition( + date.toInstant().atZone(defZone).toLocalDateTime()) != null) { + System.out.println("ReproducibleJar testcase being run during Zone offset transition. Test skipped."); + inTransition = true; + } + return inTransition; + } + + /** + * Remove the directory and its contents + */ + static void cleanup(File dir) { + File[] x = dir.listFiles(); + if (x != null) { + for (File f : x) { + f.delete(); + } + } + dir.delete(); + } +} diff --git a/test/jdk/tools/jimage/JImageNonAsciiNameTest.java b/test/jdk/tools/jimage/JImageNonAsciiNameTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4d1e5ba94ad82532e4b4c2cf291bf26ffe48eb1a --- /dev/null +++ b/test/jdk/tools/jimage/JImageNonAsciiNameTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.Path; +import jdk.internal.jimage.BasicImageReader; +import jdk.internal.jimage.ImageLocation; +import jdk.test.lib.compiler.InMemoryJavaCompiler; +import jdk.test.lib.util.JarBuilder; + +import tests.Helper; +import tests.JImageGenerator; +import tests.Result; + +/* + * @test + * @bug 8278185 + * @summary Test non-ASCII path in custom JRE + * @library ../lib + * /test/lib + * @modules java.base/jdk.internal.jimage + * jdk.jdeps/com.sun.tools.classfile + * jdk.jlink/jdk.tools.jimage + * @build tests.* + * @run main/othervm JImageNonAsciiNameTest + */ + +public class JImageNonAsciiNameTest { + private final static String moduleName = "A_module"; + private final static String packageName = "test.\u3042"; //non-ASCII + private final static String className = "A"; + private final static String fullName = packageName + "." + className; + private static Helper helper; + + public static void main(String[] args) throws Exception { + helper = Helper.newHelper(); + if (helper == null) { + System.err.println("Test not run"); + return; + } + + String source = + "package "+packageName+";" + + "public class "+className+" {" + + " public static void main(String[] args) {}" + + "}"; + String moduleInfo = "module " + moduleName + " {}"; + + // Using InMemory features to avoid generating non-ASCII name file + byte[] byteA = InMemoryJavaCompiler.compile(fullName, source); + byte[] byteModule = InMemoryJavaCompiler.compile( + "module-info", moduleInfo); + + Path jarDir = helper.getJarDir(); + JarBuilder jb = new JarBuilder( + jarDir.resolve(moduleName + ".jar").toString()); + jb.addEntry(fullName.replace(".","/") + ".class", byteA); + jb.addEntry("module-info.class", byteModule); + jb.build(); + + Path outDir = helper.createNewImageDir(moduleName); + + Result result = JImageGenerator.getJLinkTask() + .modulePath(helper.defaultModulePath()) + .output(outDir) + .addMods(moduleName) + .call(); + Path testImage = result.assertSuccess(); + + BasicImageReader bir = BasicImageReader.open( + testImage.resolve("lib").resolve("modules")); + ImageLocation loc = bir.findLocation(moduleName, + fullName.replace(".","/") + ".class"); + if (loc == null) { + throw new RuntimeException("Failed to find " + + fullName + " in module " +moduleName); + } + } +} diff --git a/test/jdk/tools/jmod/JmodTest.java b/test/jdk/tools/jmod/JmodTest.java index bfec68b748beb213766098842047d5aec8092401..78f1a89a759ccbd02bd4d3a089c6d4df86545b27 100644 --- a/test/jdk/tools/jmod/JmodTest.java +++ b/test/jdk/tools/jmod/JmodTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8142968 8166568 8166286 8170618 8168149 8240910 8276764 + * @bug 8142968 8166568 8166286 8170618 8168149 8240910 8276764 8276766 * @summary Basic test for jmod * @library /test/lib * @modules jdk.compiler @@ -183,13 +183,15 @@ public class JmodTest { @Test public void testList() throws IOException { String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); + Path jmod = MODS_DIR.resolve("foo.jmod"); + FileUtils.deleteFileIfExistsWithRetry(jmod); jmod("create", "--class-path", cp, - MODS_DIR.resolve("foo.jmod").toString()) + jmod.toString()) .assertSuccess(); jmod("list", - MODS_DIR.resolve("foo.jmod").toString()) + jmod.toString()) .assertSuccess() .resultChecker(r -> { // asserts dependent on the exact contents of foo @@ -211,6 +213,64 @@ public class JmodTest { }); } + @Test + public void testSourceDateReproducible() throws IOException { + String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString(); + Path jmod1 = MODS_DIR.resolve("foo1.jmod"); + Path jmod2 = MODS_DIR.resolve("foo2.jmod"); + Path jmod3 = MODS_DIR.resolve("foo3.jmod"); + FileUtils.deleteFileIfExistsWithRetry(jmod1); + FileUtils.deleteFileIfExistsWithRetry(jmod2); + FileUtils.deleteFileIfExistsWithRetry(jmod3); + + // Use source date of 15/03/2022 + String sourceDate = "2022-03-15T00:00:00+00:00"; + + jmod("create", + "--class-path", cp, + "--date", sourceDate, + jmod1.toString()) + .assertSuccess(); + + try { + // Sleep 5 seconds to ensure zip timestamps might be different if they could be + Thread.sleep(5000); + } catch(InterruptedException ex) {} + + jmod("create", + "--class-path", cp, + "--date", sourceDate, + jmod2.toString()) + .assertSuccess(); + + // Compare file byte content to see if they are identical + assertSameContent(jmod1, jmod2); + + // Use a date before 1980 and assert failure error + sourceDate = "1976-03-15T00:00:00+00:00"; + + jmod("create", + "--class-path", cp, + "--date", sourceDate, + jmod3.toString()) + .assertFailure() + .resultChecker(r -> { + assertContains(r.output, "is out of the valid range"); + }); + + // Use a date after 2099 and assert failure error + sourceDate = "2100-03-15T00:00:00+00:00"; + + jmod("create", + "--class-path", cp, + "--date", sourceDate, + jmod3.toString()) + .assertFailure() + .resultChecker(r -> { + assertContains(r.output, "is out of the valid range"); + }); + } + @Test public void testExtractCWD() throws IOException { Path cp = EXPLODED_DIR.resolve("foo").resolve("classes"); diff --git a/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/OverridableResourceTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/OverridableResourceTest.java index 55a3c22dc9a83a759fd5e13099550abd41989e78..7b00a60acf06ff1cbf35b9ff2b4c92b251ca45e4 100644 --- a/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/OverridableResourceTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/OverridableResourceTest.java @@ -136,16 +136,16 @@ public class OverridableResourceTest { } private void testCustomtWithSubstitution(String defaultName) throws IOException { - final List<String> resourceData = List.of("A", "[BB]", "C", "Foo", - "GoodbyeHello"); + final List<String> resourceData = List.of("A", "[BB]", "C", "Foo", "Foo", + "GoodbyeHello", "_B"); final Path customFile = createCustomFile("foo", resourceData); final Map<String, String> substitutionData = new HashMap(Map.of("B", - "Bar", "Foo", "B")); + "Bar", "Foo", "B", "_B", "JJ")); substitutionData.put("Hello", null); final List<String> expectedResourceData = List.of("A", "[BarBar]", "C", - "B", "Goodbye"); + "Bar", "Bar", "Goodbye", "JJ"); final List<String> actualResourceData = convertToStringList(saveToFile( new OverridableResource(defaultName) diff --git a/test/jdk/tools/jpackage/macosx/SigningPackageTest.java b/test/jdk/tools/jpackage/macosx/SigningPackageTest.java index 351e354357b725847594c0b83b6ac3dbd304ae07..2fa9e452cfba123e026d9f41ec21bd06c53a8719 100644 --- a/test/jdk/tools/jpackage/macosx/SigningPackageTest.java +++ b/test/jdk/tools/jpackage/macosx/SigningPackageTest.java @@ -76,9 +76,13 @@ public class SigningPackageTest { private static void verifyAppImageInDMG(JPackageCommand cmd) { MacHelper.withExplodedDmg(cmd, dmgImage -> { Path launcherPath = dmgImage.resolve(Path.of("Contents", "MacOS", cmd.name())); - SigningBase.verifyCodesign(launcherPath, true); - SigningBase.verifyCodesign(dmgImage, true); - SigningBase.verifySpctl(dmgImage, "exec"); + // We will be called with all folders in DMG since JDK-8263155, but + // we only need to verify app. + if (dmgImage.endsWith(cmd.name() + ".app")) { + SigningBase.verifyCodesign(launcherPath, true); + SigningBase.verifyCodesign(dmgImage, true); + SigningBase.verifySpctl(dmgImage, "exec"); + } }); } diff --git a/test/jdk/tools/launcher/VersionCheck.java b/test/jdk/tools/launcher/VersionCheck.java index 32d8db799ead208a1547055b4de833b5273f5ba3..8ce636c4af7cffe74792e84302f3b46688fb6625 100644 --- a/test/jdk/tools/launcher/VersionCheck.java +++ b/test/jdk/tools/launcher/VersionCheck.java @@ -23,7 +23,7 @@ /** * @test - * @bug 6545058 6611182 8016209 8139986 8162746 + * @bug 6545058 6611182 8016209 8139986 8162746 8278967 * @summary validate and test -version, -fullversion, and internal, as well as * sanity checks if a tool can be launched. * @modules jdk.compiler @@ -126,9 +126,12 @@ public class VersionCheck extends TestHelper { static String getVersion0(boolean allLines, String... argv) { TestHelper.TestResult tr = doExec(argv); StringBuilder out = new StringBuilder(); - // remove the HotSpot line + // remove the HotSpot line and security manager deprecation warnings for (String x : tr.testOutput) { - if (allLines || !x.matches(".*Client.*VM.*|.*Server.*VM.*")) { + if (allLines || !x.matches(".*Client.*VM.*|" + + ".*Server.*VM.*|" + + "WARNING:.*terminally.*deprecated.*|" + + "WARNING:.*System::setSecurityManager.*")) { out = out.append(x + "\n"); } } diff --git a/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java b/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java index 1cc649b2c272e2e6925883be7788dcf6f123518e..ca3d24aed70b77bd2f4b72ac0c2158e4f7e05bc7 100644 --- a/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java +++ b/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java @@ -139,9 +139,6 @@ public class CheckStylesheetClasses { "search-tag-desc-result", "search-tag-holder-result", "ui-autocomplete", "ui-autocomplete-category", "expanded"); - // snippet-related - removeAll(styleSheetNames, "bold", "highlighted", "italic"); - // very JDK specific styleSheetNames.remove("module-graph"); diff --git a/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/ClassCastExceptionTaglet.java b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/ClassCastExceptionTaglet.java new file mode 100644 index 0000000000000000000000000000000000000000..3d6cd7392c93a3a5f9f37d9bfb3779242e894503 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/ClassCastExceptionTaglet.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import javax.lang.model.element.Element; + +import com.sun.source.doctree.DocTree; +import jdk.javadoc.doclet.Taglet; + +public class ClassCastExceptionTaglet /* does NOT implement jdk.javadoc.doclet.Taglet */ { + + public Set<Taglet.Location> getAllowedLocations() { + return EnumSet.allOf(Taglet.Location.class); + } + + public boolean isInlineTag() { + return false; + } + + public String getName() { + return "ClassCastExceptionTaglet"; + } + + public String toString(List<? extends DocTree> tags, Element element) { + return ""; + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/ExceptionInInitializerErrorTaglet.java b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/ExceptionInInitializerErrorTaglet.java new file mode 100644 index 0000000000000000000000000000000000000000..22bd088bbe61821e73e87bd282d83d58093b08af --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/ExceptionInInitializerErrorTaglet.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import javax.lang.model.element.Element; + +import com.sun.source.doctree.DocTree; +import jdk.javadoc.doclet.Taglet; + +public class ExceptionInInitializerErrorTaglet implements Taglet { + + static { + if (true) { + throw new RuntimeException(); + } + } + + @Override + public Set<Taglet.Location> getAllowedLocations() { + return EnumSet.allOf(Taglet.Location.class); + } + + @Override + public boolean isInlineTag() { + return false; + } + + @Override + public String getName() { + return "ExceptionInInitializerErrorTaglet"; + } + + @Override + public String toString(List<? extends DocTree> tags, Element element) { + return ""; + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/InstantiationExceptionTaglet.java b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/InstantiationExceptionTaglet.java new file mode 100644 index 0000000000000000000000000000000000000000..b3995a033995757898ba8797f519abf78ff269b6 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/InstantiationExceptionTaglet.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import javax.lang.model.element.Element; + +import com.sun.source.doctree.DocTree; +import jdk.javadoc.doclet.Taglet; + +public abstract class InstantiationExceptionTaglet implements Taglet { + + @Override + public Set<Taglet.Location> getAllowedLocations() { + return EnumSet.allOf(Taglet.Location.class); + } + + @Override + public boolean isInlineTag() { + return false; + } + + @Override + public String getName() { + return "InstantiationExceptionTaglet"; + } + + @Override + public String toString(List<? extends DocTree> tags, Element element) { + return ""; + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/InvocationTargetExceptionTaglet.java b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/InvocationTargetExceptionTaglet.java new file mode 100644 index 0000000000000000000000000000000000000000..37faf0f2ab67c63410fb39d4d3984fff5e310616 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/InvocationTargetExceptionTaglet.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import javax.lang.model.element.Element; + +import com.sun.source.doctree.DocTree; +import jdk.javadoc.doclet.Taglet; + +public class InvocationTargetExceptionTaglet implements Taglet { + + public InvocationTargetExceptionTaglet() { + throw new RuntimeException(); + } + + @Override + public Set<Location> getAllowedLocations() { + return EnumSet.allOf(Location.class); + } + + @Override + public boolean isInlineTag() { + return false; + } + + @Override + public String getName() { + return "InvocationTargetExceptionTaglet"; + } + + @Override + public String toString(List<? extends DocTree> tags, Element element) { + return ""; + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/NoSuchMethodExceptionNoNullaryCtorTaglet.java b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/NoSuchMethodExceptionNoNullaryCtorTaglet.java new file mode 100644 index 0000000000000000000000000000000000000000..5f18ed460c041aa71854331bd16b3b843235f461 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/NoSuchMethodExceptionNoNullaryCtorTaglet.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import javax.lang.model.element.Element; + +import com.sun.source.doctree.DocTree; +import jdk.javadoc.doclet.Taglet; + +public class NoSuchMethodExceptionNoNullaryCtorTaglet implements Taglet { + + public NoSuchMethodExceptionNoNullaryCtorTaglet(Object obj) {} + + @Override + public Set<Location> getAllowedLocations() { + return EnumSet.allOf(Taglet.Location.class); + } + + @Override + public boolean isInlineTag() { + return false; + } + + @Override + public String getName() { + return "NoSuchMethodExceptionNoNullaryCtorTaglet"; + } + + @Override + public String toString(List<? extends DocTree> tags, Element element) { + return ""; + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/NoSuchMethodExceptionPrivateCtorTaglet.java b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/NoSuchMethodExceptionPrivateCtorTaglet.java new file mode 100644 index 0000000000000000000000000000000000000000..cbf71d6021e0a519193f3c8912bbbd0df1afe8db --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/NoSuchMethodExceptionPrivateCtorTaglet.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import javax.lang.model.element.Element; + +import com.sun.source.doctree.DocTree; +import jdk.javadoc.doclet.Taglet; + +public class NoSuchMethodExceptionPrivateCtorTaglet implements Taglet { + + private NoSuchMethodExceptionPrivateCtorTaglet() {} + + @Override + public Set<Taglet.Location> getAllowedLocations() { + return EnumSet.allOf(Taglet.Location.class); + } + + @Override + public boolean isInlineTag() { + return false; + } + + @Override + public String getName() { + return "NoSuchMethodExceptionPrivateCtorTaglet"; + } + + @Override + public String toString(List<? extends DocTree> tags, Element element) { + return ""; + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/TestRegistrationErrors.java b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/TestRegistrationErrors.java new file mode 100644 index 0000000000000000000000000000000000000000..8d2d95d6a639e055fbbbd1c8d00fefa65d5173a0 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testCustomTagletRegistration/TestRegistrationErrors.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8206181 + * @library ../../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build javadoc.tester.* * + * @run main TestRegistrationErrors + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +import javadoc.tester.JavadocTester; + +public class TestRegistrationErrors extends JavadocTester { + + public static void main(String... args) throws Exception { + TestRegistrationErrors tester = new TestRegistrationErrors(); + tester.runTests(); + } + + @Test + public void test() throws Exception { + try (Stream<Path> tagletClasses = findTagletClasses()) { + tagletClasses.forEach(p -> { + String tagletName = getTagletName(p); + javadoc("-d", "out-" + tagletName, // a directory per taglet + "-tagletpath", System.getProperty("test.classes"), + "-taglet", tagletName, + testSrc("TestRegistrationErrors.java")); // specify this file + checkExit(Exit.ERROR); + new OutputChecker(Output.OUT).checkUnique(Pattern.compile("thrown while trying to register Taglet")); + checkNoCrashes(); + }); + } + } + + private static Stream<Path> findTagletClasses() throws IOException { + var path = Path.of(System.getProperty("test.classes")); + return Files.find(path, Integer.MAX_VALUE, + (p, a) -> a.isRegularFile() && p.toString().endsWith("Taglet.class")); + } + + private static String getTagletName(Path tagletClass) { + Path fileName = tagletClass.getFileName(); + return fileName.toString().substring(0, fileName.toString().lastIndexOf('.')); + } + + protected void checkNoCrashes() { + checking("check crashes"); + Matcher matcher = Pattern.compile("\\s*at.*\\(.*\\.java:\\d+\\)") + .matcher(getOutput(Output.STDERR)); + if (!matcher.find()) { + passed(""); + } else { + failed("Looks like a stacktrace: " + matcher.group()); + } + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testDateOption/TestDateOption.java b/test/langtools/jdk/javadoc/doclet/testDateOption/TestDateOption.java new file mode 100644 index 0000000000000000000000000000000000000000..411e37efab93de7ecd5d065bbb39797032270928 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testDateOption/TestDateOption.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8272984 + * @summary javadoc support for SOURCE_DATE_EPOCH + * @library /tools/lib ../../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build toolbox.ToolBox javadoc.tester.* + * @run main TestDateOption + */ + +import java.nio.file.Path; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.Locale; + +import javadoc.tester.JavadocTester; +import toolbox.ToolBox; + +public class TestDateOption extends JavadocTester { + + /** + * The entry point of the test. + * + * @param args the array of command line arguments + * @throws Exception if the test fails + */ + public static void main(String... args) throws Exception { + TestDateOption tester = new TestDateOption(); + tester.runTests(m -> new Object[] { Path.of(m.getName()) }); + } + + ToolBox tb = new ToolBox(); + + @Test + public void testDateOption(Path base) throws Exception { + + ZonedDateTime zdt = ZonedDateTime.now(); // uses current date, time, timezone etc + // adjust the calendar to some date before the default used by javadoc (i.e. today/now) + // set a specific time, such as 10 to 3. (Rupert Brooke, Grantchester) + ZonedDateTime testDate = zdt.minusDays(100) + .withHour(14) + .withMinute(50) + .withSecond(0); + + out.println("Test Date: '" + testDate + "'"); + + Path srcDir = base.resolve("src"); + tb.writeJavaFiles(srcDir, """ + package p; + /** Comment. */ + public interface I { } + """); + Path outDir = base.resolve("out"); + + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "--date", testDate.toString(), + "p"); + checkExit(Exit.OK); + + int featureVersion = Runtime.version().feature(); + + // The following format is as used by javadoc; it is the historical format used by Date.toString() + DateTimeFormatter fmt = + DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy").withLocale(Locale.US); + String generatedByStamp = testDate.format(fmt); + String generatedBy = String.format("<!-- Generated by javadoc (%d) on %s -->", + featureVersion, generatedByStamp); + + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String dcCreatedStamp = testDate.format(dateFormat); + String dcCreated = String.format(""" + <meta name="dc.created" content="%s">""", + dcCreatedStamp); + + // check the timestamps in all generated HTML files + for (Path file : tb.findFiles(".html", outputDir)) { + checkOutput(outputDir.relativize(file).toString(), true, + generatedBy, + dcCreated); + } + } + + @Test + public void testBadDateOption(Path base) throws Exception { + Path srcDir = base.resolve("src"); + tb.writeJavaFiles(srcDir, """ + package p; + /** Comment. */ + public interface I { } + """); + Path outDir = base.resolve("out"); + + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "--date", "NOT A DATE", + "p"); + checkExit(Exit.CMDERR); + + checkOutput(Output.OUT, true, + "error: value for '--date' not valid: NOT A DATE"); + } + + @Test + public void testInvalidDateOption(Path base) throws Exception { + Path srcDir = base.resolve("src"); + tb.writeJavaFiles(srcDir, """ + package p; + /** Comment. */ + public interface I { } + """); + Path outDir = base.resolve("out"); + + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "--date", new Date(0).toInstant().toString(), + "p"); + checkExit(Exit.CMDERR); + + checkOutput(Output.OUT, true, + "error: value for '--date' out of range: 1970-01-01T00:00:00Z"); + } +} \ No newline at end of file diff --git a/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java b/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java new file mode 100644 index 0000000000000000000000000000000000000000..80e61d22d48637fc1f055811fd66959daf7ec23d --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8272944 + * @summary Use snippets in jdk.javadoc documentation + * @library /tools/lib ../../lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.javadoc/jdk.javadoc.internal.tool + * @build snippets.SnippetUtils toolbox.JavacTask toolbox.ToolBox javadoc.tester.* + * @run main TestDocletExample + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.spi.ToolProvider; +import java.util.stream.Stream; + +import snippets.SnippetUtils; +import toolbox.Task; +import toolbox.TestRunner; +import toolbox.ToolBox; + +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; + + +public class TestDocletExample extends TestRunner { + public static void main(String... args) throws Exception { + var t = new TestDocletExample(); + t.runTests(m -> new Object[] { Path.of(m.getName()) }); + } + + SnippetUtils snippets = new SnippetUtils("jdk.javadoc"); + ToolBox tb = new ToolBox(); + + TestDocletExample() { + super(System.out); + } + + @Test + public void testEntryPoint(Path base) throws Exception { + var docletPkg = snippets.getElements().getPackageElement("jdk.javadoc.doclet"); + var dc = snippets.getDocTrees().getDocCommentTree(docletPkg); + var entryPointSnippet = snippets.getSnippetById(dc, "entry-point"); + var entryPointCode = entryPointSnippet.getBody().getBody(); + var code = """ + class C { + %s { } + } + """.formatted(entryPointCode); + DiagnosticCollector<JavaFileObject> collector = new DiagnosticCollector<>(); + snippets.parse(code, null, collector); + var diags = collector.getDiagnostics(); + if (diags.isEmpty()) { + out.println("parsed entry point snippet"); + } else { + diags.forEach(out::println); + throw new Exception("parse failed"); + } + } + + @Test + public void testDocletExample(Path base) throws Exception { + + // get source code + var docletPkg = snippets.getElements().getPackageElement("jdk.javadoc.doclet"); + var dc = snippets.getDocTrees().getDocCommentTree(docletPkg); + var exampleSnippet = snippets.getSnippetById(dc, "Example.java"); + var exampleCode = exampleSnippet.getBody().getBody(); + + // compile it + Path src = base.resolve("src"); + Path classes = base.resolve("classes"); + Files.createDirectories(classes); + + tb.writeJavaFiles(src, exampleCode); + new toolbox.JavacTask(tb) + .outdir(classes) + .files(tb.findJavaFiles(src)) + .run(Task.Expect.SUCCESS) + .writeAll(); + + // get demo command + var cmdSnippet = snippets.getSnippetById(dc, "run-doclet"); + var cmd = cmdSnippet.getBody().getBody() + .replaceAll("\\s+//.*", "") // remove markup + .replaceAll("\\\\\n", " ") // join lines + .trim(); + out.println(cmd); + + tb.writeFile(src.resolve("overview.html"), + """ + <!doctype html> + <html><title>Overview + + Overview + + + """); + + var cmdWords = Stream.of(cmd.split("\\s+")) + .map(s -> s.replace("source-location", src.toString())) + .map(s -> s.replace("doclet-classes", classes.toString())) + .toList(); + var toolName = cmdWords.get(0); + var toolArgs = cmdWords.subList(1, cmdWords.size()); + + ToolProvider tool = ToolProvider.findFirst(toolName) + .orElseThrow(() -> new Exception("tool not found: " + toolName)); + int rc = tool.run(System.out, System.err, toolArgs.toArray(new String[0])); + if (rc != 0) { + throw new Exception("ecommand return code: " + rc); + } + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testGenericTypeLink/TestGenericTypeLink.java b/test/langtools/jdk/javadoc/doclet/testGenericTypeLink/TestGenericTypeLink.java index fbfbb5f39782849d97592a3e38e2a48d9379128c..1f0ea233288abb63f76f0b043cb51ba1aa71db61 100644 --- a/test/langtools/jdk/javadoc/doclet/testGenericTypeLink/TestGenericTypeLink.java +++ b/test/langtools/jdk/javadoc/doclet/testGenericTypeLink/TestGenericTypeLink.java @@ -166,18 +166,48 @@ public class TestGenericTypeLink extends JavadocTester { checkExit(Exit.ERROR); checkOutput("pkg2/B.html", true, """ -

        java.util.Foo<String> - Baz<Object> - #b(List<Integer>)
        """, +
        +
        + invalid @link +
        java.util.Foo<String>
        +
        + + \s +
        + invalid @linkplain +
        Baz<Object>
        +
        + + \s +
        + invalid @link +
        #b(List<Integer>)
        +
        +
        """, """
        See Also:
          -
        • java.util.List<Bar>
        • -
        • Baz<Object, String>
        • -
        • B#b(List<Baz>)
        • +
        • +
          + invalid @see +
          java.util.List<Bar>
          +
          +
        • +
        • +
          + invalid @see +
          Baz<Object, String>
          +
          +
        • +
        • +
          + invalid @see +
          B#b(List<Baz>)
          +
          +
        """); diff --git a/test/langtools/jdk/javadoc/doclet/testInherited/TestInherited.java b/test/langtools/jdk/javadoc/doclet/testInherited/TestInherited.java index 21391201a032c6ab86792bfe0b1338c43e294a9e..0806278b43d28d18951255915aa3189f52671191 100644 --- a/test/langtools/jdk/javadoc/doclet/testInherited/TestInherited.java +++ b/test/langtools/jdk/javadoc/doclet/testInherited/TestInherited.java @@ -69,11 +69,11 @@ public class TestInherited extends JavadocTester { checkExit(Exit.OK); checkOutput("BadParam.Base.html", true, """
        Parameters:
        -
        i - a < b
        +
        i - a invalid input: '<' b
        """); checkOutput("BadParam.Sub.html", true, """
        Parameters:
        -
        i - a < b
        +
        i - a invalid input: '<' b
        """); } @@ -101,11 +101,11 @@ public class TestInherited extends JavadocTester { checkExit(Exit.OK); checkOutput("BadReturn.Base.html", true, """
        Returns:
        -
        a < b
        +
        a invalid input: '<' b
        """); checkOutput("BadReturn.Sub.html", true, """
        Returns:
        -
        a < b
        +
        a invalid input: '<' b
        """); } @@ -147,16 +147,36 @@ public class TestInherited extends JavadocTester { src.resolve("BadReference.java").toString()); checkExit(Exit.OK); checkOutput("BadReference.Intf.html", true, """ -
        NonExistingClass
        +
        +
        + invalid @link +
        NonExistingClass
        +
        +
        """); checkOutput("BadReference.Impl1.html", true, """ -
        NonExistingClass
        +
        +
        + invalid @link +
        NonExistingClass
        +
        +
        """); checkOutput("BadReference.Impl2.html", true, """ -
        NonExistingClass
        +
        +
        + invalid @link +
        NonExistingClass
        +
        +
        """); checkOutput("BadReference.Impl3.html", true, """ -
        NonExistingClass
        +
        +
        + invalid @link +
        NonExistingClass
        +
        +
        """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java b/test/langtools/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java index 35a25e29bf26310e930c68274e9521ffbf55dbf9..b0b54bbdd6c2e11d638f59ba83221199bd46ecb9 100644 --- a/test/langtools/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java +++ b/test/langtools/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java @@ -85,6 +85,6 @@ public class TestNonInlineHtmlTagRemoval extends JavadocTester { checkOutput("Negative.html", true, """ -
        case1: A hanging < : xx<
        """); +
        case1: A hanging < : xxinvalid input: '<'
        """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testParamTaglet/TestParamTaglet.java b/test/langtools/jdk/javadoc/doclet/testParamTaglet/TestParamTaglet.java index b6b6a7a78d429e8f5f0e0541726db932fc0b2412..200af37a94838c370e7137b8ba535dd084c9c4b0 100644 --- a/test/langtools/jdk/javadoc/doclet/testParamTaglet/TestParamTaglet.java +++ b/test/langtools/jdk/javadoc/doclet/testParamTaglet/TestParamTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * 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 4802275 4967243 8026567 8239804 + * @bug 4802275 4967243 8026567 8239804 8234682 * @summary Make sure param tags are still printed even though they do not * match up with a real parameters. * Make sure inheritDoc cannot be used in an invalid param tag. @@ -48,22 +48,51 @@ public class TestParamTaglet extends JavadocTester { "-sourcepath", testSrc, "pkg"); checkExit(Exit.ERROR); - + checkOutput(Output.OUT, true, + "warning: no @param for param1", + "error: @param name not found", + "warning: @param \"b\" has already been specified"); checkOutput("pkg/C.html", true, - //Regular param tags. + // Regular param tags. """
        Parameters:
        param1 - testing 1 2 3.
        -
        param2 - testing 1 2 3.""", - //Param tags that don't match with any real parameters. +
        param2 - testing 1 2 3.
        + """, + // Param tags that don't match with any real parameters. + // {@inheritDoc} misuse does not cause doclet to throw exception. + // Param is printed with nothing inherited. """
        Parameters:
        p1 - testing 1 2 3.
        -
        p2 - testing 1 2 3.""", - //{@inherit} doc misuse does not cause doclet to throw exception. - // Param is printed with nothing inherited. - //XXX: in the future when Configuration is available during doc inheritence, - //print a warning for this mistake. - "inheritBug -"); +
        p2 - testing 1 2 3.
        +
        inheritBug -
        + """, + """ +
        Parameters:
        +
        i - an int
        +
        d - a double
        +
        b - a boolean
        +
        x - does not exist
        +
        x - duplicate
        +
        b - another duplicate
        + """, + """ +
        Type Parameters:
        +
        T2 - type 2
        +
        Parameters:
        +
        t1 - param 1
        +
        t3 - param 3
        + """); + checkOutput("pkg/C.Point.html", true, + """ +
        Record Components:
        +
        y - the y coordinate
        + """); + checkOutput("pkg/C.Nested.html", true, + """ +
        Type Parameters:
        +
        T1 - type 1
        + """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testParamTaglet/pkg/C.java b/test/langtools/jdk/javadoc/doclet/testParamTaglet/pkg/C.java index a50a8d7c6b9be35ed1e0838d7d49c557539a9ed8..ca5bda9eb6053c8ed2d3fd005aa59c113f3dfcc7 100644 --- a/test/langtools/jdk/javadoc/doclet/testParamTaglet/pkg/C.java +++ b/test/langtools/jdk/javadoc/doclet/testParamTaglet/pkg/C.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,42 @@ public class C extends Parent { * @param p2 testing 1 2 3. * @param inheritBug {@inheritDoc} */ + @Override public void nonMatchingParams(int param1, int param2) {} + /** + * Overriding method with missing/additional/duplicate param tags in non-declaration order. + * + * @param x does not exist + * @param b a boolean + * @param i an int + * @param x duplicate + * @param b another duplicate + */ + @Override + public void unorderedParams(int i, double d, boolean b) {} + + /** + * Generic method with mixed/missing param tags. + * + * @param t1 param 1 + * @param type 2 + * @param t3 param 3 + */ + public static void genericMethod(T1 t1, T2 t2, T3 t3) {} + + /** + * A partially documented point. + * + * @param y the y coordinate + */ + public static record Point(int x, int y) {} + + /** + * Generic class with missing param tags. + * + * @param type 1 + */ + public static class Nested {} + } diff --git a/test/langtools/jdk/javadoc/doclet/testParamTaglet/pkg/Parent.java b/test/langtools/jdk/javadoc/doclet/testParamTaglet/pkg/Parent.java index f0b380b19bd5ca634c8c690d0f37eadb0d8d8dcd..133c7038cb5ac37d8879f0b83031ac1f7664c498 100644 --- a/test/langtools/jdk/javadoc/doclet/testParamTaglet/pkg/Parent.java +++ b/test/langtools/jdk/javadoc/doclet/testParamTaglet/pkg/Parent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,4 +29,11 @@ public class Parent { * Just a dummy method that is here for inheritDoc testing purposes. */ public void nonMatchingParams(int param1, int param2) {} + + /** + * Base method with partially documented params. + * + * @param d a double + */ + public void unorderedParams(int i, double d, boolean b) {} } diff --git a/test/langtools/jdk/javadoc/doclet/testSeeTag/TestSeeTag.java b/test/langtools/jdk/javadoc/doclet/testSeeTag/TestSeeTag.java index f364cd47ef7c1ea33161bf393c2d1df3f848ea0a..b6661acae52b5d1275023d7aa408af9cceeb2cbd 100644 --- a/test/langtools/jdk/javadoc/doclet/testSeeTag/TestSeeTag.java +++ b/test/langtools/jdk/javadoc/doclet/testSeeTag/TestSeeTag.java @@ -100,7 +100,12 @@ public class TestSeeTag extends JavadocTester {
        • Object
        • -
        • Foo<String>
        • +
        • +
          + invalid @see +
          Foo<String>
          +
          +
        """); diff --git a/test/langtools/jdk/javadoc/doclet/testSnippetTag/SnippetTester.java b/test/langtools/jdk/javadoc/doclet/testSnippetTag/SnippetTester.java index ebe13149bb258907e6984263d531f62c9aa56f65..23d653be00f82f1b5f151170ce8225719f2d1ae9 100644 --- a/test/langtools/jdk/javadoc/doclet/testSnippetTag/SnippetTester.java +++ b/test/langtools/jdk/javadoc/doclet/testSnippetTag/SnippetTester.java @@ -26,9 +26,11 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.function.BiPredicate; import java.util.function.ObjIntConsumer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -122,4 +124,46 @@ public class SnippetTester extends JavadocTester {
        %s
        """.formatted(svgString, idString, langString, content); } + + // There's JavadocTester.diff(), but its semantics is different; hence we + // use this method. + protected void match(Path path1, Path path2, BiPredicate filter) throws IOException { + checking("diff " + path1 + ", " + path2); + try (var paths1 = Files.find(path1, Integer.MAX_VALUE, filter).sorted(); + var paths2 = Files.find(path2, Integer.MAX_VALUE, filter).sorted()) { + var it1 = paths1.iterator(); + var it2 = paths2.iterator(); + while (true) { + if (it1.hasNext() != it2.hasNext()) { + failed(it1.hasNext() ? it1.next() : it2.next(), "missing"); + return; + } + if (!it1.hasNext()) { + passed("match"); + return; + } + Path next1 = it1.next(); + Path next2 = it2.next(); + if (!path1.relativize(next1).equals(path2.relativize(next2))) { + // compare directory tree to see the difference + failed("mismatching names %s %s".formatted(next1, next2)); + return; + } + if (Files.isDirectory(next1) != Files.isDirectory(next2)) { + // it'd be surprising to ever see this + failed("mismatching types %s %s".formatted(next1, next2)); + return; + } + if (Files.isDirectory(next1)) { + continue; + } + if (Files.size(next1) != Files.size(next2) + || Files.mismatch(next1, next2) != -1L) { + failed("mismatching contents: diff %s %s".formatted(next1.toAbsolutePath(), + next2.toAbsolutePath())); + return; + } + } + } + } } diff --git a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java index 66d08933bc2dabea1fb0fa76355daa0153be6b05..8b5e6b4438dc01c1994094f0cbea193f83c6e683 100644 --- a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java +++ b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java @@ -603,6 +603,115 @@ First line // @highlight : testPositive(base, testCases); } + @Test + public void testPositiveInlineTagMarkup_FalseMarkup(Path base) throws Exception { + var testCases = List.of( + new TestCase( + """ + First line + // @formatter:off + Second Line + Third line + // @formatter:on + Fourth line + """, + """ + First line + // @formatter:off + Second Line + Third line + // @formatter:on + Fourth line + """), + new TestCase("showThis", + """ + First line + // @formatter:off + // @start region=showThis + Second Line + Third line + // @end region + // @formatter:on + Fourth line + """, + """ + Second Line + Third line + """) + ); + testPositive(base, testCases); + } + + @Test + public void testPositiveInlineTagMarkup_NextLineTwoTags(Path base) throws Exception { + var firstTag = new String[]{ + "@highlight string=firstWord", + "@replace string=secondWord replacement=replacedSecondWord", + "@link substring=firstWord target=java.lang.Object"}; + var secondTag = new String[]{ + "@highlight string=secondWord", + "@replace string=firstWord replacement=replacedFirstWord", + "@link substring=secondWord target=java.lang.Thread"}; + List testCases = new ArrayList<>(); + for (var f : firstTag) { + for (var s : secondTag) + for (var separator : List.of("", " ")) { + var t = new TestCase( + """ + first-line // %s %s%s: + firstWord secondWord thirdWord + """.formatted(f, s, separator), + """ + first-line + firstWord secondWord thirdWord // %s %s + """.formatted(f, s)); + testCases.add(t); + } + } + testEquivalence(base, testCases); + } + + record Snippet(String region, String snippet) { } + + private void testEquivalence(Path base, List testCases) throws IOException { + // group all the testcases in just two runs + Path out1 = base.resolve("out1"); + Path out2 = base.resolve("out2"); + run(base.resolve("src1"), out1, testCases.stream().map(t -> new Snippet(t.region(), t.input())).toList()); + run(base.resolve("src2"), out2, testCases.stream().map(t -> new Snippet(t.region(), t.expectedOutput())).toList()); + match(out1, out2, (p, a) -> /* p.toString().endsWith(".html") */ true); + } + + private void run(Path source, Path target, List snippets) throws IOException { + StringBuilder methods = new StringBuilder(); + forEachNumbered(snippets, (i, n) -> { + String r = i.region.isBlank() ? "" : "region=" + i.region; + var methodDef = """ + + /** + {@snippet %s: + %s}*/ + public void case%s() {} + """.formatted(r, i.snippet(), n); + methods.append(methodDef); + }); + var classDef = """ + public class A { + %s + } + """.formatted(methods.toString()); + Path src = Files.createDirectories(source); + tb.writeJavaFiles(src, classDef); + javadoc("-d", target.toString(), + "--limit-modules", "java.base", + "-quiet", "-nohelp", "-noindex", "-nonavbar", "-nosince", + "-notimestamp", "-notree", "-Xdoclint:none", + "-sourcepath", src.toString(), + src.resolve("A.java").toString()); + checkExit(Exit.OK); + checkNoCrashes(); + } + private static String link(boolean linkPlain, String targetReference, String content) diff --git a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetTag.java b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetTag.java index 07efd52829b7233190c850fb006dc0eefbc8c609..4b0dd06a2a246adc35c34432829beaf02cea552f 100644 --- a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetTag.java +++ b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetTag.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8266666 8275788 + * @bug 8266666 8275788 8276964 * @summary Implementation for snippets * @library /tools/lib ../../lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -1080,6 +1080,12 @@ public class TestSnippetTag extends SnippetTester { checkOutput(Output.OUT, true, """ A.java:4: error: File not found: %s""".formatted(fileName)); + checkOutput("pkg/A.html", true, """ +
        + invalid @snippet +
        File not found: text.txt
        +
        + """); checkNoCrashes(); } @@ -1155,6 +1161,12 @@ public class TestSnippetTag extends SnippetTester { checkOutput(Output.OUT, true, """ A.java:3: error: @snippet does not specify contents"""); + checkOutput("pkg/A.html", true, """ +
        + invalid @snippet +
        @snippet does not specify contents
        +
        + """); checkNoCrashes(); } @@ -1211,6 +1223,12 @@ public class TestSnippetTag extends SnippetTester { checkOutput(Output.OUT, true, """ A.java:3: error: @snippet specifies multiple external contents, which is ambiguous"""); + checkOutput("pkg/A.html", true, """ +
        + invalid @snippet +
        @snippet specifies multiple external contents, which is ambiguous
        +
        + """); checkNoCrashes(); } @@ -1863,15 +1881,15 @@ public class TestSnippetTag extends SnippetTester { for (String attrName : List.of("class", "file", "id", "lang", "region")) { // special case: valueless region attribute TestCase t = new TestCase(""" -{@snippet %s: - First line - Second line -} -""".formatted(attrName), -""" -: error: missing value for attribute "%s" -{@snippet %s: - ^""".formatted(attrName, attrName)); + {@snippet %s: + First line + Second line + } + """.formatted(attrName), + """ + : error: missing value for attribute "%s" + {@snippet %s: + ^""".formatted(attrName, attrName)); testCases.add(t); } @@ -1915,15 +1933,18 @@ public class TestSnippetTag extends SnippetTester { for (String quote : List.of("", "'", "\"")) for (String value : List.of("", " ")) { var t = new TestCase(""" -{@snippet region=%s%s%s: - First line - Second line -} -""".formatted(quote, value, quote), - """ -: error: illegal value for attribute "region": "%s" -{@snippet region=%s%s%s: - ^""".formatted(quote.isEmpty() ? "" : value, quote, value, quote)); // unquoted whitespace translates to empty string + {@snippet region=%s%s%s: + First line + Second line + } + """.formatted(quote, value, quote), + """ + : error: illegal value for attribute "region": "%s" + {@snippet region=%s%s%s: + ^ + """.formatted( + quote.isEmpty() ? "" : value, // unquoted whitespace translates to empty string + quote, value, quote)); testCases.add(t); } @@ -2015,6 +2036,17 @@ public class TestSnippetTag extends SnippetTester { checkOutput(Output.OUT, true, """ A.java:4: error: contents mismatch"""); + checkOutput("pkg/A.html", true, """ +
        + invalid @snippet +
        contents mismatch:
        +                        ----------------- inline -------------------
        +                        Hello, Snippet!
        +                        ----------------- external -----------------
        +                        Hello, Snippet!...more
        +                        
        +
        + """); checkNoCrashes(); } @@ -2055,6 +2087,19 @@ public class TestSnippetTag extends SnippetTester { checkOutput(Output.OUT, true, """ A.java:4: error: contents mismatch"""); + checkOutput("pkg/A.html", true, """ +
        + invalid @snippet +
        contents mismatch:
        +                        ----------------- inline -------------------
        +                        Hello, Snippet! ...more
        +
        +                        ----------------- external -----------------
        +                        Hello, Snippet!
        +
        +                        
        +
        + """); checkNoCrashes(); } @@ -2278,41 +2323,41 @@ public class TestSnippetTag extends SnippetTester { final var testCases = List.of( new TestCase(""" -{@snippet : -hello there // @highlight regex ="\t**" -}""", + {@snippet : + hello there // @highlight regex ="\t**" + }""", """ -error: snippet markup: invalid regex -hello there // @highlight regex ="\t**" - \t ^ -"""), + error: snippet markup: invalid regex + hello there // @highlight regex ="\t**" + \t ^ + """), new TestCase(""" -{@snippet : -hello there // @highlight regex ="\\t**" -}""", + {@snippet : + hello there // @highlight regex ="\\t**" + }""", """ -error: snippet markup: invalid regex -hello there // @highlight regex ="\\t**" - ^ -"""), + error: snippet markup: invalid regex + hello there // @highlight regex ="\\t**" + ^ + """), new TestCase(""" -{@snippet : -hello there // @highlight regex="\\.\\*\\+\\E" -}""", + {@snippet : + hello there // @highlight regex="\\.\\*\\+\\E" + }""", """ -error: snippet markup: invalid regex -hello there // @highlight regex="\\.\\*\\+\\E" - \s\s\s\s ^ -"""), // use \s to counteract shift introduced by \\ so as to visually align ^ right below E + error: snippet markup: invalid regex + hello there // @highlight regex="\\.\\*\\+\\E" + \s\s\s\s ^ + """), // use \s to counteract shift introduced by \\ so as to visually align ^ right below E new TestCase(""" -{@snippet : -hello there // @highlight type="italics" regex =" [" -}""", + {@snippet : + hello there // @highlight type="italics" regex =" [" + }""", """ -error: snippet markup: invalid regex -hello there // @highlight type="italics" regex =" [" - ^ -""") + error: snippet markup: invalid regex + hello there // @highlight type="italics" regex =" [" + ^ + """) ); List inputs = testCases.stream().map(s -> s.input).toList(); @@ -2342,6 +2387,12 @@ hello there // @highlight type="italics" regex =" [" src.resolve("A.java").toString()); checkExit(Exit.ERROR); checkOrder(Output.OUT, testCases.stream().map(TestCase::expectedError).toArray(String[]::new)); + checkOutput("A.html", true, """ +
        + invalid @snippet +
        invalid regex
        +
        + """); checkNoCrashes(); } @@ -2352,117 +2403,118 @@ hello there // @highlight type="italics" regex =" [" final var testCases = List.of( new TestCase(""" -{@snippet : - hello // @link -}""", + {@snippet : + hello // @link + }""", """ -error: snippet markup: missing attribute "target" - hello // @link - ^ + error: snippet markup: missing attribute "target" + hello // @link + ^ """), new TestCase(""" -{@snippet : - hello // @start -}""", + {@snippet : + hello // @start + }""", """ -error: snippet markup: missing attribute "region" - hello // @start - ^ + error: snippet markup: missing attribute "region" + hello // @start + ^ """), new TestCase(""" -{@snippet : - hello // @replace -}""", + {@snippet : + hello // @replace + }""", """ -error: snippet markup: missing attribute "replacement" - hello // @replace - ^ + error: snippet markup: missing attribute "replacement" + hello // @replace + ^ """), /* ---------------------- */ new TestCase(""" -{@snippet : - hello // @highlight regex=\\w+ substring=hello -}""", + {@snippet : + hello // @highlight regex=\\w+ substring=hello + }""", """ -error: snippet markup: attributes "substring" and "regex" used simultaneously - hello // @highlight regex=\\w+ substring=hello - ^ + error: snippet markup: attributes "substring" and "regex" used simultaneously + hello // @highlight regex=\\w+ substring=hello + ^ """), new TestCase(""" -{@snippet : - hello // @start region="x" name="here" -}""", + {@snippet : + hello // @start region="x" name="here" + }""", """ -error: snippet markup: unexpected attribute - hello // @start region="x" name="here" - ^ + error: snippet markup: unexpected attribute + hello // @start region="x" name="here" + ^ """), new TestCase(""" -{@snippet : - hello // @start region="" -}""", + {@snippet : + hello // @start region="" + }""", """ -error: snippet markup: invalid attribute value - hello // @start region="" - ^ + error: snippet markup: invalid attribute value + hello // @start region="" + ^ """), new TestCase(""" -{@snippet : - hello // @link target="Object#equals()" type=fluffy -}""", + {@snippet : + hello // @link target="Object#equals()" type=fluffy + }""", """ -error: snippet markup: invalid attribute value - hello // @link target="Object#equals()" type=fluffy - ^ + error: snippet markup: invalid attribute value + hello // @link target="Object#equals()" type=fluffy + ^ """), /* ---------------------- */ new TestCase(""" -{@snippet : - hello // @highlight substring=" -}""", + {@snippet : + hello + there // @highlight substring=" + }""", """ -error: snippet markup: unterminated attribute value - hello // @highlight substring=" - ^ + error: snippet markup: unterminated attribute value + there // @highlight substring=" + ^ """), new TestCase(""" -{@snippet : - hello // @start region="this" - world // @start region="this" - ! // @end -}""", + {@snippet : + hello // @start region="this" + world // @start region="this" + ! // @end + }""", """ -error: snippet markup: duplicated region - world // @start region="this" - ^ + error: snippet markup: duplicated region + world // @start region="this" + ^ """), new TestCase(""" -{@snippet : - hello // @end -}""", + {@snippet : + hello // @end + }""", """ -error: snippet markup: no region to end - hello // @end - ^ + error: snippet markup: no region to end + hello // @end + ^ """), new TestCase(""" -{@snippet : - hello // @start region=this -}""", + {@snippet : + hello // @start region=this + }""", """ -error: snippet markup: unpaired region - hello // @start region=this - ^ + error: snippet markup: unpaired region + hello // @start region=this + ^ """), new TestCase(""" -{@snippet : - hello // @highlight substring="hello" : -}""", + {@snippet : + hello // @highlight substring="hello" : + }""", """ -error: snippet markup: tag refers to non-existent lines - hello // @highlight substring="hello" : - ^ - """) + error: snippet markup: tag refers to non-existent lines + hello // @highlight substring="hello" : + ^ + """) ); List inputs = testCases.stream().map(s -> s.input).toList(); StringBuilder methods = new StringBuilder(); @@ -2492,6 +2544,12 @@ error: snippet markup: tag refers to non-existent lines checkExit(Exit.ERROR); // use the facility from JDK-8273154 when it becomes available checkOutput(Output.OUT, true, testCases.stream().map(TestCase::expectedError).toArray(String[]::new)); + checkOutput("A.html", true, """ +
        + invalid @snippet +
        missing attribute "target"
        +
        + """); checkNoCrashes(); } } diff --git a/test/langtools/jdk/javadoc/doclet/testXOption/TestXOption.java b/test/langtools/jdk/javadoc/doclet/testXOption/TestXOption.java index 7d00116fccc674b84d81d718e6740250906e8f60..3c65066419c1835945ab3ada7eb3cb7f7c440f75 100644 --- a/test/langtools/jdk/javadoc/doclet/testXOption/TestXOption.java +++ b/test/langtools/jdk/javadoc/doclet/testXOption/TestXOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,6 +98,7 @@ public class TestXOption extends JavadocTester { "-Xmaxwarns ", "-Xdocrootparent ", "-Xdoclint ", - "-Xdoclint:"); + "-Xdoclint:", + "--date "); } } diff --git a/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java b/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java index ff84f37c56bbb9db6d450e8d89b18248b907c3e3..1892fa2ebd5fdecff6d8d4c2a22e810d1f004d92 100644 --- a/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java +++ b/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java @@ -58,6 +58,7 @@ import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import javax.tools.StandardJavaFileManager; /** @@ -245,6 +246,7 @@ public abstract class JavadocTester { private boolean automaticCheckLinks = true; private boolean automaticCheckUniqueOUT = true; private boolean useStandardStreams = false; + private StandardJavaFileManager fileManager = null; /** The current subtest number. Incremented when checking(...) is called. */ private int numTestsRun = 0; @@ -371,9 +373,17 @@ public abstract class JavadocTester { StreamOutput sysErr = new StreamOutput(System.err, System::setErr); try { - exitCode = useStandardStreams - ? jdk.javadoc.internal.tool.Main.execute(args) // use sysOut, sysErr - : jdk.javadoc.internal.tool.Main.execute(args, outOut.pw); // default + jdk.javadoc.internal.tool.Main main = new jdk.javadoc.internal.tool.Main(); + if (useStandardStreams) { + // use sysOut, sysErr + } else { + // default: use single explicit stream + main.setStreams(outOut.pw, outOut.pw); + } + if (fileManager != null) { + main.setFileManager(fileManager); + } + exitCode = main.run(args).exitCode; } finally { outputMap.put(Output.STDOUT, sysOut.close()); outputMap.put(Output.STDERR, sysErr.close()); @@ -442,6 +452,15 @@ public abstract class JavadocTester { useStandardStreams = b; } + /** + * Sets the file manager to use for subsequent invocations of javadoc. + * If {@code null}, a default file manager will be created and used + * for each invocation. + */ + public void setFileManager(StandardJavaFileManager fm) { + fileManager = fm; + } + /** * The exit codes returned by the javadoc tool. * @see jdk.javadoc.internal.tool.Main.Result diff --git a/test/langtools/jdk/javadoc/lib/javadoc/tester/TestJavaFileManagerBuilder.java b/test/langtools/jdk/javadoc/lib/javadoc/tester/TestJavaFileManagerBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..69024a48cba45ce988e886bbe0f09ac166541f32 --- /dev/null +++ b/test/langtools/jdk/javadoc/lib/javadoc/tester/TestJavaFileManagerBuilder.java @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javadoc.tester; + +import javax.tools.FileObject; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.lang.reflect.UndeclaredThrowableException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.function.BiFunction; +import java.util.function.Predicate; + +/** + * A builder to create "test file managers" that can return "test file objects". + * All such objects can throw user-provided exceptions when specified methods + * are called. This is done by registering "handlers" to be associated with individual + * methods. + * + * The file objects that are returned as "test file objects" are filtered by a predicate + * on the file object. + * + * Note that "test file objects" passed as arguments to methods on the "test file manager" + * that created them are unwrapped, and replaced by the original file object. + * This ensures that the underlying file manager sees the underlying file objects, + * for cases when the identity of the file objects is important. + * However, it does mean that methods on file objects called internally by a + * file manager will not throw any user-provided exceptions. + * + * For now, the handlers for a file object are simply grouped by predicate and then by + * method, and the group of methods used for a "test file object" is determined by the + * first predicate that matches. + * An alternative, more expensive, implementation would be to group the handlers + * by method and predicate and then dynamically build the set of methods to be used for + * a file object by filtering the methods by their applicable predicate. + */ +public class TestJavaFileManagerBuilder { + private final StandardJavaFileManager fm; + private Map> fileManagerHandlers; + + private record FileObjectHandlers(Predicate filter, + Map> handlers) { } + private final List fileObjectHandlers; + + public TestJavaFileManagerBuilder(StandardJavaFileManager fm) { + this.fm = fm; + fileManagerHandlers = Collections.emptyMap(); + fileObjectHandlers = new ArrayList<>(); + } + + /** + * Provides functions to be called when given file manager methods are called. + * The function should either return an exception to be thrown, or {@code null} + * to indicate that no exception should be thrown. + * + *

        It is an error for any function to return a checked exception that is not + * declared by the method. This error will result in {@link UndeclaredThrowableException} + * being thrown when the method is called. + * + * @param handlers a map giving the function to be called before a file manager method is invoked + * + * @return this object + * + * @throws IllegalArgumentException if any key in the map of handlers is a method that is not + * declared in {@code JavaFileManager} + */ + public TestJavaFileManagerBuilder handle(Map> handlers) { + handlers.forEach((m, h) -> { + if (!JavaFileManager.class.isAssignableFrom(m.getDeclaringClass())) { + throw new IllegalArgumentException(("not a method on JavaFileManager: " + m)); + } + }); + + fileManagerHandlers = handlers; + return this; + } + + /** + * Provides functions to be called when given file object methods are called, + * for file objects that match a given predicate. + * The function should either return an exception to be thrown, or {@code null} + * to indicate that no exception should be thrown. + * + *

        It is an error for the function to return a checked exception that is not + * declared by the method. This error will result in {@link UndeclaredThrowableException} + * being thrown when the method is called. + * + *

        When subsequently finding the handlers to be used for a particular file object, the various + * predicates passed to this method will be tested in the order that they were registered. + * The handlers associated with the first matching predicate will be used. + * + * @apiNote Examples of predicates include: + *

          + *
        • using {@code .equals} or {@link JavaFileObject#isNameCompatible(String, JavaFileObject.Kind)} + * to match a specific file object, + *
        • using string or regular expression operations on the name or URI of the file object, + *
        • using {@code Path} operations on the file object's {@link StandardJavaFileManager#asPath(FileObject) path}. + *
        + * + * @param filter the predicate used to identify file objects for which the handlers are applicable + * @param handlers a map giving the function to be called before a file object method is invoked + * + * @return this object + * + * @throws IllegalArgumentException if any key in the map is a method that is not declared in a class + * that is assignable to {@code FileObject} + */ + public TestJavaFileManagerBuilder handle(Predicate filter, + Map> handlers) { + handlers.forEach((m, h) -> { + if (!FileObject.class.isAssignableFrom(m.getDeclaringClass())) { + throw new IllegalArgumentException(("not a method on FileObject: " + m)); + } + }); + + fileObjectHandlers.add(new FileObjectHandlers(filter, handlers)); + return this; + } + + /** + * {@return a file manager configured with the given handlers} + */ + public StandardJavaFileManager build() { + return (StandardJavaFileManager) Proxy.newProxyInstance(getClass().getClassLoader(), + new Class[] { StandardJavaFileManager.class }, + new JavaFileManager_InvocationHandler()); + } + + /** + * An invocation handler for "test file managers", which provides "test file objects" + * that may be configured to invoke functions to handle selected methods. + */ + private class JavaFileManager_InvocationHandler implements InvocationHandler { + // a cache of "real file object" -> "proxy file object". + Map cache = new WeakHashMap<>(); + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Object result = handleMethod(fm, method, unwrap(args)); + + if (result instanceof Iterable iterable) { + // All methods on StandardJavaFileManager that return Iterable for some T + // are such that T is one of ? extends [Java]FileObject, ? extends File, ? extends Path. + // If the result is empty, return it unchanged; otherwise check the first + // element to determine the type of the iterable, and if it is an iterable of + // file objects, post-process the result to use proxy file objects where appropriate. + // Note 1: this assumes that no methods return a mixture of FileObject and JavaFileObject. + // Note 2: all file objects returned by the standard file manager are instances of javaFileObject + Iterator iter = iterable.iterator(); + if (iter.hasNext() && iter.next() instanceof JavaFileObject) { + List list = new ArrayList<>(); + for (JavaFileObject jfo : (Iterable) iterable) { + list.add(wrap(jfo)); + } + return list; + } else { + return result; + } + } else if (result instanceof JavaFileObject jfo) { + return wrap(jfo); + } else { + return result; + } + } + + /** + * Returns a proxy file object that either calls handler functions for specific methods + * or delegates to an underlying file object. + * + * @param jfo the underlying file object + * + * @return the proxy file object + */ + private JavaFileObject wrap(JavaFileObject jfo) { + return fileObjectHandlers.stream() + .filter(e -> e.filter().test(jfo)) + .findFirst() + .map(e -> cache.computeIfAbsent(jfo, jfo_ -> createProxyFileObject(jfo_, e.handlers()))) + .orElse(jfo); + } + + /** + * Creates a proxy file object that either calls handler functions for specific methods + * or delegates to an underlying file object. + * + * @param jfo the underlying file object + * @param handlers the handlers + * + * @return the proxy file object + */ + private JavaFileObject createProxyFileObject(JavaFileObject jfo, + Map> handlers) { + return (JavaFileObject) Proxy.newProxyInstance(getClass().getClassLoader(), + new Class[] { JavaFileObject.class }, + new JavaFileObject_InvocationHandler(jfo, handlers)); + } + + /** + * {@return an array of objects with any proxy file objects replaced by their underlying + * delegate value} + * + * If there are no proxy objects in the array, the original array is returned. + * + * @param args the array of values + */ + private Object[] unwrap(Object[] args) { + if (!containsProxyFileObject(args)) { + return args; + } + + Object[] uArgs = new Object[args.length]; + for (int i = 0; i < args.length; i++) { + Object arg = args[i]; + uArgs[i] = (Proxy.isProxyClass(arg.getClass()) + && Proxy.getInvocationHandler(arg) instanceof JavaFileObject_InvocationHandler ih) + ? ih.jfo + : arg; + } + return uArgs; + } + + /** + * {@return {@code true} if an array of objects contains any proxy file objects, + * and {@code false} otherwise} + * + * @param args the array of objects + */ + private boolean containsProxyFileObject(Object[] args) { + for (Object arg : args) { + if (arg != null && Proxy.isProxyClass(arg.getClass()) + && Proxy.getInvocationHandler(arg) instanceof JavaFileObject_InvocationHandler) { + return true; + } + } + return false; + } + + private Object handleMethod(JavaFileManager fm, Method method, Object[] args) throws Throwable { + var handler = fileManagerHandlers.get(method); + if (handler != null) { + Throwable t = handler.apply(fm, args); + if (t != null) { + throw t; + } + } + + return method.invoke(fm, args); + } + } + + /** + * An invocation handler for "test file objects" which can be configured to call functions + * to handle the calls for individual methods. + * It is expected that a common use case is to throw an exception in circumstances that + * would otherwise be hard to create. + */ + private record JavaFileObject_InvocationHandler(JavaFileObject jfo, + Map> handlers) + implements InvocationHandler { + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return handleMethod(jfo, method, args); + } + + private Object handleMethod(JavaFileObject jfo, Method method, Object[] args) throws Throwable { + var handler = handlers.get(method); + if (handler != null) { + Throwable t = handler.apply(jfo, args); + if (t != null) { + throw t; + } + } + return method.invoke(jfo, args); + } + } +} diff --git a/test/langtools/jdk/javadoc/testTFMBuilder/TestTFMBuilder.java b/test/langtools/jdk/javadoc/testTFMBuilder/TestTFMBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..1e892df80bbb6264b7846082dc23db30a1317b0e --- /dev/null +++ b/test/langtools/jdk/javadoc/testTFMBuilder/TestTFMBuilder.java @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8276892 + * @summary Provide a way to emulate exceptional situations in FileManager when using JavadocTester + * @library /tools/lib/ ../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build toolbox.ToolBox javadoc.tester.* + * @run main TestTFMBuilder + */ + + +import javax.tools.DocumentationTool; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javadoc.tester.JavadocTester; +import javadoc.tester.TestJavaFileManagerBuilder; +import toolbox.ToolBox; + +/** + * Tests the {@link TestJavaFileManagerBuilder} class. + * + */ +// The use of the contraction TFMBuilder is deliberate, to avoid using +// the confusing but otherwise logical name of TestTestJavaFileManagerBuilder +public class TestTFMBuilder extends JavadocTester { + public static class TestException extends RuntimeException { + TestException(JavaFileObject jfo) { + this(jfo.getName()); + } + + TestException(String msg) { + super(msg); + } + } + + public static void main(String... args) throws Exception { + TestTFMBuilder tester = new TestTFMBuilder(); + tester.setup().runTests(m -> new Object[] { Path.of(m.getName()) }); + } + + private Path srcDir = Path.of("src"); + private Class thisClass = TestTFMBuilder.class; + private String thisClassName = thisClass.getName(); + + TestTFMBuilder setup() throws Exception { + ToolBox tb = new ToolBox(); + tb.writeJavaFiles(srcDir, """ + package p; + /** Dummy class, to be read by javadoc. {@snippet file="C.properties" } */ + public class C { + private C() { } + }"""); + tb.writeFile(srcDir.resolve("p").resolve("snippet-files").resolve("C.properties"), """ + dummy content + """); + return this; + } + + StandardJavaFileManager getFileManager() { + DocumentationTool dt = ToolProvider.getSystemDocumentationTool(); + return dt.getStandardFileManager(null, null, null); + } + + @Test + public void testSimpleDirectUse(Path base) throws Exception { + try (StandardJavaFileManager fm = getFileManager()) { + fm.setLocation(StandardLocation.SOURCE_PATH, List.of(Path.of(testSrc).toFile())); + + // obtain a normal file object from the standard file manager + JavaFileObject someFileObject = + fm.getJavaFileForInput(StandardLocation.SOURCE_PATH, thisClassName, JavaFileObject.Kind.SOURCE); + + // build a file manager that throws an exception when someFileObject is read + StandardJavaFileManager tfm = new TestJavaFileManagerBuilder(fm) + .handle(jfo -> jfo.equals(someFileObject), + Map.of(JavaFileObject.class.getMethod("getCharContent", boolean.class), + (fo, args) -> new TestException(fo.getName()))) + .build(); + + // access the "same" file object via the test file manager + JavaFileObject someTestFileObject = + tfm.getJavaFileForInput(StandardLocation.SOURCE_PATH, thisClassName, JavaFileObject.Kind.SOURCE); + + checking("non-trapped method"); + try { + out.println("someTestFileObject.getName: " + someTestFileObject.getName()); + passed("method returned normally, as expected"); + } catch (Throwable t) { + failed("method threw unexpected exception: " + t); + } + + checking ("trapped method"); + try { + someTestFileObject.getCharContent(true); + failed("method returned normally, without throwing an exception"); + } catch (TestException e) { + String expect = someFileObject.getName(); + String found = e.getMessage(); + if (found.equals(expect)) { + passed("method threw exception as expected"); + } else { + failed("method throw exception with unexpected message:\n" + + "expected: " + expect + "\n" + + " found: " + found); + } + } catch (Throwable t) { + failed("method threw unexpected exception: " + t); + } + } + } + + @Test + public void testFileManagerAccess(Path base) throws Exception { + try (StandardJavaFileManager fm = getFileManager()) { + + // build a file manager that throws an exception when a specific source file is accessed + Method getFileForInput_method = JavaFileManager.class.getMethod("getFileForInput", + JavaFileManager.Location.class, String.class, String.class); + StandardJavaFileManager tfm = new TestJavaFileManagerBuilder(fm) + .handle(Map.of(getFileForInput_method, + (fm_, args) -> { + var relativeName = (String) args[2]; + return (relativeName.endsWith("C.properties")) + ? new TestException("getFileForInput: " + Arrays.asList(args)) + : null; + })) + .build(); + + try { + setFileManager(tfm); + javadoc("-d", base.resolve("api").toString(), + "-sourcepath", srcDir.toString(), + "p"); + checkExit((Exit.ERROR)); // Ideally, this should be ABNORMAL, but right now, the doclet has no way to indicate that + checkOutput(Output.OUT, true, + """ + error: An internal exception has occurred. + \t(##EXC##: getFileForInput: [SOURCE_PATH, p, snippet-files/C.properties]) + 1 error""" + .replace("##EXC##", TestException.class.getName())); + } finally { + setFileManager(null); + } + } + } + + @Test + public void testFileObjectRead(Path base) throws Exception { + try (StandardJavaFileManager fm = getFileManager()) { + + // build a file manager that throws an exception when any *.java is read + StandardJavaFileManager tfm = new TestJavaFileManagerBuilder(fm) + .handle(jfo -> jfo.getName().endsWith(".java"), + Map.of(JavaFileObject.class.getMethod("getCharContent", boolean.class), + (fo, args) -> new TestException(fo.getName()))) + .build(); + + try { + setFileManager(tfm); + javadoc("-d", base.resolve("api").toString(), + "-sourcepath", srcDir.toString(), + "p"); + checkExit((Exit.ABNORMAL)); + checkOutput(Output.OUT, true, + """ + Loading source files for package p... + error: fatal error encountered: ##EXC##: ##FILE## + error: Please file a bug against the javadoc tool via the Java bug reporting page""" + .replace("##EXC##", TestException.class.getName()) + .replace("##FILE##", srcDir.resolve("p").resolve("C.java").toString())); + } finally { + setFileManager(null); + } + } + } + + @Test + public void testFileObjectWrite(Path base) throws Exception { + try (StandardJavaFileManager fm = getFileManager()) { + Path outDir = base.resolve("api"); + + // build a file manager that throws an exception when any file is generated + StandardJavaFileManager tfm = new TestJavaFileManagerBuilder(fm) + .handle(jfo -> fm.asPath(jfo).startsWith(outDir.toAbsolutePath()) + && jfo.getName().endsWith(".html"), + Map.of(JavaFileObject.class.getMethod("openOutputStream"), + (fo, args) -> new TestException(fo.getName()))) + .build(); + + try { + setFileManager(tfm); + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "p"); + checkExit((Exit.ERROR)); + checkOutput(Output.OUT, true, + """ + Generating ##FILE##... + error: An internal exception has occurred. + \t(##EXC##: ##FILE##) + 1 error""" + .replace("##EXC##", TestException.class.getName()) + .replace("##FILE##", outDir.resolve("p").resolve("C.html").toString())); + } finally { + setFileManager(null); + } + } + } +} \ No newline at end of file diff --git a/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java b/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java index 8b8202e9fe5c9243e5d434fd0ec492cd240cc404..6d49b54559e9bb48fb7cde33c318144cddc48a66 100644 --- a/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java +++ b/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * 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 8274211 + * @bug 8274211 8278538 * @summary Test man page that options are documented * @modules jdk.javadoc/jdk.javadoc.internal.tool:+open * @run main CheckManPageOptions @@ -54,22 +54,19 @@ import java.util.stream.Collectors; * of the javadoc man page against the set of options declared in the source code. */ public class CheckManPageOptions { + static class SourceDirNotFound extends Error { } + public static void main(String... args) throws Exception { - new CheckManPageOptions().run(args); + try { + new CheckManPageOptions().run(args); + } catch (SourceDirNotFound e) { + System.err.println("NOTE: Cannot find src directory; test skipped"); + } } static final PrintStream out = System.err; - // FIXME: JDK-8274295, JDK-8266666, JDK-8278077 - List MISSING_IN_MAN_PAGE = List.of( - "--add-script", - "--legal-notices", - "--link-modularity-mismatch", - "--link-platform-properties", - "--no-platform-links", - "--since", - "--since-label", - "--snippet-path"); + List MISSING_IN_MAN_PAGE = List.of("--date"); void run(String... args) throws Exception { var file = args.length == 0 ? findDefaultFile() : Path.of(args[0]); @@ -152,7 +149,7 @@ public class CheckManPageOptions { } dir = dir.getParent(); } - throw new IllegalStateException("cannot find root dir"); + throw new SourceDirNotFound(); } List getToolOptions() throws Error { diff --git a/test/langtools/jdk/javadoc/tool/doclint/DocLintReferencesTest.java b/test/langtools/jdk/javadoc/tool/doclint/DocLintReferencesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ee316135e3730d6c15a4c9128467140a14307a68 --- /dev/null +++ b/test/langtools/jdk/javadoc/tool/doclint/DocLintReferencesTest.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8280688 + * @summary doclint reference checks withstand warning suppression + * @library /tools/lib ../../lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.javadoc/jdk.javadoc.internal.api + * jdk.javadoc/jdk.javadoc.internal.tool + * @build toolbox.JavacTask toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox + * @run main DocLintReferencesTest + */ + +import toolbox.JavacTask; +import toolbox.JavadocTask; +import toolbox.Task; +import toolbox.TestRunner; +import toolbox.ToolBox; + +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Combo test for how javac and javadoc handle {@code @see MODULE/TYPE} + * for different combinations of MODULE and TYPE, with and without + * {@code @SuppressWarnings("doclint") }. + * + * Generally, in javac, references to unknown elements are reported + * as suppressible warnings if the module is not resolved in the module graph. + * Otherwise, in both javac and javadoc, any issues with references + * are reported as errors. + * + * This allows references to other modules to appear in documentation comments + * without causing a hard error if the modules are not available at compile-time. + */ +public class DocLintReferencesTest extends TestRunner { + + public static void main(String... args) throws Exception { + DocLintReferencesTest t = new DocLintReferencesTest(); + t.runTests(); + } + + DocLintReferencesTest() { + super(System.err); + } + + private final ToolBox tb = new ToolBox(); + + enum SuppressKind { NO, YES } + enum ModuleKind { NONE, BAD, NOT_FOUND, GOOD } + enum TypeKind { NONE, BAD, NOT_FOUND, GOOD } + + @Test + public void comboTest () { + for (SuppressKind sk : SuppressKind.values() ) { + for (ModuleKind mk : ModuleKind.values() ) { + for (TypeKind tk: TypeKind.values() ) { + if (mk == ModuleKind.NONE && tk == TypeKind.NONE) { + continue; + } + + try { + test(sk, mk, tk); + } catch (Throwable e) { + error("Exception " + e); + } + } + } + } + } + + void test(SuppressKind sk, ModuleKind mk, TypeKind tk) throws Exception { + out.println(); + out.println("*** Test SuppressKind:" + sk + " ModuleKind: " + mk + " TypeKind: " + tk); + Path base = Path.of(sk + "-" + mk + "-" + tk); + + String sw = switch (sk) { + case NO -> ""; + case YES -> "@SuppressWarnings(\"doclint\")"; + }; + String m = switch (mk) { + case NONE -> ""; + case BAD -> "bad-name/"; + case NOT_FOUND -> "not.found/"; + case GOOD -> "java.base/"; + }; + String t = switch (tk) { + case NONE -> ""; + case BAD -> "bad-name"; + case NOT_FOUND -> "java.lang.NotFound"; + case GOOD -> "java.lang.Object"; + }; + + Path src = base.resolve("src"); + tb.writeJavaFiles(src, """ + package p; + /** + * Comment. + * @see #M##T# + */ + #SW# + public class C { + private C() { } + } + """ + .replace("#M#", m) + .replace("#T#", t) + .replace("#SW#", sw)); + + testJavac(sk, mk, tk, base, src); + testJavadoc(sk, mk, tk, base, src); + } + + void testJavac(SuppressKind sk, ModuleKind mk, TypeKind tk, Path base, Path src) throws Exception { + Files.createDirectories(base.resolve("classes")); + + out.println("javac:"); + try { + String s = predictOutput(sk, mk, tk, false); + Task.Expect e = s.isEmpty() ? Task.Expect.SUCCESS : Task.Expect.FAIL; + + String o = new JavacTask(tb) + .outdir(base.resolve("classes")) + .options("-Xdoclint:all/protected", "-Werror") + .files(tb.findJavaFiles(src)) + .run(e) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutput(s, o); + + } catch (Throwable t) { + error("Error: " + t); + } + out.println(); + } + + void testJavadoc(SuppressKind sk, ModuleKind mk, TypeKind tk, Path base, Path src) throws Exception { + Files.createDirectories(base.resolve("api")); + + out.println("javadoc:"); + try { + String s = predictOutput(sk, mk, tk, true); + Task.Expect e = s.isEmpty() ? Task.Expect.SUCCESS : Task.Expect.FAIL; + + String o = new JavadocTask(tb) + .outdir(base.resolve("api")) + .options("-Xdoclint", "-Werror", "-quiet", "-sourcepath", src.toString(), "p") + .run(e) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutput(s, o); + + } catch (Throwable t) { + error("Error: " + t); + } + out.println(); + } + + private static final String ERROR_UNEXPECTED_TEXT = "error: unexpected text"; + private static final String ERROR_REFERENCE_NOT_FOUND = "error: reference not found"; + private static final String WARNING_MODULE_FOR_REFERENCE_NOT_FOUND = "warning: module for reference not found: not.found"; + private static final String EMPTY = ""; + + /** + * Returns the expected diagnostic, if any, based on the parameters of the test case. + * + * The "interesting" cases are those for which the module name is not found, + * in which case an error for "reference not found" is reduced to warning, + * which may be suppressed. + * + * @param sk whether @SuppressWarnings is present of not + * @param mk the kind of module in the reference + * @param tk the kind of class or interface name in the reference + * @param strict whether all "not found" references are errors, + * or just warnings if the module name is not found + * @return a diagnostic string, or an empty string if no diagnostic should be generated + */ + String predictOutput(SuppressKind sk, ModuleKind mk, TypeKind tk, boolean strict) { + return switch (mk) { + case NONE -> switch(tk) { + case NONE -> throw new Error("should not happen"); // filtered out in combo loops + case BAD -> ERROR_UNEXPECTED_TEXT; + case NOT_FOUND -> ERROR_REFERENCE_NOT_FOUND; + case GOOD -> EMPTY; + }; + + case BAD -> ERROR_UNEXPECTED_TEXT; + + case NOT_FOUND -> switch(tk) { + case BAD -> ERROR_UNEXPECTED_TEXT; + case NONE, NOT_FOUND, GOOD -> strict + ? ERROR_REFERENCE_NOT_FOUND + : sk == SuppressKind.YES + ? EMPTY + : WARNING_MODULE_FOR_REFERENCE_NOT_FOUND; + }; + + case GOOD -> switch(tk) { + case BAD -> ERROR_UNEXPECTED_TEXT; + case NOT_FOUND -> ERROR_REFERENCE_NOT_FOUND; + case GOOD, NONE -> EMPTY; + }; + }; + } + + /** + * Checks the actual output against the expected string, generated by {@code predictError}. + * If the expected string is empty, the output should be empty. + * If the expected string is not empty, it should be present in the output. + * + * @param expect the expected string + * @param found the output + */ + void checkOutput(String expect, String found) { + if (expect.isEmpty()) { + if (found.isEmpty()) { + out.println("Output OK"); + } else { + error("unexpected output"); + } + } else { + if (found.contains(expect)) { + out.println("Output OK"); + } else { + error("expected output not found: " + expect); + } + } + + } +} diff --git a/test/langtools/jdk/jshell/CommandCompletionTest.java b/test/langtools/jdk/jshell/CommandCompletionTest.java index 27746a748b9dff441b9f893726c6c66ead04e007..3a5eb1a46a7ce46d258315ce60b69b9e08793bfe 100644 --- a/test/langtools/jdk/jshell/CommandCompletionTest.java +++ b/test/langtools/jdk/jshell/CommandCompletionTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8144095 8164825 8169818 8153402 8165405 8177079 8178013 8167554 8166232 + * @bug 8144095 8164825 8169818 8153402 8165405 8177079 8178013 8167554 8166232 8277328 * @summary Test Command Completion * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -331,6 +331,22 @@ public class CommandCompletionTest extends ReplToolTesting { ); } + @Test + public void testClassPathWithSpace() throws IOException { + Compiler compiler = new Compiler(); + Path outDir = compiler.getPath("testClassPathWithSpace"); + Path dirWithSpace = Files.createDirectories(outDir.resolve("dir with space")); + Files.createDirectories(dirWithSpace.resolve("nested with space")); + String[] pathArray = new String[] {"dir\\ with\\ space/"}; + String[] pathArray2 = new String[] {"nested\\ with\\ space/"}; + testNoStartUp( + a -> assertCompletion(a, "/env -class-path " + outDir + "/|", false, pathArray), + a -> assertCompletion(a, "/env -class-path " + outDir + "/dir|", false, pathArray), + a -> assertCompletion(a, "/env -class-path " + outDir + "/dir\\ with|", false, pathArray), + a -> assertCompletion(a, "/env -class-path " + outDir + "/dir\\ with\\ space/|", false, pathArray2) + ); + } + @Test public void testUserHome() throws IOException { List completions; @@ -338,8 +354,9 @@ public class CommandCompletionTest extends ReplToolTesting { String selectedFile; try (Stream content = Files.list(home)) { selectedFile = content.filter(CLASSPATH_FILTER) + .filter(file -> file.getFileName().toString().contains(" ")) .findAny() - .map(file -> file.getFileName().toString()) + .map(file -> file.getFileName().toString().replace(" ", "\\ ")) .orElse(null); } if (selectedFile == null) { @@ -347,8 +364,8 @@ public class CommandCompletionTest extends ReplToolTesting { } try (Stream content = Files.list(home)) { completions = content.filter(CLASSPATH_FILTER) - .filter(file -> file.getFileName().toString().startsWith(selectedFile)) - .map(file -> file.getFileName().toString() + (Files.isDirectory(file) ? "/" : "")) + .filter(file -> file.getFileName().toString().startsWith(selectedFile.replace("\\ ", " "))) + .map(file -> file.getFileName().toString().replace(" ", "\\ ") + (Files.isDirectory(file) ? "/" : "")) .sorted() .collect(Collectors.toList()); } diff --git a/test/langtools/tools/javac/8203436/T8203436a.java b/test/langtools/tools/javac/8203436/T8203436a.java index eba0f827c8626865731c112d0afe3c49947d6213..db47a62e67270f3c32266f387139d8eca0f2b838 100644 --- a/test/langtools/tools/javac/8203436/T8203436a.java +++ b/test/langtools/tools/javac/8203436/T8203436a.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8203436 + * @bug 8203436 8211004 * @summary javac should fail early when emitting illegal signature attributes * @compile/fail/ref=T8203436a.out -XDrawDiagnostics T8203436a.java */ diff --git a/test/langtools/tools/javac/8203436/T8203436a.out b/test/langtools/tools/javac/8203436/T8203436a.out index 71b7e6871664f548e7286f68023f60a65c889c40..e076a20a2a84512a63797b05be11af2d1f0c8e89 100644 --- a/test/langtools/tools/javac/8203436/T8203436a.out +++ b/test/langtools/tools/javac/8203436/T8203436a.out @@ -1,2 +1,2 @@ -- compiler.err.cannot.generate.class: compiler.misc.anonymous.class: T8203436a$1, (compiler.misc.illegal.signature: compiler.misc.anonymous.class: T8203436a$1, compiler.misc.type.captureof: 1, ?) +T8203436a.java:12:7: compiler.err.enclosing.class.type.non.denotable: T8203436a 1 error diff --git a/test/langtools/tools/javac/8203436/T8203436b.out b/test/langtools/tools/javac/8203436/T8203436b.out index 979e550fff6c85603ccbff2bc79c0d6ee163770f..48eb947cecf1e5c8f8f91edf73ee018734e18df6 100644 --- a/test/langtools/tools/javac/8203436/T8203436b.out +++ b/test/langtools/tools/javac/8203436/T8203436b.out @@ -1,2 +1,2 @@ -- compiler.err.cannot.generate.class: compiler.misc.anonymous.class: T8203436b$1, (compiler.misc.illegal.signature: compiler.misc.anonymous.class: T8203436b$1, java.lang.Object&T8203436b.A&T8203436b.B) +T8203436b.java:17:10: compiler.err.enclosing.class.type.non.denotable: T8203436b 1 error diff --git a/test/langtools/tools/javac/StringConcat/StringAppendEvaluatesInOrder.java b/test/langtools/tools/javac/StringConcat/StringAppendEvaluatesInOrder.java new file mode 100644 index 0000000000000000000000000000000000000000..b2bd47acde0003a541d1c4edd2e25ab1995da3c5 --- /dev/null +++ b/test/langtools/tools/javac/StringConcat/StringAppendEvaluatesInOrder.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021, Google LLC. All rights reserved. + * 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 8273914 + * @summary Indy string concat changes order of operations + * + * @clean * + * @compile -XDstringConcat=indy StringAppendEvaluatesInOrder.java + * @run main StringAppendEvaluatesInOrder + * + * @clean * + * @compile -XDstringConcat=indyWithConstants StringAppendEvaluatesInOrder.java + * @run main StringAppendEvaluatesInOrder + * + * @clean * + * @compile -XDstringConcat=inline StringAppendEvaluatesInOrder.java + * @run main StringAppendEvaluatesInOrder + */ + +public class StringAppendEvaluatesInOrder { + static String test() { + StringBuilder builder = new StringBuilder("foo"); + int i = 15; + return "Test: " + i + " " + (++i) + builder + builder.append("bar"); + } + + static String compoundAssignment() { + StringBuilder builder2 = new StringBuilder("foo"); + Object oo = builder2; + oo += "" + builder2.append("bar"); + return oo.toString(); + } + + public static void main(String[] args) throws Exception { + assertEquals(test(), "Test: 15 16foofoobar"); + assertEquals(compoundAssignment(), "foofoobar"); + } + + private static void assertEquals(String actual, String expected) { + if (!actual.equals(expected)) { + throw new AssertionError("expected: " + expected + ", actual: " + actual); + } + } +} diff --git a/test/langtools/tools/javac/StringConcat/WellKnownTypeSignatures.java b/test/langtools/tools/javac/StringConcat/WellKnownTypeSignatures.java new file mode 100644 index 0000000000000000000000000000000000000000..07cdeef49561535175e4901dd0d51b2d9528c946 --- /dev/null +++ b/test/langtools/tools/javac/StringConcat/WellKnownTypeSignatures.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2021, Google LLC. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.*; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @bug 8273914 + * @summary Indy string concat changes order of operations + * @modules jdk.jdeps/com.sun.tools.classfile + * + * @clean * + * @compile -XDstringConcat=indy WellKnownTypeSignatures.java + * @run main WellKnownTypeSignatures + * + * @clean * + * @compile -XDstringConcat=indyWithConstants WellKnownTypeSignatures.java + * @run main WellKnownTypeSignatures + */ + +public class WellKnownTypeSignatures { + static List actualTypes; + + static int idx = 0; + + static boolean z = true; + static char c = (char) 42; + static short s = (short) 42; + static byte b = (byte) 42; + static int i = 42; + static long l = 42L; + static float f = 42.0f; + static double d = 42.0; + + public static void main(String[] argv) throws Exception { + readIndyTypes(); + + test("" + WellKnownTypeSignatures.class, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); + test("" + Boolean.valueOf(z), idx++, "(Ljava/lang/Boolean;)Ljava/lang/String;"); + test("" + Character.valueOf(c), idx++, "(Ljava/lang/Character;)Ljava/lang/String;"); + test("" + Byte.valueOf(b), idx++, "(Ljava/lang/Byte;)Ljava/lang/String;"); + test("" + Short.valueOf(s), idx++, "(Ljava/lang/Short;)Ljava/lang/String;"); + test("" + Integer.valueOf(i), idx++, "(Ljava/lang/Integer;)Ljava/lang/String;"); + test("" + Long.valueOf(l), idx++, "(Ljava/lang/Long;)Ljava/lang/String;"); + test("" + Double.valueOf(d), idx++, "(Ljava/lang/Double;)Ljava/lang/String;"); + test("" + Float.valueOf(f), idx++, "(Ljava/lang/Float;)Ljava/lang/String;"); + test("" + z, idx++, "(Z)Ljava/lang/String;"); + test("" + c, idx++, "(C)Ljava/lang/String;"); + test("" + b, idx++, "(B)Ljava/lang/String;"); + test("" + s, idx++, "(S)Ljava/lang/String;"); + test("" + i, idx++, "(I)Ljava/lang/String;"); + test("" + l, idx++, "(J)Ljava/lang/String;"); + test("" + d, idx++, "(D)Ljava/lang/String;"); + test("" + f, idx++, "(F)Ljava/lang/String;"); + } + + public static void test(String actual, int index, String expectedType) { + String actualType = actualTypes.get(index); + if (!actualType.equals(expectedType)) { + throw new IllegalStateException( + index + + " Unexpected type: expected = " + + expectedType + + ", actual = " + + actualType); + } + } + + public static void readIndyTypes() throws Exception { + actualTypes = new ArrayList(); + + ClassFile classFile = + ClassFile.read( + new File( + System.getProperty("test.classes", "."), + WellKnownTypeSignatures.class.getName() + ".class")); + ConstantPool constantPool = classFile.constant_pool; + + for (Method method : classFile.methods) { + if (method.getName(constantPool).equals("main")) { + Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); + for (Instruction i : code.getInstructions()) { + if (i.getOpcode() == Opcode.INVOKEDYNAMIC) { + CONSTANT_InvokeDynamic_info indyInfo = + (CONSTANT_InvokeDynamic_info) + constantPool.get(i.getUnsignedShort(1)); + CONSTANT_NameAndType_info natInfo = indyInfo.getNameAndTypeInfo(); + actualTypes.add(natInfo.getType()); + } + } + } + } + } +} diff --git a/test/langtools/tools/javac/StringConcat/WellKnownTypes.java b/test/langtools/tools/javac/StringConcat/WellKnownTypes.java new file mode 100644 index 0000000000000000000000000000000000000000..39150cfc4da42fb02f18f083170d34d49a9cc6da --- /dev/null +++ b/test/langtools/tools/javac/StringConcat/WellKnownTypes.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021, Google LLC. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.*; + +/* + * @test + * @bug 8273914 + * @summary Indy string concat changes order of operations + * @modules jdk.jdeps/com.sun.tools.classfile + * + * @compile -XDstringConcat=indy WellKnownTypes.java + * @run main WellKnownTypes + * + * @compile -XDstringConcat=indyWithConstants WellKnownTypes.java + * @run main WellKnownTypes + * + * @compile -XDstringConcat=inline WellKnownTypes.java + * @run main WellKnownTypes + */ + +public class WellKnownTypes { + static int idx = 0; + + static boolean z = true; + static char c = (char) 42; + static byte b = (byte) 43; + static short s = (short) 44; + static int i = 45; + static long l = 46L; + static float f = 47.0f; + static double d = 48.0; + + public static void main(String[] argv) throws Exception { + test("" + WellKnownTypes.class, idx++, "class WellKnownTypes"); + test("" + Boolean.valueOf(z), idx++, "true"); + test("" + Character.valueOf(c), idx++, "*"); + test("" + Byte.valueOf(b), idx++, "43"); + test("" + Short.valueOf(s), idx++, "44"); + test("" + Integer.valueOf(i), idx++, "45"); + test("" + Long.valueOf(l), idx++, "46"); + test("" + Float.valueOf(f), idx++, "47.0"); + test("" + Double.valueOf(d), idx++, "48.0"); + test("" + z, idx++, "true"); + test("" + c, idx++, "*"); + test("" + b, idx++, "43"); + test("" + s, idx++, "44"); + test("" + i, idx++, "45"); + test("" + l, idx++, "46"); + test("" + f, idx++, "47.0"); + test("" + d, idx++, "48.0"); + } + + public static void test(String actual, int index, String expected) { + if (!actual.equals(expected)) { + throw new IllegalStateException( + index + " Unexpected: expected = " + expected + ", actual = " + actual); + } + } +} diff --git a/test/langtools/tools/javac/StringConcat/access/Test.java b/test/langtools/tools/javac/StringConcat/access/Test.java index 72237e8b4ef7b8d43aaccdbc26979d33bd5956ac..578bbddb1188ca25381d4e4665293b17c3560e78 100644 --- a/test/langtools/tools/javac/StringConcat/access/Test.java +++ b/test/langtools/tools/javac/StringConcat/access/Test.java @@ -56,109 +56,109 @@ public class Test { // ---------------------------------------------------------------------------- // public Private_PublicClass c1 = new Private_PublicClass(); - test("" + holder.c1, idx++, "(Lp1/PublicClass;)Ljava/lang/String;"); + test("" + holder.c1, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PublicInterface c2 = new Private_PublicInterface(); - test("" + holder.c2, idx++, "(Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.c2, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PrivateInterface1 c3 = new Private_PrivateInterface1(); - test("" + holder.c3, idx++, "(Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.c3, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PrivateInterface2 c4 = new Private_PrivateInterface2(); - test("" + holder.c4, idx++, "(Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.c4, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PublicClass c5 = new Public_PublicClass(); - test("" + holder.c5, idx++, "(Lp1/Public_PublicClass;)Ljava/lang/String;"); + test("" + holder.c5, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PublicInterface c6 = new Public_PublicInterface(); - test("" + holder.c6, idx++, "(Lp1/Public_PublicInterface;)Ljava/lang/String;"); + test("" + holder.c6, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PrivateInterface1 c7 = new Public_PrivateInterface1(); - test("" + holder.c7, idx++, "(Lp1/Public_PrivateInterface1;)Ljava/lang/String;"); + test("" + holder.c7, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PrivateInterface2 c8 = new Public_PrivateInterface2(); - test("" + holder.c8, idx++, "(Lp1/Public_PrivateInterface2;)Ljava/lang/String;"); + test("" + holder.c8, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // ---------------------------------------------------------------------------- // public Private_PublicClass[] ac1 = new Private_PublicClass[0]; - test("" + holder.ac1, idx++, "([Lp1/PublicClass;)Ljava/lang/String;"); + test("" + holder.ac1, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PublicInterface[] ac2 = new Private_PublicInterface[0]; - test("" + holder.ac2, idx++, "([Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.ac2, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PrivateInterface1[] ac3 = new Private_PrivateInterface1[0]; - test("" + holder.ac3, idx++, "([Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.ac3, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PrivateInterface2[] ac4 = new Private_PrivateInterface2[0]; - test("" + holder.ac4, idx++, "([Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.ac4, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PublicClass[] ac5 = new Public_PublicClass[0]; - test("" + holder.ac5, idx++, "([Lp1/Public_PublicClass;)Ljava/lang/String;"); + test("" + holder.ac5, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PublicInterface[] ac6 = new Public_PublicInterface[0]; - test("" + holder.ac6, idx++, "([Lp1/Public_PublicInterface;)Ljava/lang/String;"); + test("" + holder.ac6, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PrivateInterface1[] ac7 = new Public_PrivateInterface1[0]; - test("" + holder.ac7, idx++, "([Lp1/Public_PrivateInterface1;)Ljava/lang/String;"); + test("" + holder.ac7, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PrivateInterface2[] ac8 = new Public_PrivateInterface2[0]; - test("" + holder.ac8, idx++, "([Lp1/Public_PrivateInterface2;)Ljava/lang/String;"); + test("" + holder.ac8, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // ---------------------------------------------------------------------------- // public Private_PublicClass[][] aac1 = new Private_PublicClass[0][]; - test("" + holder.aac1, idx++, "([[Lp1/PublicClass;)Ljava/lang/String;"); + test("" + holder.aac1, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PublicInterface[][] aac2 = new Private_PublicInterface[0][]; - test("" + holder.aac2, idx++, "([[Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.aac2, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PrivateInterface1[][] aac3 = new Private_PrivateInterface1[0][]; - test("" + holder.aac3, idx++, "([[Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.aac3, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Private_PrivateInterface2[][] aac4 = new Private_PrivateInterface2[0][]; - test("" + holder.aac4, idx++, "([[Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.aac4, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PublicClass[][] aac5 = new Public_PublicClass[0][]; - test("" + holder.aac5, idx++, "([[Lp1/Public_PublicClass;)Ljava/lang/String;"); + test("" + holder.aac5, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PublicInterface[][] aac6 = new Public_PublicInterface[0][]; - test("" + holder.aac6, idx++, "([[Lp1/Public_PublicInterface;)Ljava/lang/String;"); + test("" + holder.aac6, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PrivateInterface1[][] aac7 = new Public_PrivateInterface1[0][]; - test("" + holder.aac7, idx++, "([[Lp1/Public_PrivateInterface1;)Ljava/lang/String;"); + test("" + holder.aac7, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public Public_PrivateInterface2[][] aac8 = new Public_PrivateInterface2[0][]; - test("" + holder.aac8, idx++, "([[Lp1/Public_PrivateInterface2;)Ljava/lang/String;"); + test("" + holder.aac8, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // ---------------------------------------------------------------------------- // public PublicInterface i1 = new Private_PublicInterface(); - test("" + holder.i1, idx++, "(Lp1/PublicInterface;)Ljava/lang/String;"); + test("" + holder.i1, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public PrivateInterface1 i2 = new Private_PrivateInterface1(); - test("" + holder.i2, idx++, "(Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.i2, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public PrivateInterface2 i3 = new Private_PrivateInterface2(); - test("" + holder.i3, idx++, "(Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.i3, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public PublicInterface[] ai1 = new Private_PublicInterface[0]; - test("" + holder.ai1, idx++, "([Lp1/PublicInterface;)Ljava/lang/String;"); + test("" + holder.ai1, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public PrivateInterface1[] ai2 = new Private_PrivateInterface1[0]; - test("" + holder.ai2, idx++, "([Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.ai2, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public PrivateInterface2[] ai3 = new Private_PrivateInterface2[0]; - test("" + holder.ai3, idx++, "([Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.ai3, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public PublicInterface[][] aai1 = new Private_PublicInterface[0][]; - test("" + holder.aai1, idx++, "([[Lp1/PublicInterface;)Ljava/lang/String;"); + test("" + holder.aai1, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public PrivateInterface1[][] aai2 = new Private_PrivateInterface1[0][]; - test("" + holder.aai2, idx++, "([[Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.aai2, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); // public PrivateInterface2[][] aai3 = new Private_PrivateInterface2[0][]; - test("" + holder.aai3, idx++, "([[Ljava/lang/Object;)Ljava/lang/String;"); + test("" + holder.aai3, idx++, "(Ljava/lang/String;)Ljava/lang/String;"); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicFlag.java b/test/langtools/tools/javac/T8036019.java similarity index 64% rename from test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicFlag.java rename to test/langtools/tools/javac/T8036019.java index d505ddbbb9a70af2ec93711fe53ec9e7dfdbe525..709b8abba468b025c42725c4e139dbbc5ad49981 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicFlag.java +++ b/test/langtools/tools/javac/T8036019.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -19,21 +19,28 @@ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. - * */ /* * @test - * @summary The DynamicDumpShareSpaces flag is internal, setting it at the command line should have no effect. - * @requires vm.cds - * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds - * @compile ../test-classes/Hello.java - * @run driver DynamicFlag + * @bug 8036019 + * @summary Insufficient alternatives listed in some errors produced by the parser + * @compile/fail/ref=T8036019.out -XDrawDiagnostics T8036019.java */ -public class DynamicFlag { - public static void main(String[] args) throws Exception { - TestCommon.test(JarBuilder.getOrCreateHelloJar(), - TestCommon.list("Hello"), "-XX:+DynamicDumpSharedSpaces", "Hello"); - } + +public class T8036019 { + enum E { + E(String value) { } + } + + interface A {} + interface B {} + public class Foo { + Foo foo1 = null; + } + + @SuppressWarnings({,0}) + public class AV { + } } diff --git a/test/langtools/tools/javac/T8036019.out b/test/langtools/tools/javac/T8036019.out new file mode 100644 index 0000000000000000000000000000000000000000..2c874175793c6034a7eb66727fa9ff7ccdc01d87 --- /dev/null +++ b/test/langtools/tools/javac/T8036019.out @@ -0,0 +1,10 @@ +T8036019.java:34:17: compiler.err.expected2: ')', ',' +T8036019.java:34:23: compiler.err.expected3: ',', '}', ';' +T8036019.java:34:25: compiler.err.enum.constant.expected +T8036019.java:40:24: compiler.err.expected2: >, ',' +T8036019.java:40:26: compiler.err.expected: token.identifier +T8036019.java:40:32: compiler.err.expected: token.identifier +T8036019.java:43:25: compiler.err.annotation.missing.element.value +T8036019.java:43:27: compiler.err.expected4: class, interface, enum, record +T8036019.java:46:1: compiler.err.expected4: class, interface, enum, record +9 errors \ No newline at end of file diff --git a/test/langtools/tools/javac/T8271079.java b/test/langtools/tools/javac/T8271079.java new file mode 100644 index 0000000000000000000000000000000000000000..9b866f618a771c1058fa7d2fbf58fa95192d12dd --- /dev/null +++ b/test/langtools/tools/javac/T8271079.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8271079 + * @summary JavaFileObject#toUri in MR-JAR returns real path + * @modules java.compiler + * jdk.compiler + * @run main T8271079 + */ + +import java.io.*; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.*; +import java.util.*; +import java.util.jar.JarEntry; +import javax.tools.*; + +public class T8271079 { + + public static void main(String[] args) throws Exception { + new T8271079().run(); + } + + final PrintStream out; + + T8271079() { + this.out = System.out; + } + + void run() throws Exception { + Path mr = generateMultiReleaseJar(); + try { + testT8271079(mr); + } finally { + Files.deleteIfExists(mr); + } + } + + // $ echo 'module hello {}' > module-info.java + // $ javac -d classes --release 9 module-info.java + // $ jar --create --file mr.jar --release 9 -C classes . + Path generateMultiReleaseJar() throws Exception { + Files.writeString(Path.of("module-info.java"), "module hello {}"); + java.util.spi.ToolProvider.findFirst("javac").orElseThrow() + .run(out, System.err, "-d", "classes", "--release", "9", "module-info.java"); + Path mr = Path.of("mr.jar"); + java.util.spi.ToolProvider.findFirst("jar").orElseThrow() + .run(out, System.err, "--create", "--file", mr.toString(), "--release", "9", "-C", "classes", "."); + out.println("Created: " + mr.toUri()); + out.println(" Exists: " + Files.exists(mr)); + return mr; + } + + void testT8271079(Path path) throws Exception { + StandardJavaFileManager fileManager = + ToolProvider.getSystemJavaCompiler() + .getStandardFileManager(null, Locale.ENGLISH, StandardCharsets.UTF_8); + fileManager.setLocationFromPaths(StandardLocation.CLASS_PATH, List.of(path)); + Iterator options = Arrays.asList("--multi-release", "9").iterator(); + fileManager.handleOption(options.next(), options); + + Iterable list = + fileManager.list( + StandardLocation.CLASS_PATH, "", EnumSet.allOf(JavaFileObject.Kind.class), false); + + for (JavaFileObject f : list) { + out.println("JavaFileObject#getName: " + f.getName()); + out.println("JavaFileObject#toUri: " + f.toUri()); + openUsingUri(f.toUri()); + } + System.gc(); // JDK-8224794 + } + + void openUsingUri(URI uri) throws IOException { + URLConnection connection = uri.toURL().openConnection(); + connection.setUseCaches(false); // JDK-8224794 + if (connection instanceof JarURLConnection jar) { + try { + JarEntry entry = jar.getJarEntry(); + out.println("JarEntry#getName: " + entry.getName()); + connection.getInputStream().close(); // JDK-8224794 + } catch (FileNotFoundException e) { + throw e; + } + } + } +} diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/6967002/T6967002.out b/test/langtools/tools/javac/annotations/typeAnnotations/6967002/T6967002.out index 86480c2bfa8e41bcd1d5aa357574aed7572a9f2a..d9a3545d31deec460f0a1142b0b08ce4996f6cfa 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/6967002/T6967002.out +++ b/test/langtools/tools/javac/annotations/typeAnnotations/6967002/T6967002.out @@ -1,2 +1,2 @@ -T6967002.java:10:22: compiler.err.expected: ')' +T6967002.java:10:22: compiler.err.expected2: ')', ',' 1 error diff --git a/test/langtools/tools/javac/api/TestGetSourceVersions.java b/test/langtools/tools/javac/api/TestGetSourceVersions.java index 9b0ddb9d6733c4eefa5d21b4e815d61d9a659a87..472c4fe97eda00f54ac642cf1199852fe9479fad 100644 --- a/test/langtools/tools/javac/api/TestGetSourceVersions.java +++ b/test/langtools/tools/javac/api/TestGetSourceVersions.java @@ -35,7 +35,7 @@ * @run main TestGetSourceVersions RELEASE_3 RELEASE_4 RELEASE_5 RELEASE_6 RELEASE_7 * RELEASE_8 RELEASE_9 RELEASE_10 RELEASE_11 RELEASE_12 * RELEASE_13 RELEASE_14 RELEASE_15 RELEASE_16 RELEASE_17 - * RELEASE_18 + * RELEASE_18 RELEASE_19 */ import java.util.EnumSet; diff --git a/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java b/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java new file mode 100644 index 0000000000000000000000000000000000000000..b9db273bea49a4679de1ef4219af9ac2dbee00b6 --- /dev/null +++ b/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8272944 + * @summary Use snippets in java.compiler documentation + * @library /tools/lib ../../lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build snippets.SnippetUtils toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox + * @run main TestJavaxToolsSnippets + */ + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; + +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; + +import com.sun.source.doctree.SnippetTree; + +import snippets.SnippetUtils; +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.TestRunner; +import toolbox.ToolBox; + +/** + * Tests the snippets in the {@code javax.tools} package, by compiling the + * external snippets and parsing the internal Java snippets. + */ +public class TestJavaxToolsSnippets extends TestRunner { + public static void main(String... args) throws Exception { + new TestJavaxToolsSnippets().runTests(m -> new Object[] { Path.of(m.getName()) }); + } + + SnippetUtils snippets = new SnippetUtils("java.compiler"); + ToolBox tb = new ToolBox(); + + TestJavaxToolsSnippets() { + super(System.err); + } + + @Test + public void testExternalSnippets(Path base) throws Exception { + Path snippetFilesDir = snippets.getSourceDir() + .resolve("java.compiler") // module + .resolve("share").resolve("classes") + .resolve("javax.tools".replace(".", File.separator)) // package + .resolve("snippet-files"); + new JavacTask(tb) + .files(tb.findJavaFiles(snippetFilesDir)) + .outdir(Files.createDirectories(base.resolve("classes"))) + .run(Task.Expect.SUCCESS) + .writeAll(); + out.println("Compilation succeeded"); + } + + @Test + public void testJavaCompilerSnippets(Path base) { + TypeElement te = snippets.getElements().getTypeElement("javax.tools.JavaCompiler"); + snippets.scan(te, this::handleSnippet); + } + + @Test + public void testJavaFileManagerSnippets(Path base) { + TypeElement te = snippets.getElements().getTypeElement("javax.tools.JavaFileManager"); + snippets.scan(te, this::handleSnippet); + } + + @Test + public void testStandardJavaFileManagerSnippets(Path base) { + TypeElement te = snippets.getElements().getTypeElement("javax.tools.StandardJavaFileManager"); + snippets.scan(te, this::handleSnippet); + } + + void handleSnippet(Element e, SnippetTree tree) { + String lang = snippets.getAttr(tree, "lang"); + if (Objects.equals(lang, "java")) { + String body = snippets.getBody(tree); + if (body != null) { + String id = snippets.getAttr(tree, "id"); + try { + out.println("parsing snippet " + e + ":" + id); + if (snippets.parse(body, out::println)) { + out.println("parsed snippet"); + } else { + error("parse failed"); + } + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + } + } +} diff --git a/test/langtools/tools/javac/classfiles/ClassVersionChecker.java b/test/langtools/tools/javac/classfiles/ClassVersionChecker.java index 4fcc73031966ac41bf6581899e7ee05410f68a90..4e586c32dcb5b61695a254a284eff0434bd03d33 100644 --- a/test/langtools/tools/javac/classfiles/ClassVersionChecker.java +++ b/test/langtools/tools/javac/classfiles/ClassVersionChecker.java @@ -53,7 +53,8 @@ public class ClassVersionChecker { FIFTEEN("15", 59), SIXTEEN("16", 60), SEVENTEEN("17", 61), - EIGHTEEN("18", 62); + EIGHTEEN("18", 62), + NINETEEN("19", 63); private Version(String release, int classFileVer) { this.release = release; diff --git a/test/langtools/tools/javac/classwriter/IndyCorrectInvocationName.java b/test/langtools/tools/javac/classwriter/IndyCorrectInvocationName.java new file mode 100644 index 0000000000000000000000000000000000000000..36d7b8c2759852adb93c533a56bf15ed3a491fba --- /dev/null +++ b/test/langtools/tools/javac/classwriter/IndyCorrectInvocationName.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277634 + * @summary Verify the correct constantpool entries are created for invokedynamic instructions using + * the same bootstrap and type, but different name. + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.code + * jdk.compiler/com.sun.tools.javac.comp + * jdk.compiler/com.sun.tools.javac.jvm + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.tree + * jdk.compiler/com.sun.tools.javac.util + * jdk.jdeps/com.sun.tools.classfile + * jdk.jdeps/com.sun.tools.javap + * @build toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox + * @run main IndyCorrectInvocationName + */ + +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import com.sun.source.util.JavacTask; +import com.sun.source.util.Plugin; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.BootstrapMethods_attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.ConstantPool.CONSTANT_InvokeDynamic_info; +import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info; +import com.sun.tools.classfile.Instruction; + +import com.sun.tools.javac.api.BasicJavacTask; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symbol.MethodSymbol; +import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.jvm.PoolConstant; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCLiteral; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.Tag; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.tree.TreeScanner; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Names; + +import toolbox.JarTask; +import toolbox.ToolBox; + + +public class IndyCorrectInvocationName implements Plugin { + private static final String NL = System.lineSeparator(); + + public static void main(String... args) throws Exception { + new IndyCorrectInvocationName().run(); + } + + void run() throws Exception { + ToolBox tb = new ToolBox(); + Path pluginClasses = Path.of("plugin-classes"); + tb.writeFile(pluginClasses.resolve("META-INF").resolve("services").resolve(Plugin.class.getName()), + IndyCorrectInvocationName.class.getName() + System.lineSeparator()); + try (DirectoryStream ds = Files.newDirectoryStream(Path.of(ToolBox.testClasses))) { + for (Path p : ds) { + if (p.getFileName().toString().startsWith("IndyCorrectInvocationName") || + p.getFileName().toString().endsWith(".class")) { + Files.copy(p, pluginClasses.resolve(p.getFileName())); + } + } + } + + Path pluginJar = Path.of("plugin.jar"); + new JarTask(tb, pluginJar) + .baseDir(pluginClasses) + .files(".") + .run(); + + Path src = Path.of("src"); + tb.writeJavaFiles(src, + """ + import java.lang.invoke.CallSite; + import java.lang.invoke.ConstantCallSite; + import java.lang.invoke.MethodHandles; + import java.lang.invoke.MethodHandles.Lookup; + import java.lang.invoke.MethodType; + public class Test{ + private static final String NL = System.lineSeparator(); + private static StringBuilder output = new StringBuilder(); + public static void doRun() { + method("a"); + method("b"); + method("a"); + method("b"); + } + public static String run() { + doRun(); + return output.toString(); + } + public static void method(String name) {} + public static void actualMethod(String name) { + output.append(name).append(NL); + } + public static CallSite bootstrap(Lookup lookup, String name, MethodType type) throws Exception { + return new ConstantCallSite(MethodHandles.lookup() + .findStatic(Test.class, + "actualMethod", + MethodType.methodType(void.class, + String.class)) + .bindTo(name)); + } + } + """); + Path classes = Files.createDirectories(Path.of("classes")); + + new toolbox.JavacTask(tb) + .classpath(pluginJar) + .options("-XDaccessInternalAPI") + .outdir(classes) + .files(tb.findJavaFiles(src)) + .run() + .writeAll(); + + URLClassLoader cl = new URLClassLoader(new URL[] {classes.toUri().toURL()}); + + String actual = (String) cl.loadClass("Test") + .getMethod("run") + .invoke(null); + String expected = "a" + NL + "b" + NL + "a" + NL +"b" + NL; + if (!Objects.equals(actual, expected)) { + throw new AssertionError("expected: " + expected + "; but got: " + actual); + } + + Path testClass = classes.resolve("Test.class"); + ClassFile cf = ClassFile.read(testClass); + BootstrapMethods_attribute bootAttr = + (BootstrapMethods_attribute) cf.attributes.get(Attribute.BootstrapMethods); + if (bootAttr.bootstrap_method_specifiers.length != 1) { + throw new AssertionError("Incorrect number of bootstrap methods: " + + bootAttr.bootstrap_method_specifiers.length); + } + Code_attribute codeAttr = + (Code_attribute) cf.methods[1].attributes.get(Attribute.Code); + Set seenBootstraps = new HashSet<>(); + Set seenNameAndTypes = new HashSet<>(); + Set seenNames = new HashSet<>(); + for (Instruction i : codeAttr.getInstructions()) { + switch (i.getOpcode()) { + case INVOKEDYNAMIC -> { + int idx = i.getUnsignedShort(1); + CONSTANT_InvokeDynamic_info dynamicInfo = + (CONSTANT_InvokeDynamic_info) cf.constant_pool.get(idx); + seenBootstraps.add(dynamicInfo.bootstrap_method_attr_index); + seenNameAndTypes.add(dynamicInfo.name_and_type_index); + CONSTANT_NameAndType_info nameAndTypeInfo = + cf.constant_pool.getNameAndTypeInfo(dynamicInfo.name_and_type_index); + seenNames.add(nameAndTypeInfo.getName()); + } + case RETURN -> {} + default -> throw new AssertionError("Unexpected instruction: " + i.getOpcode()); + } + } + if (seenBootstraps.size() != 1) { + throw new AssertionError("Unexpected bootstraps: " + seenBootstraps); + } + if (seenNameAndTypes.size() != 2) { + throw new AssertionError("Unexpected names and types: " + seenNameAndTypes); + } + if (!seenNames.equals(Set.of("a", "b"))) { + throw new AssertionError("Unexpected names and types: " + seenNames); + } + } + + // Plugin impl... + + @Override + public String getName() { return "IndyCorrectInvocationName"; } + + @Override + public void init(JavacTask task, String... args) { + Context c = ((BasicJavacTask) task).getContext(); + task.addTaskListener(new TaskListener() { + @Override + public void started(TaskEvent e) { + if (e.getKind() == TaskEvent.Kind.GENERATE) { + convert(c, (JCCompilationUnit) e.getCompilationUnit()); + } + } + }); + } + + @Override + public boolean autoStart() { + return true; + } + + private void convert(Context context, JCCompilationUnit toplevel) { + TreeMaker make = TreeMaker.instance(context); + Names names = Names.instance(context); + Symtab syms = Symtab.instance(context); + new TreeScanner() { + MethodSymbol bootstrap; + @Override + public void visitClassDef(JCClassDecl tree) { + bootstrap = (MethodSymbol) tree.sym.members().getSymbolsByName(names.fromString("bootstrap")).iterator().next(); + super.visitClassDef(tree); + } + @Override + public void visitApply(JCMethodInvocation tree) { + if (tree.args.size() == 1 && tree.args.head.hasTag(Tag.LITERAL)) { + String name = (String) ((JCLiteral) tree.args.head).value; + Type.MethodType indyType = new Type.MethodType( + com.sun.tools.javac.util.List.nil(), + syms.voidType, + com.sun.tools.javac.util.List.nil(), + syms.methodClass + ); + Symbol.DynamicMethodSymbol dynSym = new Symbol.DynamicMethodSymbol(names.fromString(name), + syms.noSymbol, + bootstrap.asHandle(), + indyType, + new PoolConstant.LoadableConstant[0]); + + JCTree.JCFieldAccess qualifier = make.Select(make.QualIdent(bootstrap.owner), dynSym.name); + qualifier.sym = dynSym; + qualifier.type = syms.voidType; + tree.meth = qualifier; + tree.args = com.sun.tools.javac.util.List.nil(); + tree.type = syms.voidType; + } + super.visitApply(tree); + } + + }.scan(toplevel); + } + +} diff --git a/test/langtools/tools/javac/code/CharImmediateValue.java b/test/langtools/tools/javac/code/CharImmediateValue.java new file mode 100644 index 0000000000000000000000000000000000000000..38745358be040041300d3d4fdbe8286623227b2e --- /dev/null +++ b/test/langtools/tools/javac/code/CharImmediateValue.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8280067 + * @summary Verify constant/immediate char values are correctly enhanced to ints when used in unary + * operators + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.code + * jdk.compiler/com.sun.tools.javac.comp + * jdk.compiler/com.sun.tools.javac.jvm + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.tree + * jdk.compiler/com.sun.tools.javac.util + * jdk.jdeps/com.sun.tools.classfile + * jdk.jdeps/com.sun.tools.javap + * @build toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox + * @compile CharImmediateValue.java + * @run main CharImmediateValue + */ + +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; + +import com.sun.source.util.JavacTask; +import com.sun.source.util.Plugin; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Opcode; + +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.TreeScanner; + +import toolbox.JarTask; +import toolbox.ToolBox; + + +public class CharImmediateValue implements Plugin { + public static void main(String... args) throws Exception { + new CharImmediateValue().runSourceTest(); + new CharImmediateValue().runReplacementTest(); + } + + void runSourceTest() throws Exception { + int param = 0; + Character var = (char) -(false ? (char) param : (char) 2); + } + + void runReplacementTest() throws Exception { + ToolBox tb = new ToolBox(); + Path pluginClasses = Path.of("plugin-classes"); + tb.writeFile(pluginClasses.resolve("META-INF").resolve("services").resolve(Plugin.class.getName()), + CharImmediateValue.class.getName() + System.lineSeparator()); + try (DirectoryStream ds = Files.newDirectoryStream(Path.of(ToolBox.testClasses))) { + for (Path p : ds) { + if (p.getFileName().toString().startsWith("CharImmediateValue") || + p.getFileName().toString().endsWith(".class")) { + Files.copy(p, pluginClasses.resolve(p.getFileName())); + } + } + } + + Path pluginJar = Path.of("plugin.jar"); + new JarTask(tb, pluginJar) + .baseDir(pluginClasses) + .files(".") + .run(); + + Path src = Path.of("src"); + tb.writeJavaFiles(src, + """ + public class Test{ + private static char replace; //this will be replace with a constant "1" after constant folding is done + public static String run() { + char c = (char) - replace; + if (c < 0) { + throw new AssertionError("Incorrect value!"); + } else { + return Integer.toString(c); + } + } + } + """); + Path classes = Files.createDirectories(Path.of("classes")); + + new toolbox.JavacTask(tb) + .classpath(pluginJar) + .options("-XDaccessInternalAPI") + .outdir(classes) + .files(tb.findJavaFiles(src)) + .run() + .writeAll(); + + URLClassLoader cl = new URLClassLoader(new URL[] {classes.toUri().toURL()}); + + String actual = (String) cl.loadClass("Test") + .getMethod("run") + .invoke(null); + String expected = "65535"; + if (!Objects.equals(actual, expected)) { + throw new AssertionError("expected: " + expected + "; but got: " + actual); + } + + Path testClass = classes.resolve("Test.class"); + ClassFile cf = ClassFile.read(testClass); + Code_attribute codeAttr = + (Code_attribute) cf.methods[1].attributes.get(Attribute.Code); + boolean seenCast = false; + for (Instruction i : codeAttr.getInstructions()) { + if (i.getOpcode() == Opcode.I2C) { + seenCast = true; + } + } + if (!seenCast) { + throw new AssertionError("Missing cast!"); + } + } + + // Plugin impl... + + @Override + public String getName() { return "CharImmediateValue"; } + + @Override + public void init(JavacTask task, String... args) { + task.addTaskListener(new TaskListener() { + @Override + public void started(TaskEvent e) { + if (e.getKind() == TaskEvent.Kind.GENERATE) { + convert((JCCompilationUnit) e.getCompilationUnit()); + } + } + }); + } + + @Override + public boolean autoStart() { + return true; + } + + private void convert(JCCompilationUnit toplevel) { + new TreeScanner() { + @Override + public void visitIdent(JCIdent tree) { + if (tree.name.contentEquals("replace")) { + tree.type = tree.type.constType(1); + } + super.visitIdent(tree); + } + }.scan(toplevel); + } + +} diff --git a/test/langtools/tools/javac/diags/examples.not-yet.txt b/test/langtools/tools/javac/diags/examples.not-yet.txt index f257b7df8e09d4ae187c5ed7a14c7f1a32dd3cd2..9f9f8f780144708d7f61108f4708b10c79cd457e 100644 --- a/test/langtools/tools/javac/diags/examples.not-yet.txt +++ b/test/langtools/tools/javac/diags/examples.not-yet.txt @@ -206,3 +206,4 @@ compiler.warn.source.target.conflict compiler.warn.target.default.source.conflict compiler.err.preview.not.latest compiler.err.preview.without.source.or.release +compiler.misc.illegal.signature # the compiler can now detect more non-denotable types before class writing diff --git a/test/langtools/tools/javac/diags/examples/AnnotationMissingElementValue.java b/test/langtools/tools/javac/diags/examples/AnnotationMissingElementValue.java new file mode 100644 index 0000000000000000000000000000000000000000..65f24aad3167d04053f306700151019955e1092c --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AnnotationMissingElementValue.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * 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. + */ + +// key: compiler.err.annotation.missing.element.value + +@SuppressWarnings({,0}) +public class AV { +} diff --git a/test/langtools/tools/javac/diags/examples/IllegalSignature.java b/test/langtools/tools/javac/diags/examples/IllegalSignature.java index a9b64b41afa68242acccb45f0aabcd9535f8c88e..96b93b6bdabbdef78199f279fe755c3b934137fb 100644 --- a/test/langtools/tools/javac/diags/examples/IllegalSignature.java +++ b/test/langtools/tools/javac/diags/examples/IllegalSignature.java @@ -21,8 +21,7 @@ * questions. */ -// key: compiler.err.cannot.generate.class -// key: compiler.misc.illegal.signature +// key: compiler.err.enclosing.class.type.non.denotable class IllegalSignature { class Inner { } diff --git a/test/langtools/tools/javac/diags/examples/LambdaDeduplicate.java b/test/langtools/tools/javac/diags/examples/LambdaDeduplicate.java index 8dda7bb2dd9d93e28a5d89211d977db891cbb979..cf39f9ffb758c2e01e5c596bfde12a1bd6943717 100644 --- a/test/langtools/tools/javac/diags/examples/LambdaDeduplicate.java +++ b/test/langtools/tools/javac/diags/examples/LambdaDeduplicate.java @@ -23,7 +23,7 @@ // key: compiler.note.verbose.l2m.deduplicate -// options: --debug=dumpLambdaToMethodDeduplication +// options: -g:none --debug=dumpLambdaToMethodDeduplication import java.util.function.Function; diff --git a/test/langtools/tools/javac/diags/examples/NoJavaLang.java b/test/langtools/tools/javac/diags/examples/NoJavaLang.java index 330243dbc960115331304966a6b5eafea739cc78..7329bbc02b6d4036260ef7a3fa69900ecbf0c12c 100644 --- a/test/langtools/tools/javac/diags/examples/NoJavaLang.java +++ b/test/langtools/tools/javac/diags/examples/NoJavaLang.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,9 @@ * questions. */ -// key: compiler.misc.fatal.err.no.java.lang +// key: compiler.err.error +// key: compiler.err.no.java.lang +// key: compiler.misc.count.error // options: -source 8 -target 8 -Xbootclasspath: -classpath . // run: backdoor diff --git a/test/langtools/tools/javac/doctree/ReferenceTest.java b/test/langtools/tools/javac/doctree/ReferenceTest.java index 128d3e158b11f1ea90a2f528b83bdf933cd44ae2..eb635650b7678cc3c2a96d3a7beaae4e3c00d91b 100644 --- a/test/langtools/tools/javac/doctree/ReferenceTest.java +++ b/test/langtools/tools/javac/doctree/ReferenceTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7021614 + * @bug 7021614 8278373 * @summary extend com.sun.source API to support parsing javadoc comments * @summary check references in at-see and {at-link} tags * @modules jdk.compiler @@ -39,19 +39,23 @@ import com.sun.source.doctree.SeeTree; import com.sun.source.doctree.TextTree; import com.sun.source.util.DocTreePath; import com.sun.source.util.DocTreePathScanner; -import com.sun.source.util.DocTreeScanner; import com.sun.source.util.DocTrees; import com.sun.source.util.TreePath; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.QualifiedNameable; import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic.Kind; /** @@ -174,8 +178,18 @@ public class ReferenceTest extends AbstractProcessor { if (label.size() > 0 && label.get(0) instanceof TextTree) expect = ((TextTree) label.get(0)).getBody(); - if (!expect.equalsIgnoreCase(found == null ? "bad" : found.getKind().name())) { - error(tree, "Unexpected value found: " + found +", expected: " + expect); + if (expect.startsWith("signature:")) { + expect = expect.substring("signature:".length()); + + String signature = found.getKind().name() + ":" + elementSignature(found); + + if (!expect.equalsIgnoreCase(signature)) { + error(tree, "Unexpected value found: " + signature +", expected: " + expect); + } + } else { + if (!expect.equalsIgnoreCase(found == null ? "bad" : found.getKind().name())) { + error(tree, "Unexpected value found: " + found +", expected: " + expect); + } } } @@ -183,6 +197,29 @@ public class ReferenceTest extends AbstractProcessor { trees.printMessage(Kind.ERROR, msg, tree, dc, path.getCompilationUnit()); } } + + String elementSignature(Element el) { + return switch (el.getKind()) { + case METHOD -> elementSignature(el.getEnclosingElement()) + "." + el.getSimpleName() + "(" + executableParamNames((ExecutableElement) el) + ")"; + case CLASS, INTERFACE -> ((QualifiedNameable) el).getQualifiedName().toString(); + default -> throw new AssertionError("Unhandled Element kind: " + el.getKind()); + }; + } + + String executableParamNames(ExecutableElement ee) { + return ee.getParameters() + .stream() + .map(p -> type2Name(p.asType())) + .collect(Collectors.joining(", ")); + } + + String type2Name(TypeMirror type) { + return switch (type.getKind()) { + case DECLARED -> elementSignature(((DeclaredType) type).asElement()); + case INT, LONG -> type.toString(); + default -> throw new AssertionError("Unhandled type kind: " + type.getKind()); + }; + } } /** @@ -199,6 +236,17 @@ public class ReferenceTest extends AbstractProcessor { * @see #varargs(int... args) Method * @see #varargs(int[]) Method * @see #varargs(int[] args) Method + * + * @see #methodSearch(String) signature:METHOD:ReferenceTestExtras.methodSearch(java.lang.String) + * @see #methodSearch(StringBuilder) signature:METHOD:ReferenceTestExtras.methodSearch(java.lang.CharSequence) + * @see #methodSearchPrimitive1(int, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(int, int) + * @see #methodSearchPrimitive1(long, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(long, int) + * @see #methodSearchPrimitive1(int, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(int, long) + * @see #methodSearchPrimitive1(long, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(long, long) + * @see #methodSearchPrimitive2(int, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(int, int) + * @see #methodSearchPrimitive2(long, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(long, int) + * @see #methodSearchPrimitive2(int, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(int, long) + * @see #methodSearchPrimitive2(long, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(long, long) */ class ReferenceTestExtras { int ReferenceTestExtras; // field @@ -214,6 +262,20 @@ class ReferenceTestExtras { void m(int i, int j) { } void varargs(int... args) { } + + void methodSearch(Object o) {} + void methodSearch(String s) {} + void methodSearch(CharSequence cs) {} + + void methodSearchPrimitive1(int i, int j) {} + void methodSearchPrimitive1(long i, int j) {} + void methodSearchPrimitive1(int i, long j) {} + void methodSearchPrimitive1(long i, long j) {} + + void methodSearchPrimitive2(long i, long j) {} + void methodSearchPrimitive2(int i, long j) {} + void methodSearchPrimitive2(long i, int j) {} + void methodSearchPrimitive2(int i, int j) {} } diff --git a/test/langtools/tools/javac/enum/EnumMembersOrder.out b/test/langtools/tools/javac/enum/EnumMembersOrder.out index b1e01860f3469d908676f72f2da0528ab2f63adb..94aff47aca8eeffb2bc33165c91273bc20c7965d 100644 --- a/test/langtools/tools/javac/enum/EnumMembersOrder.out +++ b/test/langtools/tools/javac/enum/EnumMembersOrder.out @@ -1,4 +1,4 @@ -EnumMembersOrder.java:11:16: compiler.err.expected: ')' +EnumMembersOrder.java:11:16: compiler.err.expected2: ')', ',' EnumMembersOrder.java:11:18: compiler.err.expected3: ',', '}', ';' EnumMembersOrder.java:11:20: compiler.err.enum.constant.expected 3 errors diff --git a/test/langtools/tools/javac/fatalErrors/NoJavaLangTest.java b/test/langtools/tools/javac/fatalErrors/NoJavaLangTest.java index b200c4c07193c97b485277937934b5bda6c83b26..ea39a0231f0a245624ed38b7dee852d3845fb4c4 100644 --- a/test/langtools/tools/javac/fatalErrors/NoJavaLangTest.java +++ b/test/langtools/tools/javac/fatalErrors/NoJavaLangTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. * 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 4263768 4785453 + * @bug 4263768 4785453 8205187 * @summary Verify that the compiler does not crash when java.lang is not available * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -38,7 +38,7 @@ import toolbox.JavacTask; import toolbox.Task; import toolbox.ToolBox; -public class NoJavaLangTest { +public class NoJavaLangTest { private static final String noJavaLangSrc = "public class NoJavaLang {\n" + @@ -50,7 +50,7 @@ public class NoJavaLangTest { "}"; private static final String compilerErrorMessage = - "Fatal Error: Unable to find package java.lang in classpath or bootclasspath"; + "error: Unable to find package java.lang in platform classes"; public static void main(String[] args) throws Exception { new NoJavaLangTest().run(); @@ -90,7 +90,6 @@ public class NoJavaLangTest { Files.delete(Paths.get("modules", "java.base", "java", "lang", "Object.class")); - // ideally we'd have a better message for this case String[] mpOpts = { "--system", "none", "--module-path", "modules" }; test(mpOpts, compilerErrorMessage); } @@ -101,15 +100,13 @@ public class NoJavaLangTest { String out = new JavacTask(tb) .options(options) .sources(noJavaLangSrc) - .run(Task.Expect.FAIL, 3) + .run(Task.Expect.FAIL, 1) .writeAll() .getOutput(Task.OutputKind.DIRECT); - if (!out.trim().equals(expect)) { + if (!out.trim().startsWith(expect)) { throw new AssertionError("javac generated error output is not correct"); } - - System.err.println("OK"); } } diff --git a/test/langtools/tools/javac/generics/diamond/neg/Neg21.out b/test/langtools/tools/javac/generics/diamond/neg/Neg21.out index 35e1a94cc156e4fc83d5edc891ec9a476feecd59..d273f7ae713005ae9ba64a74c19832be76a81759 100644 --- a/test/langtools/tools/javac/generics/diamond/neg/Neg21.out +++ b/test/langtools/tools/javac/generics/diamond/neg/Neg21.out @@ -1,2 +1,3 @@ +Neg21.java:13:9: compiler.err.enclosing.class.type.non.denotable: Neg21 Neg21.java:13:28: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg21.A), (compiler.misc.diamond.invalid.arg: java.lang.Object&java.io.Serializable&java.lang.Cloneable, (compiler.misc.diamond: Neg21.A)) -1 error +2 errors diff --git a/test/langtools/tools/javac/lambda/CantFindSymbolImplicitLambdaAndDiamondTest.java b/test/langtools/tools/javac/lambda/CantFindSymbolImplicitLambdaAndDiamondTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a053d7f27ab76beb250e4ed2dd1c4a15fb46c631 --- /dev/null +++ b/test/langtools/tools/javac/lambda/CantFindSymbolImplicitLambdaAndDiamondTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary symbol not found error, implicit lambdas and diamond constructor invocations + * @compile CantFindSymbolImplicitLambdaAndDiamondTest.java + */ + +import java.util.function.Consumer; + +class CantFindSymbolImplicitLambdaAndDiamondTest { + static class B{} + + static class A1 { + A1(Consumer cons) {} + } + + static class A2 { + A2(Consumer cons) {} + } + + public void mount() { + new A1(inHours -> + new B<>() {{ + System.out.println(inHours); + }}); + + new A2<>(inHours -> + new B<>() {{ + System.out.println(inHours); + }}); + } +} diff --git a/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.java b/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..2302b8f431d3b57d214b6a672016722e4e047b8e --- /dev/null +++ b/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021, Google LLC. All rights reserved. + * 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 8275233 + * @summary Incorrect line number reported in exception stack trace thrown from a lambda expression + * @compile/ref=DeduplicationDebugInfo.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication -g:none DeduplicationDebugInfo.java + * @compile/ref=DeduplicationDebugInfo_none.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication DeduplicationDebugInfo.java + * @compile/ref=DeduplicationDebugInfo_none.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication -g:lines DeduplicationDebugInfo.java + * @compile/ref=DeduplicationDebugInfo_none.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication -g:vars DeduplicationDebugInfo.java + * @compile/ref=DeduplicationDebugInfo_none.out -XDrawDiagnostics -XDdebug.dumpLambdaToMethodDeduplication -g:lines,vars DeduplicationDebugInfo.java + */ + +import java.util.function.Function; + +class DeduplicationDebugInfoTest { + void f() { + Function f = x -> x.hashCode(); + Function g = x -> x.hashCode(); + } +} diff --git a/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.out b/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.out new file mode 100644 index 0000000000000000000000000000000000000000..f428fe28846675bad558eda19e0f18e3d15ca8fd --- /dev/null +++ b/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo.out @@ -0,0 +1 @@ +DeduplicationDebugInfo.java:39:39: compiler.note.verbose.l2m.deduplicate: lambda$f$0(java.lang.Object) diff --git a/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo_none.out b/test/langtools/tools/javac/lambda/deduplication/DeduplicationDebugInfo_none.out new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java b/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java index 14d0b88f09e40b525a492ee77f8741ba4ccfc0be..44c200e62261e3cb4069d882d69ba1b1ec4a6e54 100644 --- a/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java +++ b/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java @@ -93,6 +93,7 @@ public class DeduplicationTest { Arrays.asList( "-d", ".", + "-g:none", "-XDdebug.dumpLambdaToMethodDeduplication", "-XDdebug.dumpLambdaToMethodStats"), null, diff --git a/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java b/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java index 634a468d5591e29dee8487685035babc857edd31..03e065828961cb412239ce6fd48067ceb7e21d10 100644 --- a/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java +++ b/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java @@ -112,7 +112,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { * corresponding platform visitor type. */ - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static abstract class AbstractAnnotationValueVisitor extends AbstractAnnotationValueVisitor14 { /** @@ -123,7 +123,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static abstract class AbstractElementVisitor extends AbstractElementVisitor14 { /** * Constructor for concrete subclasses to call. @@ -133,7 +133,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static abstract class AbstractTypeVisitor extends AbstractTypeVisitor14 { /** * Constructor for concrete subclasses to call. @@ -143,7 +143,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static class ElementKindVisitor extends ElementKindVisitor14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -164,7 +164,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static class ElementScanner extends ElementScanner14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -183,7 +183,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static class SimpleAnnotationValueVisitor extends SimpleAnnotationValueVisitor14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -204,7 +204,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static class SimpleElementVisitor extends SimpleElementVisitor14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -225,7 +225,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static class SimpleTypeVisitor extends SimpleTypeVisitor14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -246,7 +246,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_18) + @SupportedSourceVersion(RELEASE_19) public static class TypeKindVisitor extends TypeKindVisitor14 { /** * Constructor for concrete subclasses to call; uses {@code null} diff --git a/test/langtools/tools/javac/parser/7157165/T7157165.out b/test/langtools/tools/javac/parser/7157165/T7157165.out index deb580df96c647d06dfffda4887b1d9119d3806b..7552381ba15c13fcef7ad5f97905525e43cd421f 100644 --- a/test/langtools/tools/javac/parser/7157165/T7157165.out +++ b/test/langtools/tools/javac/parser/7157165/T7157165.out @@ -1,4 +1,4 @@ -T7157165.java:11:20: compiler.err.expected: > +T7157165.java:11:20: compiler.err.expected2: >, ',' T7157165.java:11:22: compiler.err.expected: token.identifier T7157165.java:11:28: compiler.err.expected: token.identifier 3 errors diff --git a/test/langtools/tools/javac/parser/SingleCommaAnnotationValueFail.out b/test/langtools/tools/javac/parser/SingleCommaAnnotationValueFail.out index 23d1082361bc9f8c0c7bb80ce5a9cb768f4a0137..05d27bc67df77e508ec2b9dee0fbe96b699fec68 100644 --- a/test/langtools/tools/javac/parser/SingleCommaAnnotationValueFail.out +++ b/test/langtools/tools/javac/parser/SingleCommaAnnotationValueFail.out @@ -1,3 +1,3 @@ -SingleCommaAnnotationValueFail.java:11:12: compiler.err.expected: '}' +SingleCommaAnnotationValueFail.java:11:12: compiler.err.annotation.missing.element.value SingleCommaAnnotationValueFail.java:11:14: compiler.err.expected4: class, interface, enum, record 2 errors diff --git a/test/langtools/tools/javac/patterns/BindingsInitializer.java b/test/langtools/tools/javac/patterns/BindingsInitializer.java new file mode 100644 index 0000000000000000000000000000000000000000..eaf550c3dafe004a4c7cd907b9df6568343afaa6 --- /dev/null +++ b/test/langtools/tools/javac/patterns/BindingsInitializer.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8278834 + * @summary Verify pattern matching nested inside initializers of classes nested in methods + * works correctly. + * @library /tools/lib /tools/javac/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.file + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * @build toolbox.ToolBox toolbox.JavacTask + * @build combo.ComboTestHelper + * @compile BindingsInitializer.java + * @run main BindingsInitializer + */ + +import combo.ComboInstance; +import combo.ComboParameter; +import combo.ComboTask; +import combo.ComboTestHelper; +import java.nio.file.Path; +import java.nio.file.Paths; +import toolbox.ToolBox; + +public class BindingsInitializer extends ComboInstance { + protected ToolBox tb; + + BindingsInitializer() { + super(); + tb = new ToolBox(); + } + + public static void main(String... args) throws Exception { + new ComboTestHelper() + .withDimension("OUTER", (x, outer) -> x.outer = outer, Outer.values()) + .withDimension("MIDDLE", (x, middle) -> x.middle = middle, Middle.values()) + .withDimension("INNER", (x, inner) -> x.inner = inner, Inner.values()) + .withDimension("TEST", (x, test) -> x.test = test, Test.values()) + .run(BindingsInitializer::new); + } + + private Outer outer; + private Middle middle; + private Inner inner; + private Test test; + + private static final String MAIN_TEMPLATE = + """ + public class Test { + private static Object obj = ""; + #{OUTER} + } + """; + + @Override + protected void doWork() throws Throwable { + Path base = Paths.get("."); + + ComboTask task = newCompilationTask() + .withSourceFromTemplate(MAIN_TEMPLATE, pname -> switch (pname) { + case "OUTER" -> outer; + case "MIDDLE" -> middle; + case "INNER" -> inner; + case "TESST" -> test; + default -> throw new UnsupportedOperationException(pname); + }); + + task.generate(result -> { + if (result.hasErrors()) { + throw new AssertionError("Unexpected result: " + result.compilationInfo()); + } + }); + } + + public enum Outer implements ComboParameter { + NONE("#{MIDDLE}"), + STATIC_CLASS("static class Nested { #{MIDDLE} }"), + CLASS("class Inner { #{MIDDLE} }"); + private final String code; + + private Outer(String code) { + this.code = code; + } + + @Override + public String expand(String optParameter) { + return code; + } + } + + public enum Middle implements ComboParameter { + STATIC_INIT("static { #{INNER} }"), + INIT("{ #{INNER} }"), + METHOD("void test() { #{INNER} }"); + private final String code; + + private Middle(String code) { + this.code = code; + } + + @Override + public String expand(String optParameter) { + return code; + } + } + + public enum Inner implements ComboParameter { + DIRECT("#{TEST}"), + CLASS_STATIC_INIT("class C { static { #{TEST} } }"), + CLASS_INIT("class C { { #{TEST} } }"), + CLASS_METHOD("class C { void t() { #{TEST} } }"), + ANNONYMOUS_CLASS_STATIC_INIT("new Object() { static { #{TEST} } };"), + ANNONYMOUS_CLASS_INIT("new Object() { { #{TEST} } };"), + ANNONYMOUS_CLASS_METHOD("new Object() { void t() { #{TEST} } };"); + private final String code; + + private Inner(String code) { + this.code = code; + } + + @Override + public String expand(String optParameter) { + return code; + } + } + + public enum Test implements ComboParameter { + TEST("if (obj instanceof String str) System.err.println(str);"); + private final String code; + + private Test(String code) { + this.code = code; + } + + @Override + public String expand(String optParameter) { + return code; + } + } +} diff --git a/test/langtools/tools/javac/patterns/Exhaustiveness.java b/test/langtools/tools/javac/patterns/Exhaustiveness.java index 36c824deeeed360afc04dec9fd01143f2f8cbde0..b7db66c3231a256351acfecb3b5fbc11ee22fbc9 100644 --- a/test/langtools/tools/javac/patterns/Exhaustiveness.java +++ b/test/langtools/tools/javac/patterns/Exhaustiveness.java @@ -369,102 +369,6 @@ public class Exhaustiveness extends TestRunner { """); } - @Test - public void testInaccessiblePermitted(Path base) throws IOException { - Path current = base.resolve("."); - Path libSrc = current.resolve("lib-src"); - - tb.writeJavaFiles(libSrc, - """ - package lib; - public sealed interface S permits A, B {} - """, - """ - package lib; - public final class A implements S {} - """, - """ - package lib; - final class B implements S {} - """); - - Path libClasses = current.resolve("libClasses"); - - Files.createDirectories(libClasses); - - new JavacTask(tb) - .options("--enable-preview", - "-source", JAVA_VERSION) - .outdir(libClasses) - .files(tb.findJavaFiles(libSrc)) - .run(); - - Path src = current.resolve("src"); - tb.writeJavaFiles(src, - """ - package test; - import lib.*; - public class Test { - private int test(S obj) { - return switch (obj) { - case A a -> 0; - }; - } - } - """); - - Path classes = current.resolve("libClasses"); - - Files.createDirectories(libClasses); - - var log = - new JavacTask(tb) - .options("--enable-preview", - "-source", JAVA_VERSION, - "-XDrawDiagnostics", - "-Xlint:-preview", - "--class-path", libClasses.toString()) - .outdir(classes) - .files(tb.findJavaFiles(src)) - .run(Task.Expect.FAIL) - .writeAll() - .getOutputLines(Task.OutputKind.DIRECT); - - List expectedErrors = List.of( - "Test.java:5:16: compiler.err.not.exhaustive", - "- compiler.note.preview.filename: Test.java, DEFAULT", - "- compiler.note.preview.recompile", - "1 error"); - - if (!expectedErrors.equals(log)) { - throw new AssertionError("Incorrect errors, expected: " + expectedErrors + - ", actual: " + log); - } - - Path bClass = libClasses.resolve("lib").resolve("B.class"); - - Files.delete(bClass); - - var log2 = - new JavacTask(tb) - .options("--enable-preview", - "-source", JAVA_VERSION, - "-XDrawDiagnostics", - "-Xlint:-preview", - "--class-path", libClasses.toString()) - .outdir(classes) - .files(tb.findJavaFiles(src)) - .run(Task.Expect.FAIL) - .writeAll() - .getOutputLines(Task.OutputKind.DIRECT); - - if (!expectedErrors.equals(log2)) { - throw new AssertionError("Incorrect errors, expected: " + expectedErrors + - ", actual: " + log2); - } - - } - @Test public void testExhaustiveStatement1(Path base) throws Exception { doTest(base, diff --git a/test/langtools/tools/javac/platform/NonExportedSuperTypes.java b/test/langtools/tools/javac/platform/NonExportedSuperTypes.java new file mode 100644 index 0000000000000000000000000000000000000000..b3f17fd6e3c45df11a61ac388ee7f0b635b4dfaf --- /dev/null +++ b/test/langtools/tools/javac/platform/NonExportedSuperTypes.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277106 + * @summary Verify no error is when compiling a class whose supertype is not exported. + * @modules jdk.compiler + * jdk.jfr + * @compile --release 17 NonExportedSuperTypes.java + */ + +import jdk.jfr.Event; + +public class NonExportedSuperTypes { + + public void evt(Event evt) { + evt.toString(); + } + +} diff --git a/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTest.java b/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTest.java index 2f201fd0067da1d483c0a095ed42ceaf791f44d5..c54c21bfc0d7ad330cddec0cd7b1fd0ef3d110ce 100644 --- a/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTest.java +++ b/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTest.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8072480 + * @bug 8072480 8277106 * @summary Unit test for CreateSymbols * @modules java.compiler * jdk.compiler/com.sun.tools.javac.api diff --git a/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTestImpl.java b/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTestImpl.java index 42b9649311adebe6caffc6c943bf916842729e44..307c53135a774751778b1594fc6383834bdcb1b3 100644 --- a/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTestImpl.java +++ b/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTestImpl.java @@ -28,8 +28,14 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.DirectoryStream; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; @@ -52,6 +58,14 @@ import build.tools.symbolgenerator.CreateSymbols.ClassDescription; import build.tools.symbolgenerator.CreateSymbols.ClassList; import build.tools.symbolgenerator.CreateSymbols.ExcludeIncludeList; import build.tools.symbolgenerator.CreateSymbols.VersionDescription; +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.Attributes; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ClassWriter; +import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPool.CPInfo; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info; +import com.sun.tools.classfile.ModulePackages_attribute; public class CreateSymbolsTestImpl { @@ -641,6 +655,306 @@ public class CreateSymbolsTestImpl { """); } + @Test + void testNonExportedSuperclass() throws Exception { + doTestComplex("api.Api", + """ + package api; + + public class Api extends nonapi.Impl.Nested.Exp { + + public Api(); + } + """, + """ + import api.Api; + public class Test { + private void t(Api api) { + api.run(); + } + } + """, + """ + import api.Api; + public class Test { + private void t(Api api) { + fail + } + } + """, + """ + module m { + exports api; + } + """, + """ + package api; + import nonapi.Impl; + public class Api extends Impl.Nested.Exp { + } + """, + """ + package api; + public @interface Ann { + } + """, + """ + package nonapi; + import api.Ann; + public class Impl { + public static final String C = ""; + public void test() {} + @Ann + public static class Nested { + public static class Exp extends Nested implements Runnable { + public void run() {} + public OtherNested get() { return null; } + } + } + public static class OtherNested {} + } + """); + } + + void doTestComplex(String printClass, + String expected, + String depSuccess, + String depFailure, + String... code) throws Exception { + ToolBox tb = new ToolBox(); + String testClasses = System.getProperty("test.classes"); + Path output = Paths.get(testClasses, "test-data" + i++); + deleteRecursively(output); + Files.createDirectories(output); + Path ver9Jar = output.resolve("9.jar"); + compileAndPack(output, + ver9Jar, + code); + + + Path ctSym = output.resolve("ct.sym"); + + deleteRecursively(ctSym); + + CreateSymbols.ALLOW_NON_EXISTING_CLASSES = true; + CreateSymbols.EXTENSION = ".class"; + + deleteRecursively(ctSym); + + List versions = + Arrays.asList(new VersionDescription(ver9Jar.toAbsolutePath().toString(), "9", null)); + + ExcludeIncludeList acceptAll = new ExcludeIncludeList(null, null) { + @Override public boolean accepts(String className, boolean includePrivateClasses) { + return true; + } + }; + new CreateSymbols().createBaseLine(versions, acceptAll, ctSym, new String[0]); + Path symbolsDesc = ctSym.resolve("symbols"); + Path systemModules = ctSym.resolve("systemModules"); + + Files.newBufferedWriter(systemModules).close(); + + Path classesZip = output.resolve("classes.zip"); + Path classesDir = output.resolve("classes"); + + new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classesZip.toAbsolutePath().toString(), 0, "9", systemModules.toString()); + + try (JarFile jf = new JarFile(classesZip.toFile())) { + Enumeration en = jf.entries(); + + while (en.hasMoreElements()) { + JarEntry je = en.nextElement(); + if (je.isDirectory()) continue; + Path target = classesDir.resolve(je.getName()); + Files.createDirectories(target.getParent()); + Files.copy(jf.getInputStream(je), target); + } + } + + Path classes = classesDir; + Path scratch = output.resolve("scratch"); + + Files.createDirectories(scratch); + + String modulePath; + + try (Stream elements = Files.list(classes)) { + modulePath = elements.filter(el -> el.getFileName().toString().contains("9")) + .map(el -> el.resolve("m")) + .map(el -> el.toAbsolutePath().toString()) + .collect(Collectors.joining(File.pathSeparator)); + } + + { + String out = new JavacTask(tb, Task.Mode.CMDLINE) + .options("-d", scratch.toAbsolutePath().toString(), "--module-path", modulePath, + "--add-modules", "m", "-Xprint", "api.Api") + .run(Expect.SUCCESS) + .getOutput(Task.OutputKind.STDOUT) + .replaceAll("\\R", "\n"); + + if (!out.equals(expected)) { + throw new AssertionError("out=" + out + "; expected=" + expected); + } + } + + { + new JavacTask(tb) + .options("-d", scratch.toAbsolutePath().toString(), "--module-path", modulePath, + "--add-modules", "m") + .sources(depSuccess) + .run(Expect.SUCCESS) + .writeAll(); + } + + { + String expectedFailure = new JavacTask(tb) + .options("-d", scratch.toAbsolutePath().toString(), "--module-path", output.resolve("temp").toString(), + "--add-modules", "m", "-XDrawDiagnostics") + .sources(depFailure) + .run(Expect.FAIL) + .getOutput(Task.OutputKind.DIRECT) + .replaceAll("\\R", "\n"); + + String out = new JavacTask(tb) + .options("-d", scratch.toAbsolutePath().toString(), "--module-path", modulePath, + "--add-modules", "m", "-XDrawDiagnostics") + .sources(depFailure) + .run(Expect.FAIL) + .getOutput(Task.OutputKind.DIRECT) + .replaceAll("\\R", "\n"); + + if (!out.equals(expectedFailure)) { + throw new AssertionError("out=" + out + "; expected=" + expectedFailure); + } + } + } + + @Test + void testExtendsInternalData1() throws Exception { + doTestData(""" + module name m + header exports api,nonapi[java.base] requires name\\u0020;java.base\\u0020;flags\\u0020;8000\\u0020;version\\u0020;0 flags 8000 + + class name api/Ann + header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 + + class name api/Api + header extends nonapi/Impl$Nested$Exp flags 21 + innerclass innerClass nonapi/Impl$Nested outerClass nonapi/Impl innerClassName Nested flags 9 + innerclass innerClass nonapi/Impl$Nested$Exp outerClass nonapi/Impl$Nested innerClassName Exp flags 9 + method name descriptor ()V flags 1 + + class name nonapi/Impl + header extends java/lang/Object nestMembers nonapi/Impl$Nested,nonapi/Impl$Nested$Exp flags 21 + innerclass innerClass nonapi/Impl$Nested outerClass nonapi/Impl innerClassName Nested flags 9 + innerclass innerClass nonapi/Impl$Nested$Exp outerClass nonapi/Impl$Nested innerClassName Exp flags 9 + field name C descriptor Ljava/lang/String; constantValue flags 19 + method name descriptor ()V flags 1 + method name test descriptor ()V flags 1 + + class name nonapi/Impl$Nested + header extends java/lang/Object nestHost nonapi/Impl flags 21 classAnnotations @Lapi/Ann; + innerclass innerClass nonapi/Impl$Nested outerClass nonapi/Impl innerClassName Nested flags 9 + innerclass innerClass nonapi/Impl$Nested$Exp outerClass nonapi/Impl$Nested innerClassName Exp flags 9 + method name descriptor ()V flags 1 + + class name nonapi/Impl$Nested$Exp + header extends nonapi/Impl$Nested implements java/lang/Runnable nestHost nonapi/Impl flags 21 + innerclass innerClass nonapi/Impl$Nested outerClass nonapi/Impl innerClassName Nested flags 9 + innerclass innerClass nonapi/Impl$Nested$Exp outerClass nonapi/Impl$Nested innerClassName Exp flags 9 + method name descriptor ()V flags 1 + method name run descriptor ()V flags 1 + method name get descriptor ()Lnonapi/Impl$OtherNested; flags 1 + + """, + """ + module m { + exports api; + exports nonapi to java.base; + } + """, + """ + package api; + import nonapi.Impl; + public class Api extends Impl.Nested.Exp { + } + """, + """ + package api; + public @interface Ann { + } + """, + """ + package nonapi; + import api.Ann; + public class Impl { + public static final String C = ""; + public void test() {} + @Ann + public static class Nested { + public static class Exp extends Nested implements Runnable { + public void run() {} + public OtherNested get() { return null; } + } + } + public static class OtherNested {} + } + """); + } + + void doTestData(String data, + String... code) throws Exception { + String testClasses = System.getProperty("test.classes"); + Path output = Paths.get(testClasses, "test-data" + i++); + deleteRecursively(output); + Files.createDirectories(output); + Path ver9Jar = output.resolve("9.jar"); + compileAndPack(output, + ver9Jar, + code); + + Path ctSym = output.resolve("ct.sym"); + + deleteRecursively(ctSym); + + CreateSymbols.ALLOW_NON_EXISTING_CLASSES = true; + CreateSymbols.DO_NOT_MODIFY = ""; + CreateSymbols.EXTENSION = ".class"; + CreateSymbols.INJECTED_VERSION = "0"; + + deleteRecursively(ctSym); + + List versions = + Arrays.asList(new VersionDescription(ver9Jar.toAbsolutePath().toString(), "9", null)); + + ExcludeIncludeList acceptAll = new ExcludeIncludeList(null, null) { + @Override public boolean accepts(String className, boolean includePrivateClasses) { + return true; + } + }; + new CreateSymbols().createBaseLine(versions, acceptAll, ctSym, new String[0]); + + Path symFile = null; + + try (DirectoryStream ds = Files.newDirectoryStream(ctSym)) { + for (Path p : ds) { + if (p.toString().endsWith(".sym.txt")) { + if (symFile != null) { + throw new IllegalStateException("Multiple sym files!"); + } else { + symFile = p; + } + } + } + } + String acutalContent = new String(Files.readAllBytes(symFile), StandardCharsets.UTF_8); + if (!acutalContent.equals(data)) { + throw new AssertionError("out=" + acutalContent + "; expected=" + data); + } + } + void doTestIncluded(String code, String... includedClasses) throws Exception { boolean oldIncludeAll = includeAll; try { @@ -712,7 +1026,7 @@ public class CreateSymbolsTestImpl { new VersionDescription(jar8.toAbsolutePath().toString(), "8", "7")); ExcludeIncludeList acceptAll = new ExcludeIncludeList(null, null) { - @Override public boolean accepts(String className) { + @Override public boolean accepts(String className, boolean includePrivateClasses) { return true; } }; @@ -743,6 +1057,36 @@ public class CreateSymbolsTestImpl { System.err.println(Arrays.asList(code)); new JavacTask(tb).sources(code).options("-d", scratch.toAbsolutePath().toString()).run(Expect.SUCCESS); List classFiles = collectClassFile(scratch); + Path moduleInfo = scratch.resolve("module-info.class"); + if (Files.exists(moduleInfo)) { + Set packages = new HashSet<>(); + for (String cf : classFiles) { + int sep = cf.lastIndexOf(scratch.getFileSystem().getSeparator()); + if (sep != (-1)) { + packages.add(cf.substring(0, sep)); + } + } + ClassFile cf = ClassFile.read(moduleInfo); + List cp = new ArrayList<>(); + cp.add(null); + cf.constant_pool.entries().forEach(cp::add); + Map attrs = new HashMap<>(cf.attributes.map); + int[] encodedPackages = new int[packages.size()]; + int i = 0; + for (String p : packages) { + int nameIndex = cp.size(); + cp.add(new CONSTANT_Utf8_info(p)); + encodedPackages[i++] = cp.size(); + cp.add(new ConstantPool.CONSTANT_Package_info(null, nameIndex)); + } + int attrName = cp.size(); + cp.add(new CONSTANT_Utf8_info(Attribute.ModulePackages)); + attrs.put(Attribute.ModulePackages, new ModulePackages_attribute(attrName, encodedPackages)); + ClassFile newFile = new ClassFile(cf.magic, cf.minor_version, cf.major_version, new ConstantPool(cp.toArray(new CPInfo[0])), cf.access_flags, cf.this_class, cf.super_class, cf.interfaces, cf.fields, cf.methods, new Attributes(attrs)); + try (OutputStream out = Files.newOutputStream(moduleInfo)) { + new ClassWriter().write(newFile, out); + } + } try (Writer out = Files.newBufferedWriter(outputFile)) { for (String classFile : classFiles) { try (InputStream in = Files.newInputStream(scratch.resolve(classFile))) { diff --git a/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out b/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out index 7c9e532800b01e458680f132a62688e5b9e50ba6..b80a19b27b4865838ae73d13a9c2e4d0cc4b36b0 100644 --- a/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out +++ b/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out @@ -1,2 +1,2 @@ -- compiler.err.preview.feature.disabled.classfile: Bar.class, 18 +- compiler.err.preview.feature.disabled.classfile: Bar.class, 19 1 error diff --git a/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out b/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out index 6a8ffbd85841acb47d790f6bcae1fdae09e0a367..df31f431c153ac96f4653a0ed6c8da5788fb016a 100644 --- a/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out +++ b/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out @@ -1,4 +1,4 @@ -- compiler.warn.preview.feature.use.classfile: Bar.class, 18 +- compiler.warn.preview.feature.use.classfile: Bar.class, 19 - compiler.err.warnings.and.werror 1 error 1 warning diff --git a/test/langtools/tools/javac/processing/model/element/TestListPackageFromAPI.java b/test/langtools/tools/javac/processing/model/element/TestListPackageFromAPI.java new file mode 100644 index 0000000000000000000000000000000000000000..358be012617062e0884bd0a790a3796672787b21 --- /dev/null +++ b/test/langtools/tools/javac/processing/model/element/TestListPackageFromAPI.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * 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 8278930 + * @summary Check that when a package has Elements listed from both from classes and sources, + * and then a nested class is completed, it is not first completed from source via + * its enclosing class, and then again for itself. + * @library /tools/javac/lib + * @modules java.compiler + * jdk.compiler + * @run main TestListPackageFromAPI + */ + +import com.sun.source.util.JavacTask; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import javax.lang.model.element.PackageElement; +import javax.tools.DiagnosticListener; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +public class TestListPackageFromAPI { + + public static void main(String... args) throws IOException, URISyntaxException, InterruptedException { + try (JavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) { + List testClasses = List.of( + new TestFileObject("Test"), + new TestFileObject("Test$Nested") + ); + List testSources = List.of( + new TestFileObject("Test", + """ + class Test { + public static class Nested {} + } + """) + ); + JavaFileManager testFM = new ForwardingJavaFileManagerImpl(fm, testClasses, testSources); + DiagnosticListener noErrors = d -> { throw new AssertionError("Should not happen: " + d); }; + JavacTask task = (JavacTask) ToolProvider.getSystemJavaCompiler().getTask(null, testFM, noErrors, null, null, List.of(new TestFileObject("Input", ""))); + PackageElement pack = task.getElements().getPackageElement(""); + pack.getEnclosedElements().forEach(e -> System.err.println(e)); + } + } + + private static class TestFileObject extends SimpleJavaFileObject { + + private final String className; + private final String code; + + public TestFileObject(String className) throws URISyntaxException { + super(new URI("mem://" + className + ".class"), Kind.CLASS); + this.className = className; + this.code = null; + } + + public TestFileObject(String className, String code) throws URISyntaxException { + super(new URI("mem://" + className + ".java"), Kind.SOURCE); + this.className = className; + this.code = code; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + if (code == null) { + throw new UnsupportedOperationException(); + } + return code; + } + + @Override + public long getLastModified() { + return getKind() == Kind.CLASS ? 0 : 1000; + } + + } + + private static class ForwardingJavaFileManagerImpl extends ForwardingJavaFileManager { + + private final List testClasses; + private final List testSources; + + public ForwardingJavaFileManagerImpl(JavaFileManager fileManager, List testClasses, List testSources) { + super(fileManager); + this.testClasses = testClasses; + this.testSources = testSources; + } + + @Override + public Iterable list(JavaFileManager.Location location, String packageName, Set kinds, boolean recurse) throws IOException { + if (packageName.isEmpty()) { + List result = new ArrayList<>(); + if (location == StandardLocation.CLASS_PATH && kinds.contains(Kind.CLASS)) { + result.addAll(testClasses); + } else if (location == StandardLocation.SOURCE_PATH && kinds.contains(Kind.SOURCE)) { + result.addAll(testSources); + } + return result; + } + return super.list(location, packageName, kinds, recurse); + } + + @Override + public boolean hasLocation(Location location) { + return location == StandardLocation.CLASS_PATH || + location == StandardLocation.SOURCE_PATH || + super.hasLocation(location); + } + + @Override + public String inferBinaryName(JavaFileManager.Location location, JavaFileObject file) { + if (file instanceof TestFileObject testFO) { + return testFO.className; + } + return super.inferBinaryName(location, file); + } + } +} diff --git a/test/langtools/tools/javac/sealed/MissingPermittedSubtypes.java b/test/langtools/tools/javac/sealed/MissingPermittedSubtypes.java new file mode 100644 index 0000000000000000000000000000000000000000..ba75407099a7f0c08d9d2864f0e1be426c090279 --- /dev/null +++ b/test/langtools/tools/javac/sealed/MissingPermittedSubtypes.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 8277105 + * @summary Verify missing permitted subtype is handled properly for both casts and pattern switches. + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * @build toolbox.ToolBox toolbox.JavacTask + * @run main MissingPermittedSubtypes +*/ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import toolbox.TestRunner; +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.ToolBox; + +public class MissingPermittedSubtypes extends TestRunner { + + private static final String JAVA_VERSION = System.getProperty("java.specification.version"); + + ToolBox tb; + + public static void main(String... args) throws Exception { + new MissingPermittedSubtypes().runTests(); + } + + MissingPermittedSubtypes() { + super(System.err); + tb = new ToolBox(); + } + + public void runTests() throws Exception { + runTests(m -> new Object[] { Paths.get(m.getName()) }); + } + + @Test + public void testInaccessiblePermitted(Path base) throws IOException { + Path current = base.resolve("."); + Path libSrc = current.resolve("lib-src"); + + tb.writeJavaFiles(libSrc, + """ + package lib; + public sealed interface S permits A, B1, B2 {} + """, + """ + package lib; + public final class A implements S {} + """, + """ + package lib; + final class B1 implements S {} + """, + """ + package lib; + final class B2 implements S, Runnable { + public void run() {} + } + """); + + Path libClasses = current.resolve("libClasses"); + + Files.createDirectories(libClasses); + + new JavacTask(tb) + .options("--enable-preview", + "-source", JAVA_VERSION) + .outdir(libClasses) + .files(tb.findJavaFiles(libSrc)) + .run(); + + Path b1Class = libClasses.resolve("lib").resolve("B1.class"); + + Files.delete(b1Class); + + Path b2Class = libClasses.resolve("lib").resolve("B2.class"); + + Files.delete(b2Class); + + { + Path src1 = current.resolve("src1"); + tb.writeJavaFiles(src1, + """ + package test; + import lib.*; + public class Test1 { + private void test(S obj) { + int i = switch (obj) { + case A a -> 0; + }; + Runnable r = () -> {obj = null;}; + } + } + """); + + Path classes1 = current.resolve("classes1"); + + Files.createDirectories(classes1); + + var log = + new JavacTask(tb) + .options("--enable-preview", + "-source", JAVA_VERSION, + "-XDrawDiagnostics", + "-Xlint:-preview", + "--class-path", libClasses.toString()) + .outdir(classes1) + .files(tb.findJavaFiles(src1)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + List expectedErrors = List.of( + "Test1.java:5:24: compiler.err.cant.access: lib.B1, (compiler.misc.class.file.not.found: lib.B1)", + "Test1.java:8:29: compiler.err.cant.ref.non.effectively.final.var: obj, (compiler.misc.lambda)", + "- compiler.note.preview.filename: Test1.java, DEFAULT", + "- compiler.note.preview.recompile", + "2 errors"); + + if (!expectedErrors.equals(log)) { + throw new AssertionError("Incorrect errors, expected: " + expectedErrors + + ", actual: " + log); + } + } + + { + Path src2 = current.resolve("src2"); + tb.writeJavaFiles(src2, + """ + package test; + import lib.*; + public class Test1 { + private void test(S obj) { + Runnable r = (Runnable) obj; + String s = (String) obj; + } + } + """); + + Path classes2 = current.resolve("classes2"); + + Files.createDirectories(classes2); + + var log = + new JavacTask(tb) + .options("--enable-preview", + "-source", JAVA_VERSION, + "-XDrawDiagnostics", + "-Xlint:-preview", + "--class-path", libClasses.toString()) + .outdir(classes2) + .files(tb.findJavaFiles(src2)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + List expectedErrors = List.of( + "Test1.java:5:19: compiler.err.cant.access: lib.B1, (compiler.misc.class.file.not.found: lib.B1)", + "Test1.java:6:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: lib.S, java.lang.String)", + "2 errors"); + + if (!expectedErrors.equals(log)) { + throw new AssertionError("Incorrect errors, expected: " + expectedErrors + + ", actual: " + log); + } + } + } + +} diff --git a/test/langtools/tools/javac/versions/Versions.java b/test/langtools/tools/javac/versions/Versions.java index 7b75896bab75ee6a77f9b1b1d23f0eccbe30c216..78185eba484b786c0a393ffd6fa0ab3e2bb065fc 100644 --- a/test/langtools/tools/javac/versions/Versions.java +++ b/test/langtools/tools/javac/versions/Versions.java @@ -71,9 +71,9 @@ public class Versions { public static final Set VALID_SOURCES = Set.of("1.7", "1.8", "1.9", "1.10", "11", "12", "13", "14", - "15", "16", "17", "18"); + "15", "16", "17", "18", "19"); - public static final String LATEST_MAJOR_VERSION = "62.0"; + public static final String LATEST_MAJOR_VERSION = "63.0"; static enum SourceTarget { SEVEN(true, "51.0", "7", Versions::checksrc7), @@ -87,7 +87,8 @@ public class Versions { FIFTEEN(false, "59.0", "15", Versions::checksrc15), SIXTEEN(false, "60.0", "16", Versions::checksrc16), SEVENTEEN(false, "61.0", "17", Versions::checksrc17), - EIGHTEEN(false, "62.0", "18", Versions::checksrc18); + EIGHTEEN(false, "62.0", "18", Versions::checksrc18), + NINETEEN(false, "63.0", "19", Versions::checksrc19); private final boolean dotOne; private final String classFileVer; @@ -320,6 +321,13 @@ public class Versions { // Add expectedFail after new language features added in a later release. } + protected void checksrc19(List args) { + printargs("checksrc19", args); + expectedPass(args, List.of("New7.java", "New8.java", "New10.java", "New11.java", + "New14.java", "New15.java", "New16.java", "New17.java")); + // Add expectedFail after new language features added in a later release. + } + protected void expected(List args, List fileNames, Consumer> passOrFail) { ArrayList fullArguments = new ArrayList<>(args); diff --git a/test/langtools/tools/lib/snippets/SnippetUtils.java b/test/langtools/tools/lib/snippets/SnippetUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..21e8bbabf1800eb8124ee2d17fc1eefa35377a1c --- /dev/null +++ b/test/langtools/tools/lib/snippets/SnippetUtils.java @@ -0,0 +1,543 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package snippets; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.ModuleElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.util.Elements; +import javax.lang.model.util.SimpleElementVisitor14; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.DiagnosticListener; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +import com.sun.source.doctree.AttributeTree; +import com.sun.source.doctree.DocCommentTree; +import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.SnippetTree; +import com.sun.source.doctree.TextTree; +import com.sun.source.util.DocTreeScanner; +import com.sun.source.util.DocTrees; +import com.sun.source.util.JavacTask; + +/** + * Utilities for analyzing snippets. + * + * Support is provided for the following: + *
          + *
        • creating an instance of {@link JavacTask} suitable for looking up + * elements by name, in order to access any corresponding documentation comment, + *
        • scanning elements to find all associated snippets, + *
        • locating instances of snippets by their {@code id}, + *
        • parsing snippets, and + *
        • accessing the body of snippets, for any additional analysis. + *
        + * + * @apiNote + * The utilities do not provide support for compiling and running snippets, + * because in general, this requires too much additional context. However, + * the utilities do provide support for locating snippets in various ways, + * and accessing the body of those snippets, to simplify the task of writing + * code to compile and run snippets, where that is appropriate. + */ +public class SnippetUtils { + private static final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + + private final StandardJavaFileManager fileManager; + private final Path srcDir; + private final JavacTask javacTask; + private final Elements elements; + private final DocTrees docTrees; + + /** + * Creates an instance for analysing snippets in one or more JDK modules. + * + * The source for the modules is derived from the value of the + * {@code test.src} system property. + * + * Any messages, including error messages, will be written to {@code System.err}. + * + * @param modules the modules + * + * @throws IllegalArgumentException if no modules are specified + */ + public SnippetUtils(String... modules) { + this(findSourceDir(), null, null, Set.of(modules)); + } + + /** + * Creates an instance for analysing snippets in one or more modules. + * + * @param srcDir the location for the source of the modules; + * the location for the source of a specific module should be + * in srcDir{@code /}module{@code /share/module} + * + * @param pw a writer for any text messages that may be generated; + * if null, messages will be written to {@code System.err} + * + * @param dl a diagnostic listener for any diagnostic messages that may be generated; + * if null, messages will be written to {@code System.err} + * + * @param modules the modules + * + * @throws IllegalArgumentException if no modules are specified + */ + public SnippetUtils(Path srcDir, PrintWriter pw, DiagnosticListener dl, Set modules) { + if (modules.isEmpty()) { + throw new IllegalArgumentException("no modules specified"); + } + + this.srcDir = srcDir; + fileManager = compiler.getStandardFileManager(dl, null, null); + + List opts = new ArrayList<>(); + opts.addAll(List.of("--add-modules", String.join(",", modules))); // could use CompilationTask.addModules + modules.forEach(m -> opts.addAll(List.of("--patch-module", m + "=" + getModuleSourceDir(m)))); + opts.add("-proc:only"); + + javacTask = (JavacTask) compiler.getTask(pw, fileManager, dl, opts, null, null); + elements = javacTask.getElements(); + elements.getModuleElement("java.base"); // forces module graph to be instantiated, etc + + docTrees = DocTrees.instance(javacTask); + } + + /** + * {@return the source directory for the task used to access snippets} + */ + public Path getSourceDir() { + return srcDir; + } + + /** + * {@return the file manager for the task used to access snippets} + */ + public StandardJavaFileManager getFileManager() { + return fileManager; + } + + /** + * {@return the instance of {@code Elements} for the task used to access snippets} + */ + public Elements getElements() { + return elements; + } + + /** + * {@return the instance of {@code DocTrees} for the task used to access snippets} + */ + public DocTrees getDocTrees() { + return docTrees; + } + + /** + * {@return the doc comment tree for an element} + * + * @param element the element + */ + public DocCommentTree getDocCommentTree(Element element) { + return docTrees.getDocCommentTree(element); + } + + /** + * {@return the snippet with a given id in a doc comment tree} + * + * @param tree the doc comment tree + * @param id the id + */ + public SnippetTree getSnippetById(DocCommentTree tree, String id) { + return new SnippetFinder().scan(tree, id); + } + + /** + * {@return the snippet with a given id in the doc comment tree for an element} + * + * @param element the element + * @param id the id + */ + public SnippetTree getSnippetById(Element element, String id) { + DocCommentTree tree = getDocCommentTree(element); + return new SnippetFinder().scan(tree, id); + } + + /** + * A scanner to locate the tree for a snippet with a given id. + * Note: the scanner is use-once. + */ + private static class SnippetFinder extends DocTreeScanner { + private SnippetTree result; + private SnippetTree inSnippet; + + @Override + public SnippetTree scan(DocTree tree, String id) { + // stop scanning once the result has been found + return result != null ? result : super.scan(tree, id); + } + + @Override + public SnippetTree visitSnippet(SnippetTree tree, String id) { + inSnippet = tree; + try { + return super.visitSnippet(tree, id); + } finally { + inSnippet = null; + } + } + + @Override + public SnippetTree visitAttribute(AttributeTree tree, String id) { + if (tree.getName().contentEquals("id") + && tree.getValue().toString().equals(id)) { + result = inSnippet; + return result; + } else { + return null; + } + } + } + + /** + * Scans an element and appropriate enclosed elements for doc comments, + * and call a handler to handle any snippet trees in those doc comments. + * + * Only the public and protected members of type elements are scanned. + * The enclosed elements of modules and packages are not scanned. + * + * @param element the element + * @param handler the handler + * @throws IllegalArgumentException if any inappropriate element is scanned + */ + public void scan(Element element, BiConsumer handler) { + new ElementScanner(docTrees).scan(element, handler); + } + + private static class ElementScanner extends SimpleElementVisitor14> { + private final DocTrees trees; + + public ElementScanner(DocTrees trees) { + this.trees = trees; + } + + public void scan(Element e, BiConsumer snippetHandler) { + visit(e, new DocTreeScanner<>() { + @Override + public Void visitSnippet(SnippetTree tree, Element e) { + snippetHandler.accept(e, tree); + return null; + } + }); + } + + @Override + public Void visitModule(ModuleElement me, DocTreeScanner treeScanner) { + scanDocComment(me, treeScanner); + return null; + } + + @Override + public Void visitPackage(PackageElement pe, DocTreeScanner treeScanner) { + scanDocComment(pe, treeScanner); + return null; + } + + @Override + public Void visitType(TypeElement te, DocTreeScanner treeScanner) { + scanDocComment(te, treeScanner); + for (Element e : te.getEnclosedElements()) { + Set mods = e.getModifiers(); + if (mods.contains(Modifier.PUBLIC) || mods.contains(Modifier.PROTECTED)) { + e.accept(this, treeScanner); + } + } + return null; + } + + @Override + public Void visitExecutable(ExecutableElement ee, DocTreeScanner treeScanner) { + scanDocComment(ee, treeScanner); + return null; + } + + @Override + public Void visitVariable(VariableElement ve, DocTreeScanner treeScanner) { + switch (ve.getKind()) { + case ENUM_CONSTANT, FIELD -> scanDocComment(ve, treeScanner); + default -> defaultAction(ve, treeScanner); + } + return null; + } + + @Override + public Void defaultAction(Element e, DocTreeScanner treeScanner) { + throw new IllegalArgumentException(e.getKind() + " " + e.getSimpleName()); + } + + private void scanDocComment(Element e, DocTreeScanner treeScanner) { + DocCommentTree dc = trees.getDocCommentTree(e); + if (dc != null) { + treeScanner.scan(dc, e); + } + } + } + + /** + * {@return the string content of an inline or hybrid snippet, or {@code null} for an external snippet} + * + * @param tree the snippet + */ + public String getBody(SnippetTree tree) { + TextTree body = tree.getBody(); + return body == null ? null : body.getBody(); + } + + /** + * {@return the string content of an external or inline snippet} + * + * @param element the element whose documentation contains the snippet + * @param tree the snippet + */ + public String getBody(Element element, SnippetTree tree) throws IOException { + Path externalSnippetPath = getExternalSnippetPath(element, tree); + return externalSnippetPath == null ? getBody(tree) : Files.readString(externalSnippetPath); + } + + /** + * {@return the path for the {@code snippet-files} directory for an element} + * + * @param element the element + * + * @return the path + */ + public Path getSnippetFilesDir(Element element) { + var moduleElem = elements.getModuleOf(element); + var modulePath = getModuleSourceDir(moduleElem); + + var packageElem = elements.getPackageOf(element); // null for a module + var packagePath = packageElem == null + ? modulePath + : modulePath.resolve(packageElem.getQualifiedName().toString().replace(".", File.separator)); + + return packagePath.resolve("snippet-files"); + } + + /** + * {@return the path for an external snippet, or {@code null} if the snippet is inline} + * + * @param element the element whose documentation contains the snippet + * @param tree the snippet + */ + public Path getExternalSnippetPath(Element element, SnippetTree tree) { + var classAttr = getAttr(tree, "class"); + String file = (classAttr != null) + ? classAttr.replace(".", "/") + ".java" + : getAttr(tree, "file"); + return file == null ? null : getSnippetFilesDir(element).resolve(file.replace("/", File.separator)); + } + + /** + * {@return the value of an attribute defined by a snippet} + * + * @param tree the snippet + * @param name the name of the attribute + */ + public String getAttr(SnippetTree tree, String name) { + for (DocTree t : tree.getAttributes()) { + if (t instanceof AttributeTree at && at.getName().contentEquals(name)) { + return at.getValue().toString(); + } + } + return null; + } + + /** + * {@return the primary source directory for a module} + * + * The directory is srcDir/module-name/share/classes. + * + * @param e the module + */ + public Path getModuleSourceDir(ModuleElement e) { + return getModuleSourceDir(e.getQualifiedName().toString()); + } + + /** + * {@return the primary source directory for a module} + * + * The directory is srcDir/moduleName/share/classes. + * + * @param moduleName the module name + */ + public Path getModuleSourceDir(String moduleName) { + return srcDir.resolve(moduleName).resolve("share").resolve("classes"); + } + + /** + * Kinds of fragments of source code. + */ + public enum SourceKind { + /** A module declaration. */ + MODULE_INFO, + /** A package declaration. */ + PACKAGE_INFO, + /** A class or interface declaration. */ + TYPE_DECL, + /** A member declaration for a class or interface. */ + MEMBER_DECL, + /** A statement, expression or other kind of fragment. */ + OTHER + } + + /** + * Parses a fragment of source code, after trying to infer the kind of the fragment. + * + * @param body the string to be parsed + * @param showDiag a function to handle any diagnostics that may be generated + * @return {@code true} if the parse succeeded, and {@code false} otherwise + * + * @throws IOException if an IO exception occurs + */ + public boolean parse(String body, Consumer> showDiag) throws IOException { + DiagnosticCollector collector = new DiagnosticCollector<>(); + parse(body, null, collector); + var diags = collector.getDiagnostics(); + diags.forEach(showDiag); + return diags.isEmpty(); + } + + /** + * Parses a fragment of source code, after trying to infer the kind of the fragment. + * + * @param body the string to be parsed + * @param pw a stream for diagnostics, or {@code null} to use {@code System.err} + * @param dl a diagnostic listener, or {@code null} to report diagnostics to {@code pw} or {@code System.err} + * @throws IOException if an IO exception occurs + */ + public void parse(String body, PrintWriter pw, DiagnosticListener dl) + throws IOException { + parse(inferSourceKind(body), body, pw, dl); + } + + /** + * Parses a fragment of source code of a given kind. + * + * @param kind the kind of code to be parsed + * @param body the string to be parsed + * @param pw a stream for diagnostics, or {@code null} to use {@code System.err} + * @param dl a diagnostic listener, or {@code null} to report diagnostics to {@code pw} or {@code System.err}. + * @throws IOException if an IO exception occurs + */ + public void parse(SourceKind kind, String body, PrintWriter pw, DiagnosticListener dl) + throws IOException { + String fileBase = switch (kind) { + case MODULE_INFO -> "module-info"; + case PACKAGE_INFO -> "package-info"; + default -> "C"; // the exact name doesn't matter if just parsing (the filename check for public types comes later on) + }; + URI uri = URI.create("mem://%s.java".formatted(fileBase)); + + String compUnit = switch (kind) { + case MODULE_INFO, PACKAGE_INFO, TYPE_DECL -> body; + case MEMBER_DECL -> """ + class C { + %s + }""".formatted(body); + case OTHER -> """ + class C { + void m() { + %s + ; + } + }""".formatted(body); + }; + JavaFileObject fo = new SimpleJavaFileObject(uri, JavaFileObject.Kind.SOURCE) { + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return compUnit; + } + }; + + JavaFileManager fm = compiler.getStandardFileManager(dl, null, null); + + List opts = new ArrayList<>(); + JavacTask javacTask = (JavacTask) compiler.getTask(pw, fm, dl, opts, null, List.of(fo)); + + javacTask.parse(); + } + + public SourceKind inferSourceKind(String s) { + Pattern typeDecl = Pattern.compile("(?s)(^|\\R)([A-Za-z0-9_$ ])*\\b(?module|package|class|interface|record|enum)\\s+(?[A-Za-z0-9_$]+)"); + Matcher m1 = typeDecl.matcher(s); + if (m1.find()) { + return switch (m1.group("kw")) { + case "module" -> SourceKind.MODULE_INFO; + case "package" -> m1.find() ? SourceKind.TYPE_DECL : SourceKind.PACKAGE_INFO; + default -> SourceKind.TYPE_DECL; + }; + } + + Pattern methodDecl = Pattern.compile("(?s)(^|\\R)([A-Za-z0-9<>,]+ )+\\b(?[A-Za-z0-9_$]+)([(;]| +=)"); + Matcher m2 = methodDecl.matcher(s); + if (m2.find()) { + return SourceKind.MEMBER_DECL; + } + + return SourceKind.OTHER; + } + + private static Path findSourceDir() { + String testSrc = System.getProperty("test.src"); + Path p = Path.of(testSrc).toAbsolutePath(); + while (p.getParent() != null) { + Path srcDir = p.resolve("src"); + if (Files.exists(srcDir.resolve("java.base"))) { + return srcDir; + } + p = p.getParent(); + } + throw new IllegalArgumentException("Cannot find src/ from " + testSrc); + } +} \ No newline at end of file diff --git a/test/lib-test/jdk/test/lib/AssertsTest.java b/test/lib-test/jdk/test/lib/AssertsTest.java index 86b1a7fb8c7d5a12864bd027d14067dd1a1524a3..a4c739d64bae8250f587a5b25abd207e46726980 100644 --- a/test/lib-test/jdk/test/lib/AssertsTest.java +++ b/test/lib-test/jdk/test/lib/AssertsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ public class AssertsTest { } public int compareTo(Foo f) { - return new Integer(id).compareTo(new Integer(f.id)); + return Integer.valueOf(id).compareTo(Integer.valueOf(f.id)); } public String toString() { return "Foo(" + Integer.toString(id) + ")"; diff --git a/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java b/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java index 4be69a6566c8cf0fc3b9879d39f4ef70d8cb7505..3ca1de653a4f7e25112833d39ea693b08d59ea43 100644 --- a/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java +++ b/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ public class TestMutuallyExclusivePlatformPredicates { IGNORED("isEmulatedClient", "isDebugBuild", "isFastDebugBuild", "isSlowDebugBuild", "hasSA", "isRoot", "isTieredSupported", "areCustomLoadersSupportedForCDS", "isDefaultCDSArchiveSupported", - "isSignedOSX"); + "isHardenedOSX"); public final List methodNames; diff --git a/test/lib-test/jdk/test/lib/TestPlatformIsTieredSupported.java b/test/lib-test/jdk/test/lib/TestPlatformIsTieredSupported.java index 8f57ab64eaf5b5960eb442a24f35fccfbee627df..8c0c8ea3c189cf807dc973778a128bc838996faf 100644 --- a/test/lib-test/jdk/test/lib/TestPlatformIsTieredSupported.java +++ b/test/lib-test/jdk/test/lib/TestPlatformIsTieredSupported.java @@ -39,6 +39,7 @@ import sun.hotspot.WhiteBox; */ public class TestPlatformIsTieredSupported { public static void main(String args[]) { + @SuppressWarnings("deprecation") WhiteBox whiteBox = WhiteBox.getWhiteBox(); boolean tieredCompilation = whiteBox.getBooleanVMFlag( "TieredCompilation"); diff --git a/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java b/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java index 7b7dfc086f18b033d57d1266146e8d445fbdb6b8..c52fcd78f9324d03daac00fd287cdd6c780e971a 100644 --- a/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java +++ b/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -274,6 +274,7 @@ public class ArrayDiffTest { class StrObj { private final String value; public boolean equals(Object another) { return ((StrObj)another).value.equals(value); } + public int hashCode() { return value.hashCode(); } public StrObj(String value) { this.value = value; } public String toString() { return value; } } @@ -363,7 +364,7 @@ public class ArrayDiffTest { } public void assertTwoWay() { - ArrayDiff diff; + ArrayDiff diff; // Direct if (defaultParameters) { diff --git a/test/lib-test/jdk/test/whitebox/OldWhiteBox.java b/test/lib-test/jdk/test/whitebox/OldWhiteBox.java index 677ed210f692bbecf15f63c4cecfc85a8ae18282..41af4698e9843bbd12c8a169d41240b70eab4c9b 100644 --- a/test/lib-test/jdk/test/whitebox/OldWhiteBox.java +++ b/test/lib-test/jdk/test/whitebox/OldWhiteBox.java @@ -43,6 +43,7 @@ import sun.hotspot.WhiteBox; public class OldWhiteBox { public static void main(String[] args) { + @SuppressWarnings("deprecation") WhiteBox wb = WhiteBox.getWhiteBox(); if (wb.getHeapOopSize() < 0) { throw new Error("wb.getHeapOopSize() < 0"); diff --git a/test/lib-test/jdk/test/whitebox/vm_flags/VmFlagTest.java b/test/lib-test/jdk/test/whitebox/vm_flags/VmFlagTest.java index d48aab6cf26f10b59eba71635b817f8aef8bd545..7290cd1096c1534652d55e47cea75322c923f8ee 100644 --- a/test/lib-test/jdk/test/whitebox/vm_flags/VmFlagTest.java +++ b/test/lib-test/jdk/test/whitebox/vm_flags/VmFlagTest.java @@ -72,9 +72,9 @@ public final class VmFlagTest { protected static void runTest(String existentFlag, T[] tests, T[] results, BiConsumer set, Function get) { if (existentFlag != null) { - new VmFlagTest(existentFlag, set, get, true).test(tests, results); + new VmFlagTest(existentFlag, set, get, true).test(tests, results); } - new VmFlagTest(NONEXISTENT_FLAG, set, get, false).test(tests, results); + new VmFlagTest(NONEXISTENT_FLAG, set, get, false).test(tests, results); } public final void test(T[] tests, T[] results) { diff --git a/test/lib/RedefineClassHelper.java b/test/lib/RedefineClassHelper.java index 0fcfc52f0c1b436fde6997a61a9033181ed1ca74..91b255828739f5dd2a1d6d06ca38dcd4277f3569 100644 --- a/test/lib/RedefineClassHelper.java +++ b/test/lib/RedefineClassHelper.java @@ -47,7 +47,7 @@ public class RedefineClassHelper { * @param clazz Class to redefine * @param javacode String with the new java code for the class to be redefined */ - public static void redefineClass(Class clazz, String javacode) throws Exception { + public static void redefineClass(Class clazz, String javacode) throws Exception { byte[] bytecode = InMemoryJavaCompiler.compile(clazz.getName(), javacode); redefineClass(clazz, bytecode); } @@ -58,7 +58,7 @@ public class RedefineClassHelper { * @param clazz Class to redefine * @param bytecode byte[] with the new class */ - public static void redefineClass(Class clazz, byte[] bytecode) throws Exception { + public static void redefineClass(Class clazz, byte[] bytecode) throws Exception { instrumentation.redefineClasses(new ClassDefinition(clazz, bytecode)); } diff --git a/test/lib/jdk/test/lib/NetworkConfiguration.java b/test/lib/jdk/test/lib/NetworkConfiguration.java index 716e2aed3d59bbfd1b3b14041b3dfd932cffa3eb..386a2bf0a6f084ca46ff90e40c9f35fdd5f621d8 100644 --- a/test/lib/jdk/test/lib/NetworkConfiguration.java +++ b/test/lib/jdk/test/lib/NetworkConfiguration.java @@ -451,6 +451,7 @@ public class NetworkConfiguration { } /** Prints all the system interface information to the give stream. */ + @SuppressWarnings("removal") public static void printSystemConfiguration(PrintStream out) { PrivilegedAction pa = () -> { try { diff --git a/test/lib/jdk/test/lib/Platform.java b/test/lib/jdk/test/lib/Platform.java index 7666fdcc459df904770183fdb7ddf71d886ff339..a8405c937226a178dabc5c60cd4a3e53ff427430 100644 --- a/test/lib/jdk/test/lib/Platform.java +++ b/test/lib/jdk/test/lib/Platform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,10 @@ package jdk.test.lib; +import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -242,13 +244,13 @@ public class Platform { } /** - * Return true if the test JDK is signed, otherwise false. Only valid on OSX. + * Return true if the test JDK is hardened, otherwise false. Only valid on OSX. */ - public static boolean isSignedOSX() throws IOException { - // We only care about signed binaries for 10.14 and later (actually 10.14.5, but + public static boolean isHardenedOSX() throws IOException { + // We only care about hardened binaries for 10.14 and later (actually 10.14.5, but // for simplicity we'll also include earlier 10.14 versions). if (getOsVersionMajor() == 10 && getOsVersionMinor() < 14) { - return false; // assume not signed + return false; // assume not hardened } // Find the path to the java binary. @@ -260,38 +262,45 @@ public class Platform { } // Run codesign on the java binary. - ProcessBuilder pb = new ProcessBuilder("codesign", "-d", "-v", javaFileName); - pb.redirectError(ProcessBuilder.Redirect.DISCARD); - pb.redirectOutput(ProcessBuilder.Redirect.DISCARD); + ProcessBuilder pb = new ProcessBuilder("codesign", "--display", "--verbose", javaFileName); + pb.redirectErrorStream(true); // redirect stderr to stdout Process codesignProcess = pb.start(); + BufferedReader is = new BufferedReader(new InputStreamReader(codesignProcess.getInputStream())); + String line; + boolean isHardened = false; + boolean hardenedStatusConfirmed = false; // set true when we confirm whether or not hardened + while ((line = is.readLine()) != null) { + System.out.println("STDOUT: " + line); + if (line.indexOf("flags=0x10000(runtime)") != -1 ) { + hardenedStatusConfirmed = true; + isHardened = true; + System.out.println("Target JDK is hardened. Some tests may be skipped."); + } else if (line.indexOf("flags=0x20002(adhoc,linker-signed)") != -1 ) { + hardenedStatusConfirmed = true; + isHardened = false; + System.out.println("Target JDK is adhoc signed, but not hardened."); + } else if (line.indexOf("code object is not signed at all") != -1) { + hardenedStatusConfirmed = true; + isHardened = false; + System.out.println("Target JDK is not signed, therefore not hardened."); + } + } + if (!hardenedStatusConfirmed) { + System.out.println("Could not confirm if TargetJDK is hardened. Assuming not hardened."); + isHardened = false; + } + try { if (codesignProcess.waitFor(10, TimeUnit.SECONDS) == false) { - System.err.println("Timed out waiting for the codesign process to complete. Assuming not signed."); + System.err.println("Timed out waiting for the codesign process to complete. Assuming not hardened."); codesignProcess.destroyForcibly(); - return false; // assume not signed + return false; // assume not hardened } } catch (InterruptedException e) { throw new RuntimeException(e); } - // Check codesign result to see if java binary is signed. Here are the - // exit code meanings: - // 0: signed - // 1: not signed - // 2: invalid arguments - // 3: only has meaning with the -R argument. - // So we should always get 0 or 1 as an exit value. - if (codesignProcess.exitValue() == 0) { - System.out.println("Target JDK is signed. Some tests may be skipped."); - return true; // signed - } else if (codesignProcess.exitValue() == 1) { - System.out.println("Target JDK is not signed."); - return false; // not signed - } else { - System.err.println("Executing codesign failed. Assuming unsigned: " + - codesignProcess.exitValue()); - return false; // not signed - } + return isHardened; } private static boolean isArch(String archnameRE) { diff --git a/test/lib/jdk/test/lib/SA/SATestUtils.java b/test/lib/jdk/test/lib/SA/SATestUtils.java index 0ba91f2a994fff1eb25a697aa617a4b20d04fb3d..2f98cf99357f4dda84f4e4f16b94cd6402254418 100644 --- a/test/lib/jdk/test/lib/SA/SATestUtils.java +++ b/test/lib/jdk/test/lib/SA/SATestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,8 +63,8 @@ public class SATestUtils { throw new SkippedException("SA Attach not expected to work. Ptrace attach not supported."); } } else if (Platform.isOSX()) { - if (Platform.isSignedOSX()) { - throw new SkippedException("SA Attach not expected to work. JDK is signed."); + if (Platform.isHardenedOSX()) { + throw new SkippedException("SA Attach not expected to work. JDK is hardened."); } if (!Platform.isRoot() && !canAddPrivileges()) { throw new SkippedException("SA Attach not expected to work. Insufficient privileges (not root and can't use sudo)."); @@ -159,6 +159,7 @@ public class SATestUtils { * if we are root, so return true. Then return false for an expected denial * if "ptrace_scope" is 1, and true otherwise. */ + @SuppressWarnings("removal") private static boolean canPtraceAttachLinux() throws IOException { // SELinux deny_ptrace: var deny_ptrace = Paths.get("/sys/fs/selinux/booleans/deny_ptrace"); diff --git a/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java b/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java index 30b919d81c879f62abb5cb5e77e634f9ef912651..f5c504ba1c84e8465d9f5828e1478c6d9a4e27f5 100644 --- a/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java +++ b/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,9 @@ import sun.hotspot.WhiteBox; // This class performs operations on shared archive file public class CDSArchiveUtils { + // Minimum supported CDS file header version + private static int genericHeaderMinVersion; // CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION + private static int currentCDSArchiveVersion; // CURRENT_CDS_ARCHIVE_VERSION // offsets private static int offsetMagic; // offset of GenericCDSFileMapHeader::_magic private static int offsetCrc; // offset of GenericCDSFileMapHeader::_crc @@ -82,6 +85,9 @@ public class CDSArchiveUtils { WhiteBox wb; try { wb = WhiteBox.getWhiteBox(); + // genericHeaderMinVersion + genericHeaderMinVersion = wb.getCDSGenericHeaderMinVersion(); + currentCDSArchiveVersion = wb.getCurrentCDSVersion(); // offsets offsetMagic = wb.getCDSOffsetForName("GenericCDSFileMapHeader::_magic"); offsetCrc = wb.getCDSOffsetForName("GenericCDSFileMapHeader::_crc"); @@ -116,6 +122,10 @@ public class CDSArchiveUtils { } // accessors + // minimum supported file header version + public static int getGenericHeaderMinVersion() { return genericHeaderMinVersion; } + // current CDS version + public static int getCurrentCDSArchiveVersion() { return currentCDSArchiveVersion; } // offsets public static int offsetMagic() { return offsetMagic; } public static int offsetCrc() { return offsetCrc; } @@ -331,6 +341,18 @@ public class CDSArchiveUtils { return newJsaFile; } + public static File createMagicOnlyFile(String fileName, boolean createStatic) throws Exception { + File file = new File(fileName); + if (file.exists()) { + file.delete(); + } + try (FileOutputStream out = new FileOutputStream(file)) { + ByteBuffer buffer = ByteBuffer.allocate(4).putInt(createStatic ? staticMagic: dynamicMagic); + out.write(buffer.array(), 0, 4); + } + return file; + } + private static FileChannel getFileChannel(File file, boolean write) throws Exception { List arry = new ArrayList(); arry.add(READ); diff --git a/test/lib/jdk/test/lib/cds/CDSTestUtils.java b/test/lib/jdk/test/lib/cds/CDSTestUtils.java index f7e263ba5c53a45a888e807573c072383f470383..f9391c96ee4ece72cdeceeb9024edda6da23a249 100644 --- a/test/lib/jdk/test/lib/cds/CDSTestUtils.java +++ b/test/lib/jdk/test/lib/cds/CDSTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,9 @@ import java.io.IOException; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.CopyOption; +import java.nio.file.StandardCopyOption; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -684,4 +687,78 @@ public class CDSTestUtils { private static boolean isAsciiPrintable(char ch) { return ch >= 32 && ch < 127; } + + // JDK utility + + // Do a cheap clone of the JDK. Most files can be sym-linked. However, $JAVA_HOME/bin/java and $JAVA_HOME/lib/.../libjvm.so" + // must be copied, because the java.home property is derived from the canonicalized paths of these 2 files. + // Set a list of {jvm, "java"} which will be physically copied. If a file needs copied physically, add it to the list. + private static String[] phCopied = {System.mapLibraryName("jvm"), "java"}; + public static void clone(File src, File dst) throws Exception { + if (dst.exists()) { + if (!dst.isDirectory()) { + throw new RuntimeException("Not a directory :" + dst); + } + } else { + if (!dst.mkdir()) { + throw new RuntimeException("Cannot create directory: " + dst); + } + } + // final String jvmLib = System.mapLibraryName("jvm"); + for (String child : src.list()) { + if (child.equals(".") || child.equals("..")) { + continue; + } + + File child_src = new File(src, child); + File child_dst = new File(dst, child); + if (child_dst.exists()) { + throw new RuntimeException("Already exists: " + child_dst); + } + if (child_src.isFile()) { + boolean needPhCopy = false; + for (String target : phCopied) { + if (child.equals(target)) { + needPhCopy = true; + break; + } + } + if (needPhCopy) { + Files.copy(child_src.toPath(), /* copy data to -> */ child_dst.toPath(), + new CopyOption[] { StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES}); + } else { + Files.createSymbolicLink(child_dst.toPath(), /* link to -> */ child_src.toPath()); + } + } else { + clone(child_src, child_dst); + } + } + } + + // modulesDir, like $JDK/lib + // oldName, module name under modulesDir + // newName, new name for oldName + public static void rename(File fromFile, File toFile) throws Exception { + if (!fromFile.exists()) { + throw new RuntimeException(fromFile.getName() + " does not exist"); + } + + if (toFile.exists()) { + throw new RuntimeException(toFile.getName() + " already exists"); + } + + boolean success = fromFile.renameTo(toFile); + if (!success) { + throw new RuntimeException("rename file " + fromFile.getName()+ " to " + toFile.getName() + " failed"); + } + } + + public static ProcessBuilder makeBuilder(String... args) throws Exception { + System.out.print("["); + for (String s : args) { + System.out.print(" " + s); + } + System.out.println(" ]"); + return new ProcessBuilder(args); + } } diff --git a/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java b/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java index 9444e4cc97b50f70889f8e9b231e158c7917d12b..3fe7b43a82402ce9374d90b8066b5246fc209975 100644 --- a/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java +++ b/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import javax.tools.ForwardingJavaFileManager; import javax.tools.FileObject; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; import javax.tools.SimpleJavaFileObject; @@ -106,7 +107,7 @@ public class InMemoryJavaCompiler { } } - private static class FileManagerWrapper extends ForwardingJavaFileManager { + private static class FileManagerWrapper extends ForwardingJavaFileManager { private static final Location PATCH_LOCATION = new Location() { @Override public String getName() { diff --git a/test/lib/jdk/test/lib/format/ArrayCodec.java b/test/lib/jdk/test/lib/format/ArrayCodec.java index 0e34e7cd811226da3ff0e3754c2cd097932fe9df..8c2b1013204116062fa266baa4f7250f1dc96d3d 100644 --- a/test/lib/jdk/test/lib/format/ArrayCodec.java +++ b/test/lib/jdk/test/lib/format/ArrayCodec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,7 +141,7 @@ public class ArrayCodec { * @throws IllegalArgumentException if {@code array}'s component type is not supported * @return an ArrayCodec for the provided array */ - public static ArrayCodec of(Object array) { + public static ArrayCodec of(Object array) { var type = array.getClass().getComponentType(); if (type == byte.class) { return ArrayCodec.of((byte[])array); diff --git a/test/lib/jdk/test/lib/format/ArrayDiff.java b/test/lib/jdk/test/lib/format/ArrayDiff.java index 6755a693b7c8340c01477b7dd9bcd3c98e332182..1b86e4d7578983f8fc906a8933c51981563f4de4 100644 --- a/test/lib/jdk/test/lib/format/ArrayDiff.java +++ b/test/lib/jdk/test/lib/format/ArrayDiff.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,7 +93,7 @@ public class ArrayDiff implements Diff { * @param second the second array * @return an ArrayDiff instance for the two arrays */ - public static ArrayDiff of(Object first, Object second) { + public static ArrayDiff of(Object first, Object second) { return ArrayDiff.of(first, second, Diff.Defaults.WIDTH, Diff.Defaults.CONTEXT_BEFORE); } @@ -109,7 +109,8 @@ public class ArrayDiff implements Diff { * @throws NullPointerException if at least one of the arrays is null * @return an ArrayDiff instance for the two arrays and formatting parameters provided */ - public static ArrayDiff of(Object first, Object second, int width, int contextBefore) { + @SuppressWarnings("rawtypes") + public static ArrayDiff of(Object first, Object second, int width, int contextBefore) { Objects.requireNonNull(first); Objects.requireNonNull(second); @@ -204,4 +205,3 @@ public class ArrayDiff implements Diff { } } - diff --git a/test/lib/jdk/test/lib/hexdump/ASN1Formatter.java b/test/lib/jdk/test/lib/hexdump/ASN1Formatter.java index 5001978b8603c33dc87e004e13983a7baf1f8b77..ad96466d75f9977da4bcacc83715d5e90f415655 100644 --- a/test/lib/jdk/test/lib/hexdump/ASN1Formatter.java +++ b/test/lib/jdk/test/lib/hexdump/ASN1Formatter.java @@ -626,6 +626,7 @@ public class ASN1Formatter implements HexPrinter.Formatter { * @return the InputStream or the wrapped decoder of Base64Mime. * @throws IOException if an I/O error occurs */ + @SuppressWarnings("deprecation") private static InputStream wrapIfBase64Mime(BufferedInputStream bis) throws IOException { bis.mark(256); DataInputStream dis = new DataInputStream(bis); diff --git a/test/lib/jdk/test/lib/hexdump/StreamDump.java b/test/lib/jdk/test/lib/hexdump/StreamDump.java index 21ad296bca8c413e4bf78d7c395b798b16279f5c..cbdef1f61dc4d6f60fa51edfbb2cf18091242217 100644 --- a/test/lib/jdk/test/lib/hexdump/StreamDump.java +++ b/test/lib/jdk/test/lib/hexdump/StreamDump.java @@ -165,6 +165,7 @@ public class StreamDump { * @return an InputStream, unchanged unless it is Base64 Mime * @throws IOException if an I/O Error occurs */ + @SuppressWarnings("deprecation") static InputStream decodeMaybe(InputStream is) throws IOException { DataInputStream dis = new DataInputStream(is); is.mark(1024); diff --git a/test/lib/jdk/test/lib/jfr/StreamingUtils.java b/test/lib/jdk/test/lib/jfr/StreamingUtils.java index cb95c3d25d89f4be3d4c802af16d031775548842..427a4eb4262fb7790aa81d91106550e81c0331c0 100644 --- a/test/lib/jdk/test/lib/jfr/StreamingUtils.java +++ b/test/lib/jdk/test/lib/jfr/StreamingUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,16 +43,18 @@ public class StreamingUtils { public static Path getJfrRepository(Process process) throws Exception { while (true) { if (!process.isAlive()) { - String msg = String.format("Process (pid = %d) is no longer alive, exit value = %d", + String msg = String.format("Process (pid = %d) is no longer alive, exit value = %d\n", process.pid(), process.exitValue()); + msg += "Stderr: " + new String(process.getErrorStream().readAllBytes()) + "\n"; + msg += "Stdout: " + new String(process.getInputStream().readAllBytes()) + "\n"; throw new RuntimeException(msg); } try { VirtualMachine vm = VirtualMachine.attach(String.valueOf(process.pid())); String repo = vm.getSystemProperties().getProperty("jdk.jfr.repository"); + vm.detach(); if (repo != null) { - vm.detach(); System.out.println("JFR repository: " + repo); return Paths.get(repo); } diff --git a/test/lib/jdk/test/lib/net/IPSupport.java b/test/lib/jdk/test/lib/net/IPSupport.java index b86354a2503e0d12b1bd9ef89d09c2a915494da7..78efba3a172aafebd7f4b01acd4a277177f31e44 100644 --- a/test/lib/jdk/test/lib/net/IPSupport.java +++ b/test/lib/jdk/test/lib/net/IPSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,6 +71,7 @@ public class IPSupport { } } + @SuppressWarnings("removal") private static T runPrivilegedAction(Callable callable) { try { PrivilegedExceptionAction pa = () -> callable.call(); diff --git a/test/lib/jdk/test/lib/net/SimpleSSLContext.java b/test/lib/jdk/test/lib/net/SimpleSSLContext.java index 5660ed048aa64bda61a472785b31ee064b5cccce..e8611fb007f32d75e3fb86e4380cc284aecb0417 100644 --- a/test/lib/jdk/test/lib/net/SimpleSSLContext.java +++ b/test/lib/jdk/test/lib/net/SimpleSSLContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,6 +54,7 @@ public class SimpleSSLContext { this(() -> "TLS"); } + @SuppressWarnings("removal") private SimpleSSLContext(Supplier protocols) throws IOException { try { final String proto = protocols.get(); diff --git a/test/lib/jdk/test/lib/net/testkeys b/test/lib/jdk/test/lib/net/testkeys index 4673898e0ae15936ac8b83357b802dc425f0c64c..d2818ec9b6c6dd5386a2cabe53b923bf6046e577 100644 Binary files a/test/lib/jdk/test/lib/net/testkeys and b/test/lib/jdk/test/lib/net/testkeys differ diff --git a/test/lib/jdk/test/lib/process/Proc.java b/test/lib/jdk/test/lib/process/Proc.java index def8796fce86a23349b56a7486b16b890d74eaba..3541f34144fe0c09d1331615aece1ee75566a3b6 100644 --- a/test/lib/jdk/test/lib/process/Proc.java +++ b/test/lib/jdk/test/lib/process/Proc.java @@ -113,8 +113,8 @@ public class Proc { private List args = new ArrayList<>(); private Map env = new HashMap<>(); - private Map prop = new HashMap(); - private Map secprop = new HashMap(); + private Map prop = new HashMap<>(); + private Map secprop = new HashMap<>(); private boolean inheritIO = false; private boolean noDump = false; diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index 7998bbbbe8248ef328a1b4d3709313550f3e10a2..19e3bb54785fc66bad837a152e00a4aa20021d80 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -432,6 +432,7 @@ public final class ProcessTools { * the default charset. * @return The {@linkplain OutputAnalyzer} instance wrapping the process. */ + @SuppressWarnings("removal") public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input, Charset cs) throws Exception { OutputAnalyzer output = null; @@ -604,6 +605,7 @@ public final class ProcessTools { return pb; } + @SuppressWarnings("removal") private static Process privilegedStart(ProcessBuilder pb) throws IOException { try { return AccessController.doPrivileged( diff --git a/test/lib/jdk/test/lib/security/XMLUtils.java b/test/lib/jdk/test/lib/security/XMLUtils.java index bffab4be405797e4aa142a2c1a6ed71241df95d6..fa93e3f6b003207302f64c8032ddd1035d0be5f5 100644 --- a/test/lib/jdk/test/lib/security/XMLUtils.java +++ b/test/lib/jdk/test/lib/security/XMLUtils.java @@ -92,9 +92,11 @@ public class XMLUtils { Asserts.assertTrue(v2.validate(s3.sign(d))); // can read KeyInfo Asserts.assertTrue(v2.secureValidation(false).validate(s3.sign(p.toUri()))); // can read KeyInfo Asserts.assertTrue(v2.secureValidation(false).baseURI(b).validate( - s3.sign(p.getParent().toUri(), p.getFileName().toUri()))); // can read KeyInfo + s3.sign(p.toAbsolutePath().getParent().toUri(), p.getFileName().toUri()))); // can read KeyInfo Asserts.assertTrue(v1.validate(s1.sign("text"))); // plain text Asserts.assertTrue(v1.validate(s1.sign("binary".getBytes()))); // raw data + Asserts.assertTrue(v1.validate(s1.signEnveloping(d, "x", "#x"))); + Asserts.assertTrue(v1.validate(s1.signEnveloping(d, "x", "#xpointer(id('x'))"))); } //////////// CONVERT //////////// @@ -347,14 +349,14 @@ public class XMLUtils { } // Signs a document in enveloping mode - public Document signEnveloping(Document document) throws Exception { + public Document signEnveloping(Document document, String id, String ref) throws Exception { Document newDocument = DocumentBuilderFactory.newInstance() .newDocumentBuilder().newDocument(); FAC.newXMLSignature( - buildSignedInfo(FAC.newReference("#object", dm)), + buildSignedInfo(FAC.newReference(ref, dm)), buildKeyInfo(), List.of(FAC.newXMLObject(List.of(new DOMStructure(document.getDocumentElement())), - "object", null, null)), + id, null, null)), null, null) .sign(new DOMSignContext(privateKey, newDocument)); @@ -474,7 +476,7 @@ public class XMLUtils { // If key is not null, any key from the signature will be ignored public boolean validate(Document document, PublicKey key) throws Exception { - NodeList nodeList = document.getElementsByTagName("Signature"); + NodeList nodeList = document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (nodeList.getLength() == 1) { Node signatureNode = nodeList.item(0); if (signatureNode != null) { diff --git a/test/lib/jdk/test/lib/util/ClassTransformer.java b/test/lib/jdk/test/lib/util/ClassTransformer.java new file mode 100644 index 0000000000000000000000000000000000000000..7ace81df87b6ff7627b4b7108c57a4ee4e292117 --- /dev/null +++ b/test/lib/jdk/test/lib/util/ClassTransformer.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test.lib.util; + +import jdk.test.lib.compiler.CompilerUtils; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +// ClassTransformer provides functionality to transform java source and compile it. +// We cannot use InMemoryJavaCompiler as test files usually contain 2 classes (the test itself and debuggee) +// and InMemoryJavaCompiler cannot compile them. +public class ClassTransformer { + + private final List lines; + private String fileName; + private String workDir = "ver{0}"; + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + private ClassTransformer(List lines) { + this.lines = lines; + } + + public ClassTransformer setFileName(String fileName) { + this.fileName = fileName; + return this; + } + + // workDir is a MessageFormat pattern, id (int) is an {0} arg of the pattern. + // can be relative (relatively "scratch" dir) or absolute. + public ClassTransformer setWorkDir(String dir) { + workDir = dir; + return this; + } + + public static ClassTransformer fromString(String content) { + return new ClassTransformer(Arrays.asList(content.split("\\R"))); + } + + public static ClassTransformer fromFile(Path filePath) { + try { + return new ClassTransformer(Files.readAllLines(filePath)) + .setFileName(filePath.getFileName().toString()); + } catch (IOException e) { + throw new RuntimeException("failed to read " + filePath, e); + } + } + public static ClassTransformer fromFile(String filePath) { + return fromFile(Paths.get(filePath)); + } + + public static ClassTransformer fromTestSource(String fileName) { + return fromFile(Paths.get(System.getProperty("test.src")).resolve(fileName)); + } + + // returns path to the .class file of the transformed class + public String transform(int id, String className, String... compilerOptions) { + Path subdir = Paths.get(".").resolve(MessageFormat.format(workDir, id)); + Path transformedSrc = subdir.resolve(fileName); + try { + Files.createDirectories(subdir); + Files.write(transformedSrc, transform(id).getBytes()); + } catch (IOException e) { + throw new RuntimeException("failed to write transformed " + transformedSrc, e); + } + try { + // need to add extra classpath args + List args = new LinkedList<>(Arrays.asList(compilerOptions)); + args.add("-cp"); + args.add(System.getProperty("java.class.path")); + CompilerUtils.compile(subdir, subdir, false, args.toArray(new String[args.size()])); + } catch (IOException e) { + throw new RuntimeException("failed to compile " + transformedSrc, e); + } + return subdir.resolve(className + ".class").toString(); + } + + /* + * To do RedefineClasses operations, embed @1 tags in the .java + * file to tell this script how to modify it to produce the 2nd + * version of the .class file to be used in the redefine operation. + * Here are examples of each editing tag and what change + * it causes in the new file. Note that blanks are not preserved + * in these editing operations. + * + * @1 uncomment + * orig: // @1 uncomment gus = 89; + * new: gus = 89; + * + * @1 commentout + * orig: gus = 89 // @1 commentout + * new: // gus = 89 // @1 commentout + * + * @1 delete + * orig: gus = 89 // @1 delete + * new: entire line deleted + * + * @1 newline + * orig: gus = 89; // @1 newline gus++; + * new: gus = 89; // + * gus++; + * + * @1 replace + * orig: gus = 89; // @1 replace gus = 90; + * new: gus = 90; + */ + public String transform(int id) { + Pattern delete = Pattern.compile("@" + id + " *delete"); + Pattern uncomment = Pattern.compile("// *@" + id + " *uncomment (.*)"); + Pattern commentout = Pattern.compile(".* @" + id + " *commentout"); + Pattern newline = Pattern.compile("(.*) @" + id + " *newline (.*)"); + Pattern replace = Pattern.compile("@" + id + " *replace (.*)"); + return lines.stream() + .filter(s -> !delete.matcher(s).find()) // @1 delete + .map(s -> { + Matcher m = uncomment.matcher(s); // @1 uncomment + return m.find() ? m.group(1) : s; + }) + .map(s-> { + Matcher m = commentout.matcher(s); // @1 commentout + return m.find() ? "//" + s : s; + }) + .map(s -> { + Matcher m = newline.matcher(s); // @1 newline + return m.find() ? m.group(1) + LINE_SEPARATOR + m.group(2) : s; + }) + .map(s -> { + Matcher m = replace.matcher(s); // @1 replace + return m.find() ? m.group(1) : s; + }) + .collect(Collectors.joining(LINE_SEPARATOR)); + } + +} diff --git a/test/lib/jdk/test/lib/util/CoreUtils.java b/test/lib/jdk/test/lib/util/CoreUtils.java index d7e68e82f427e4819596fbe2d5f2ed2fd01a4e1d..c93357925934cb4dc6475221fac0976441aaeb71 100644 --- a/test/lib/jdk/test/lib/util/CoreUtils.java +++ b/test/lib/jdk/test/lib/util/CoreUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,8 +107,10 @@ public class CoreUtils { // Find the core file String coreFileLocation = parseCoreFileLocationFromOutput(crashOutputString); if (coreFileLocation != null) { - System.out.println("Found core file: " + coreFileLocation); - Asserts.assertGT(new File(coreFileLocation).length(), 0L, "Unexpected core size"); + long coreFileSize = new File(coreFileLocation).length(); + System.out.println("Found core file " + coreFileLocation + + ", size = " + coreFileSize / 1024 / 1024 + "mb"); + Asserts.assertGT(coreFileSize, 0L, "Unexpected core size"); // Make sure the core file is moved into the cwd if not already there. Path corePath = Paths.get(coreFileLocation); @@ -136,12 +138,12 @@ public class CoreUtils { if (!coresDir.canWrite()) { throw new SkippedException("Directory \"" + coresDir + "\" is not writable"); } - if (Platform.isSignedOSX()) { + if (Platform.isHardenedOSX()) { if (Platform.getOsVersionMajor() > 10 || (Platform.getOsVersionMajor() == 10 && Platform.getOsVersionMinor() >= 15)) { - // We can't generate cores files with signed binaries on OSX 10.15 and later. - throw new SkippedException("Cannot produce core file with signed binary on OSX 10.15 and later"); + // We can't generate cores files with hardened binaries on OSX 10.15 and later. + throw new SkippedException("Cannot produce core file with hardened binary on OSX 10.15 and later"); } } } else if (Platform.isLinux()) { diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index c4f90b975a4178f0d935d52d074c09c966e8394b..6fa0fb4c47aa4c378ef144bbe4bafb57272dee96 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -225,7 +225,6 @@ public class WhiteBox { public native void NMTReleaseMemory(long addr, long size); public native long NMTMallocWithPseudoStack(long size, int index); public native long NMTMallocWithPseudoStackAndType(long size, int index, int type); - public native boolean NMTChangeTrackingLevel(); public native int NMTGetHashSize(); public native long NMTNewArena(long initSize); public native void NMTFreeArena(long arena); @@ -624,6 +623,8 @@ public class WhiteBox { } // Sharing & archiving + public native int getCDSGenericHeaderMinVersion(); + public native int getCurrentCDSVersion(); public native String getDefaultArchivePath(); public native boolean cdsMemoryMappingFailed(); public native boolean isSharingEnabled(); diff --git a/test/lib/sun/hotspot/WhiteBox.java b/test/lib/sun/hotspot/WhiteBox.java index 4536e6080937a18d02792362c4ad01c080a5cd59..e80f284eaede2440946e5d1b6c473d2998535a16 100644 --- a/test/lib/sun/hotspot/WhiteBox.java +++ b/test/lib/sun/hotspot/WhiteBox.java @@ -226,7 +226,6 @@ public class WhiteBox { public native void NMTReleaseMemory(long addr, long size); public native long NMTMallocWithPseudoStack(long size, int index); public native long NMTMallocWithPseudoStackAndType(long size, int index, int type); - public native boolean NMTChangeTrackingLevel(); public native int NMTGetHashSize(); public native long NMTNewArena(long initSize); public native void NMTFreeArena(long arena); @@ -625,6 +624,8 @@ public class WhiteBox { } // Sharing & archiving + public native int getCDSGenericHeaderMinVersion(); + public native int getCurrentCDSVersion(); public native String getDefaultArchivePath(); public native boolean cdsMemoryMappingFailed(); public native boolean isSharingEnabled(); diff --git a/test/micro/org/openjdk/bench/java/lang/Integers.java b/test/micro/org/openjdk/bench/java/lang/Integers.java index c238ae5d735a96464303af2bc74c40bd5b01eec8..221dc79ee4c50ba7fde8a8c4e209bb0477c82e9b 100644 --- a/test/micro/org/openjdk/bench/java/lang/Integers.java +++ b/test/micro/org/openjdk/bench/java/lang/Integers.java @@ -53,17 +53,20 @@ public class Integers { private int size; private String[] strings; + private int[] intsTiny; private int[] intsSmall; private int[] intsBig; @Setup public void setup() { - Random r = new Random(0); - strings = new String[size]; + Random r = new Random(0); + strings = new String[size]; + intsTiny = new int[size]; intsSmall = new int[size]; - intsBig = new int[size]; + intsBig = new int[size]; for (int i = 0; i < size; i++) { strings[i] = "" + (r.nextInt(10000) - (5000)); + intsTiny[i] = r.nextInt(99); intsSmall[i] = 100 * i + i + 103; intsBig[i] = ((100 * i + i) << 24) + 4543 + i * 4; } @@ -91,6 +94,14 @@ public class Integers { } } + /** Performs toString on very small values, just one or two digits. */ + @Benchmark + public void toStringTiny(Blackhole bh) { + for (int i : intsTiny) { + bh.consume(Integer.toString(i)); + } + } + /** Performs toString on large values, roughly 10 digits. */ @Benchmark public void toStringBig(Blackhole bh) { diff --git a/test/micro/org/openjdk/bench/java/lang/StringDecode.java b/test/micro/org/openjdk/bench/java/lang/StringDecode.java index ace4252c7a3a310febae96f697c34994be280ef7..186d2aed6d95b99a5c1f06ab5b50c48083818075 100644 --- a/test/micro/org/openjdk/bench/java/lang/StringDecode.java +++ b/test/micro/org/openjdk/bench/java/lang/StringDecode.java @@ -40,59 +40,120 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(value = 3, jvmArgs = "-Xmx1g") +@Fork(value = 3) @Warmup(iterations = 5, time = 2) @Measurement(iterations = 5, time = 3) @State(Scope.Thread) public class StringDecode { - @BenchmarkMode(Mode.AverageTime) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - @Fork(value = 3, jvmArgs = "-Xmx1g") - @Warmup(iterations = 5, time = 2) - @Measurement(iterations = 5, time = 2) - @State(Scope.Thread) - public static class WithCharset { - - @Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6", "ISO-2022-KR"}) - private String charsetName; - - private Charset charset; - private byte[] asciiString; - private byte[] utf16String; - - @Setup - public void setup() { - charset = Charset.forName(charsetName); - asciiString = "ascii string".getBytes(charset); - utf16String = "UTF-\uFF11\uFF16 string".getBytes(charset); - } - - @Benchmark - public void decodeCharsetName(Blackhole bh) throws Exception { - bh.consume(new String(asciiString, charsetName)); - bh.consume(new String(utf16String, charsetName)); - } - - @Benchmark - public void decodeCharset(Blackhole bh) throws Exception { - bh.consume(new String(asciiString, charset)); - bh.consume(new String(utf16String, charset)); - } - } + @Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6", "ISO-2022-KR"}) + private String charsetName; - private byte[] asciiDefaultString; - private byte[] utf16DefaultString; + private Charset charset; + private byte[] asciiString; + private byte[] utf16String; + private byte[] longUtf16String; + private byte[] longUtf16StartString; + private byte[] longLatin1String; @Setup public void setup() { - asciiDefaultString = "ascii string".getBytes(); - utf16DefaultString = "UTF-\uFF11\uFF16 string".getBytes(); + charset = Charset.forName(charsetName); + asciiString = "ascii string".getBytes(charset); + utf16String = "UTF-\uFF11\uFF16 string".getBytes(charset); + longUtf16String = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac sem eu + urna egestas placerat. Etiam finibus ipsum nulla, non mattis dolor cursus a. + Nulla nec nisl consectetur, lacinia neque id, accumsan ante. Curabitur et + sapien in magna porta ultricies. Sed vel pellentesque nibh. Pellentesque dictum + dignissim diam eu ultricies. Class aptent taciti sociosqu ad litora torquent + per conubia nostra, per inceptos himenaeos. Suspendisse erat diam, fringilla + sed massa sed, posuere viverra orci. Suspendisse tempor libero non gravida + efficitur. Vivamus lacinia risus non orci viverra, at consectetur odio laoreet. + Suspendisse potenti. + + Phasellus vel nisi iaculis, accumsan quam sed, bibendum eros. Sed venenatis + nulla tortor, et eleifend urna sodales id. Nullam tempus ac metus sit amet + sollicitudin. Nam sed ex diam. Praesent vitae eros et neque condimentum + consectetur eget non tortor. Praesent bibendum vel felis nec dignissim. + Maecenas a enim diam. Suspendisse quis ligula at nisi accumsan lacinia id + hendrerit sapien. \uFF11Donec aliquam mattis lectus eu ultrices. Duis eu nisl\uFF11 + euismod, blandit mauris vel, \uFF11placerat urna. Etiam malesuada enim purus, + tristique mollis odio blandit quis.\uFF11 Vivamus posuere. \uFF11 + \uFF11 + """.getBytes(charset); + longUtf16StartString = """ + \uFF11 + Lorem ipsum dolor sit amet, \uFF11consectetur adipiscing elit. Aliquam ac sem eu + urna egestas \uFF11placerat. Etiam finibus ipsum nulla, non mattis dolor cursus a. + Nulla \uFF11nec nisl consectetur, lacinia neque id, accumsan ante. Curabitur et + sapien in \uFF11magna porta ultricies. \uFF11Sed vel pellentesque nibh. Pellentesque dictum + dignissim diam eu ultricies. Class aptent taciti sociosqu ad litora torquent + per conubia nostra, per inceptos himenaeos. Suspendisse erat diam, fringilla + sed massa sed, posuere viverra orci. Suspendisse tempor libero non gravida + efficitur. Vivamus lacinia risus non orci viverra, at consectetur odio laoreet. + Suspendisse potenti. + + Phasellus vel nisi iaculis, accumsan quam sed, bibendum eros. Sed venenatis + nulla tortor, et eleifend urna sodales id. Nullam tempus ac metus sit amet + sollicitudin. Nam sed ex diam. Praesent vitae eros et neque condimentum + consectetur eget non tortor. Praesent bibendum vel felis nec dignissim. + Maecenas a enim diam. Suspendisse quis ligula at nisi accumsan lacinia id + hendrerit sapien. Donec aliquam mattis lectus eu ultrices. Duis eu nisl + euismod, blandit mauris vel, placerat urna. Etiam malesuada enim purus, + tristique mollis odio blandit quis. Vivamus posuere. + """.getBytes(charset); + + longLatin1String = """ + a\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + b\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + c\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + d\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + e\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + f\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + g\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + h\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + i\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + j\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6 + k\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6 + l\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6 + m\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6 + """.getBytes(charset); + } + + @Benchmark + public String decodeAsciiCharsetName() throws Exception { + return new String(asciiString, charsetName); + } + + @Benchmark + public String decodeAscii() throws Exception { + return new String(asciiString, charset); + } + + @Benchmark + public String decodeLatin1Long() throws Exception { + return new String(longLatin1String, charset); + } + + @Benchmark + public String decodeUTF16Short() throws Exception { + return new String(utf16String, charset); + } + + @Benchmark + public String decodeUTF16LongEnd() throws Exception { + return new String(longUtf16String, charset); + } + + @Benchmark + public String decodeUTF16LongStart() throws Exception { + return new String(longUtf16StartString, charset); } @Benchmark - public void decodeDefault(Blackhole bh) throws Exception { - bh.consume(new String(asciiDefaultString)); - bh.consume(new String(utf16DefaultString)); + public void decodeUTF16LongMixed(Blackhole bh) throws Exception { + bh.consume(new String(longUtf16StartString, charset)); + bh.consume(new String(longUtf16String, charset)); } } diff --git a/test/micro/org/openjdk/bench/java/lang/StringEncode.java b/test/micro/org/openjdk/bench/java/lang/StringEncode.java index 4cf5032a0dad39bec490e1db562e0a28a9e55c9d..6e67d3e8cee74134d593af283bab7e0f9ed180b4 100644 --- a/test/micro/org/openjdk/bench/java/lang/StringEncode.java +++ b/test/micro/org/openjdk/bench/java/lang/StringEncode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,59 +30,97 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(value = 3, jvmArgs = "-Xmx1g") +@Fork(value = 3) @Warmup(iterations = 5, time = 2) @Measurement(iterations = 5, time = 3) @State(Scope.Thread) public class StringEncode { - @BenchmarkMode(Mode.AverageTime) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - @Fork(value = 3, jvmArgs = "-Xmx1g") - @Warmup(iterations = 5, time = 2) - @Measurement(iterations = 5, time = 2) - @State(Scope.Thread) - public static class WithCharset { + @Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6"}) + private String charsetName; + private Charset charset; + private String asciiString; + private String utf16String; + private String longUtf16String; + private String longUtf16StartString; - @Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6"}) - private String charsetName; + @Setup + public void setup() { + charset = Charset.forName(charsetName); + asciiString = "ascii string"; + utf16String = "UTF-\uFF11\uFF16 string"; + longUtf16String = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac sem eu + urna egestas placerat. Etiam finibus ipsum nulla, non mattis dolor cursus a. + Nulla nec nisl consectetur, lacinia neque id, accumsan ante. Curabitur et + sapien in magna porta ultricies. Sed vel pellentesque nibh. Pellentesque dictum + dignissim diam eu ultricies. Class aptent taciti sociosqu ad litora torquent + per conubia nostra, per inceptos himenaeos. Suspendisse erat diam, fringilla + sed massa sed, posuere viverra orci. Suspendisse tempor libero non gravida + efficitur. Vivamus lacinia risus non orci viverra, at consectetur odio laoreet. + Suspendisse potenti. - private Charset charset; - private String asciiString; - private String utf16String; + Phasellus vel nisi iaculis, accumsan quam sed, bibendum eros. Sed venenatis + nulla tortor, et eleifend urna sodales id. Nullam tempus ac metus sit amet + sollicitudin. Nam sed ex diam. Praesent vitae eros et neque condimentum + consectetur eget non tortor. Praesent bibendum vel felis nec dignissim. + Maecenas a enim diam. Suspendisse quis ligula at nisi accumsan lacinia id + hendrerit sapien. Donec aliquam mattis lectus eu ultrices. Duis eu nisl + euismod, blandit mauris vel, placerat urna. Etiam malesuada enim purus, + tristique mollis odio blandit quis. Vivamus posuere. + \uFF11 + """; + longUtf16StartString = """ + \uFF11 + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac sem eu + urna egestas placerat. Etiam finibus ipsum nulla, non mattis dolor cursus a. + Nulla nec nisl consectetur, lacinia neque id, accumsan ante. Curabitur et + sapien in magna porta ultricies. Sed vel pellentesque nibh. Pellentesque dictum + dignissim diam eu ultricies. Class aptent taciti sociosqu ad litora torquent + per conubia nostra, per inceptos himenaeos. Suspendisse erat diam, fringilla + sed massa sed, posuere viverra orci. Suspendisse tempor libero non gravida + efficitur. Vivamus lacinia risus non orci viverra, at consectetur odio laoreet. + Suspendisse potenti. - @Setup - public void setup() { - charset = Charset.forName(charsetName); - asciiString = "ascii string"; - utf16String = "UTF-\uFF11\uFF16 string"; - } + Phasellus vel nisi iaculis, accumsan quam sed, bibendum eros. Sed venenatis + nulla tortor, et eleifend urna sodales id. Nullam tempus ac metus sit amet + sollicitudin. Nam sed ex diam. Praesent vitae eros et neque condimentum + consectetur eget non tortor. Praesent bibendum vel felis nec dignissim. + Maecenas a enim diam. Suspendisse quis ligula at nisi accumsan lacinia id + hendrerit sapien. Donec aliquam mattis lectus eu ultrices. Duis eu nisl + euismod, blandit mauris vel, placerat urna. Etiam malesuada enim purus, + tristique mollis odio blandit quis. Vivamus posuere. + """; + } - @Benchmark - public void encodeCharsetName(Blackhole bh) throws Exception { - bh.consume(asciiString.getBytes(charsetName)); - bh.consume(utf16String.getBytes(charsetName)); - } + @Benchmark + public byte[] encodeAsciiCharsetName() throws Exception { + return asciiString.getBytes(charset); + } + + @Benchmark + public byte[] encodeAscii() throws Exception { + return asciiString.getBytes(charset); + } - @Benchmark - public void encodeCharset(Blackhole bh) throws Exception { - bh.consume(asciiString.getBytes(charset)); - bh.consume(utf16String.getBytes(charset)); - } + @Benchmark + public void encodeMix(Blackhole bh) throws Exception { + bh.consume(asciiString.getBytes(charset)); + bh.consume(utf16String.getBytes(charset)); } - private String asciiDefaultString; - private String utf16DefaultString; + @Benchmark + public byte[] encodeUTF16LongEnd() throws Exception { + return longUtf16String.getBytes(charset); + } - @Setup - public void setup() { - asciiDefaultString = "ascii string"; - utf16DefaultString = "UTF-\uFF11\uFF16 string"; + @Benchmark + public byte[] encodeUTF16LongStart() throws Exception { + return longUtf16StartString.getBytes(charset); } @Benchmark - public void encodeDefault(Blackhole bh) throws Exception { - bh.consume(asciiDefaultString.getBytes()); - bh.consume(utf16DefaultString.getBytes()); + public byte[] encodeUTF16() throws Exception { + return utf16String.getBytes(charset); } } diff --git a/test/micro/org/openjdk/bench/java/lang/ThreadOnSpinWait.java b/test/micro/org/openjdk/bench/java/lang/ThreadOnSpinWait.java index 72efedb59010614963ffb33e00ec8d945e9379dd..146d34bbd87dd77889077fedde1f0b69fd3f2954 100644 --- a/test/micro/org/openjdk/bench/java/lang/ThreadOnSpinWait.java +++ b/test/micro/org/openjdk/bench/java/lang/ThreadOnSpinWait.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon.com Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/micro/org/openjdk/bench/java/lang/ThreadOnSpinWaitProducerConsumer.java b/test/micro/org/openjdk/bench/java/lang/ThreadOnSpinWaitProducerConsumer.java index a4778838a84446c0aefc4c1aa446cb8d001f605c..c8662e2984db4369219a8b86fa6adc3e139f2cc0 100644 --- a/test/micro/org/openjdk/bench/java/lang/ThreadOnSpinWaitProducerConsumer.java +++ b/test/micro/org/openjdk/bench/java/lang/ThreadOnSpinWaitProducerConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Amazon.com Inc. or its affiliates. All rights reserved. + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java b/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java index 6e129a5466e895ea2f970e74ecbec48cf31ad226..404bb0583fdc791a1ca015362bb89f9dcfa260a0 100644 --- a/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java +++ b/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java @@ -61,7 +61,7 @@ public class CharsetEncodeDecode { private CharsetEncoder encoder; private CharsetDecoder decoder; - @Param({"UTF-8", "BIG5", "ISO-8859-15", "ASCII", "UTF-16"}) + @Param({"UTF-8", "BIG5", "ISO-8859-15", "ISO-8859-1", "ASCII", "UTF-16"}) private String type; @Param("16384") diff --git a/test/micro/org/openjdk/bench/java/text/ZoneStrings.java b/test/micro/org/openjdk/bench/java/text/ZoneStrings.java new file mode 100644 index 0000000000000000000000000000000000000000..383cc8e0b205bd7922dde9e9751ba396be66907d --- /dev/null +++ b/test/micro/org/openjdk/bench/java/text/ZoneStrings.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.text; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +import java.text.DateFormatSymbols; +import java.util.Locale; + +@BenchmarkMode(Mode.SingleShotTime) +@State(Scope.Thread) +public class ZoneStrings { + + @Benchmark + public void testZoneStrings() { + for (Locale l : Locale.getAvailableLocales()) { + new DateFormatSymbols(l).getZoneStrings(); + } + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstant.java b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstant.java index ada578b09ba24c757be68490f59e4883c5b33c87..1029acf7c2e3fe360a61159e35afb0dd34ee941f 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstant.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstant.java @@ -26,6 +26,7 @@ import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.MemoryLayout; import jdk.incubator.foreign.MemorySegment; import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.ValueLayout; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; @@ -61,6 +62,10 @@ public class LoopOverNonConstant { static final int ALLOC_SIZE = ELEM_SIZE * CARRIER_SIZE; static final VarHandle VH_int = MemoryLayout.sequenceLayout(JAVA_INT).varHandle(sequenceElement()); + + static final ValueLayout.OfInt JAVA_INT_ALIGNED = JAVA_INT.withBitAlignment(32); + static final VarHandle VH_int_aligned = MemoryLayout.sequenceLayout(JAVA_INT_ALIGNED).varHandle(sequenceElement()); + MemorySegment segment; long unsafe_addr; @@ -125,6 +130,15 @@ public class LoopOverNonConstant { return sum; } + @Benchmark + public int segment_loop_aligned() { + int sum = 0; + for (int i = 0; i < ELEM_SIZE; i++) { + sum += (int) VH_int_aligned.get(segment, (long) i); + } + return sum; + } + @Benchmark public int segment_loop_instance() { int sum = 0; @@ -145,6 +159,15 @@ public class LoopOverNonConstant { return sum; } + @Benchmark + public int segment_loop_instance_aligned() { + int res = 0; + for (int i = 0; i < ELEM_SIZE; i ++) { + res += segment.get(JAVA_INT_ALIGNED, i * CARRIER_SIZE); + } + return res; + } + @Benchmark public int segment_loop_instance_address() { int sum = 0; diff --git a/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstantHeap.java b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstantHeap.java index 5b51db08c00b2563aff61961a10bf7cd4607c1e1..2d6b605c2c545a5db9f3589b4cf8078cc2734f9a 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstantHeap.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverNonConstantHeap.java @@ -25,6 +25,7 @@ package org.openjdk.bench.jdk.incubator.foreign; import jdk.incubator.foreign.MemoryLayout; import jdk.incubator.foreign.MemorySegment; import jdk.incubator.foreign.ResourceScope; +import jdk.incubator.foreign.ValueLayout; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; @@ -66,8 +67,14 @@ public class LoopOverNonConstantHeap { static final int UNSAFE_BYTE_BASE = unsafe.arrayBaseOffset(byte[].class); static final VarHandle VH_int = MemoryLayout.sequenceLayout(JAVA_INT).varHandle(sequenceElement()); - MemorySegment segment; + + static final ValueLayout.OfInt JAVA_INT_ALIGNED = JAVA_INT.withBitAlignment(32); + static final VarHandle VH_int_aligned = MemoryLayout.sequenceLayout(JAVA_INT_ALIGNED).varHandle(sequenceElement()); + static final int UNSAFE_INT_BASE = unsafe.arrayBaseOffset(int[].class); + + MemorySegment segment, alignedSegment; byte[] base; + int[] alignedBase; ByteBuffer byteBuffer; @@ -95,7 +102,12 @@ public class LoopOverNonConstantHeap { for (int i = 0; i < ELEM_SIZE; i++) { unsafe.putInt(base, UNSAFE_BYTE_BASE + (i * CARRIER_SIZE) , i); } + alignedBase = new int[ELEM_SIZE]; + for (int i = 0; i < ELEM_SIZE; i++) { + unsafe.putInt(base, UNSAFE_INT_BASE + (i * CARRIER_SIZE) , i); + } segment = MemorySegment.ofArray(base); + alignedSegment = MemorySegment.ofArray(alignedBase); byteBuffer = ByteBuffer.wrap(base).order(ByteOrder.nativeOrder()); } @@ -135,6 +147,15 @@ public class LoopOverNonConstantHeap { return sum; } + @Benchmark + public int segment_loop_aligned() { + int sum = 0; + for (int i = 0; i < ELEM_SIZE; i++) { + sum += (int) VH_int_aligned.get(alignedSegment, (long) i); + } + return sum; + } + @Benchmark public int segment_loop_instance() { int res = 0; @@ -144,6 +165,15 @@ public class LoopOverNonConstantHeap { return res; } + @Benchmark + public int segment_loop_instance_aligned() { + int res = 0; + for (int i = 0; i < ELEM_SIZE; i ++) { + res += alignedSegment.get(JAVA_INT_ALIGNED, i * CARRIER_SIZE); + } + return res; + } + @Benchmark public int segment_loop_slice() { int sum = 0; diff --git a/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverPollutedSegments.java b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverPollutedSegments.java index 4cb01f091f1cc85de3ee1bc74d2d3083fe23c58c..d2803d9d7937bbfbf531caf045f3d9496f714c8c 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverPollutedSegments.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverPollutedSegments.java @@ -58,7 +58,7 @@ public class LoopOverPollutedSegments { static final Unsafe unsafe = Utils.unsafe; - MemorySegment nativeSegment, heapSegmentBytes, heapSegmentFloats; + MemorySegment nativeSegment, nativeSharedSegment, heapSegmentBytes, heapSegmentFloats; byte[] arr; long addr; @@ -73,6 +73,7 @@ public class LoopOverPollutedSegments { } arr = new byte[ALLOC_SIZE]; nativeSegment = MemorySegment.allocateNative(ALLOC_SIZE, 4, ResourceScope.newConfinedScope()); + nativeSharedSegment = MemorySegment.allocateNative(ALLOC_SIZE, 4, ResourceScope.newSharedScope()); heapSegmentBytes = MemorySegment.ofArray(new byte[ALLOC_SIZE]); heapSegmentFloats = MemorySegment.ofArray(new float[ELEM_SIZE]); @@ -81,6 +82,8 @@ public class LoopOverPollutedSegments { unsafe.putInt(arr, Unsafe.ARRAY_BYTE_BASE_OFFSET + (i * 4), i); nativeSegment.setAtIndex(JAVA_INT, i, i); nativeSegment.setAtIndex(JAVA_FLOAT, i, i); + nativeSharedSegment.setAtIndex(JAVA_INT, i, i); + nativeSharedSegment.setAtIndex(JAVA_FLOAT, i, i); intHandle.set(nativeSegment, (long)i, i); heapSegmentBytes.setAtIndex(JAVA_INT, i, i); heapSegmentBytes.setAtIndex(JAVA_FLOAT, i, i); diff --git a/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverSlice.java b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverSlice.java new file mode 100644 index 0000000000000000000000000000000000000000..ff5000f89c920d04f2a4f6ba8835b16778d0f369 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/foreign/LoopOverSlice.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.jdk.incubator.foreign; + +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.util.Iterator; +import java.util.concurrent.TimeUnit; + +import static jdk.incubator.foreign.MemoryLayout.PathElement.sequenceElement; +import static jdk.incubator.foreign.ValueLayout.JAVA_INT; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@State(org.openjdk.jmh.annotations.Scope.Thread) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Fork(value = 3, jvmArgsAppend = { "--add-modules=jdk.incubator.foreign", "--enable-native-access=ALL-UNNAMED" }) + +public class LoopOverSlice { + + static final int ELEM_SIZE = 1_000_000; + static final int CARRIER_SIZE = (int)JAVA_INT.byteSize(); + static final int ALLOC_SIZE = ELEM_SIZE * CARRIER_SIZE; + + MemorySegment nativeSegment, heapSegment; + IntBuffer nativeBuffer, heapBuffer; + ResourceScope scope; + + @Setup + public void setup() { + scope = ResourceScope.newConfinedScope(); + nativeSegment = MemorySegment.allocateNative(ALLOC_SIZE, scope); + heapSegment = MemorySegment.ofArray(new int[ELEM_SIZE]); + nativeBuffer = ByteBuffer.allocateDirect(ALLOC_SIZE).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(); + heapBuffer = IntBuffer.wrap(new int[ELEM_SIZE]); + } + + @TearDown + public void tearDown() { + scope.close(); + } + + @Benchmark + public void native_segment_slice_loop() { + new NativeSegmentWrapper(nativeSegment).forEach(NativeSegmentWrapper.Element::get); + } + + @Benchmark + public void native_buffer_slice_loop() { + new NativeBufferWrapper(nativeBuffer).forEach(NativeBufferWrapper.Element::get); + } + + @Benchmark + public void heap_segment_slice_loop() { + new HeapSegmentWrapper(heapSegment).forEach(HeapSegmentWrapper.Element::get); + } + + @Benchmark + public void heap_buffer_slice_loop() { + new HeapBufferWrapper(heapBuffer).forEach(HeapBufferWrapper.Element::get); + } + + class HeapSegmentWrapper implements Iterable { + final MemorySegment segment; + + public HeapSegmentWrapper(MemorySegment segment) { + this.segment = segment; + } + + @Override + public Iterator iterator() { + return new Iterator() { + + MemorySegment current = segment; + + @Override + public boolean hasNext() { + return current.byteSize() > 4; + } + + @Override + public Element next() { + Element element = new Element(current); + current = current.asSlice(4); + return element; + } + }; + } + + static class Element { + final MemorySegment segment; + + public Element(MemorySegment segment) { + this.segment = segment; + } + + int get() { + return segment.getAtIndex(JAVA_INT, 0); + } + } + } + + class NativeSegmentWrapper implements Iterable { + final MemorySegment segment; + + public NativeSegmentWrapper(MemorySegment segment) { + this.segment = segment; + } + + @Override + public Iterator iterator() { + return new Iterator() { + + MemorySegment current = segment; + + @Override + public boolean hasNext() { + return current.byteSize() > 4; + } + + @Override + public Element next() { + Element element = new Element(current); + current = current.asSlice(4); + return element; + } + }; + } + + static class Element { + final MemorySegment segment; + + public Element(MemorySegment segment) { + this.segment = segment; + } + + int get() { + return segment.getAtIndex(JAVA_INT, 0); + } + } + } + + class NativeBufferWrapper implements Iterable { + final IntBuffer buffer; + + public NativeBufferWrapper(IntBuffer buffer) { + this.buffer = buffer; + } + + @Override + public Iterator iterator() { + return new Iterator() { + + IntBuffer current = buffer; + + @Override + public boolean hasNext() { + return current.position() < current.limit(); + } + + @Override + public Element next() { + Element element = new Element(current); + int lim = current.limit(); + current = current.slice(1, lim - 1); + return element; + } + }; + } + + static class Element { + final IntBuffer buffer; + + public Element(IntBuffer segment) { + this.buffer = segment; + } + + int get() { + return buffer.get( 0); + } + } + } + + class HeapBufferWrapper implements Iterable { + final IntBuffer buffer; + + public HeapBufferWrapper(IntBuffer buffer) { + this.buffer = buffer; + } + + @Override + public Iterator iterator() { + return new Iterator() { + + IntBuffer current = buffer; + + @Override + public boolean hasNext() { + return current.position() < current.limit(); + } + + @Override + public Element next() { + Element element = new Element(current); + int lim = current.limit(); + current = current.slice(1, lim - 1); + return element; + } + }; + } + + static class Element { + final IntBuffer buffer; + + public Element(IntBuffer segment) { + this.buffer = segment; + } + + int get() { + return buffer.get( 0); + } + } + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskFromLongBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskFromLongBenchmark.java new file mode 100644 index 0000000000000000000000000000000000000000..e929697b57fba1e6b8663a7d0e002c1c906067e7 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskFromLongBenchmark.java @@ -0,0 +1,138 @@ +// +// Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License version 2 only, as +// published by the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). +// +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. +// +// +package org.openjdk.bench.jdk.incubator.vector; + +import jdk.incubator.vector.*; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@Fork(jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +public class MaskFromLongBenchmark { + static long val = 0; + + @Setup(Level.Invocation) + public void BmSetup() { + val++; + } + + @Benchmark + public int microMaskFromLong_Byte64() { + VectorMask mask = VectorMask.fromLong(ByteVector.SPECIES_64, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Byte128() { + VectorMask mask = VectorMask.fromLong(ByteVector.SPECIES_128, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Byte256() { + VectorMask mask = VectorMask.fromLong(ByteVector.SPECIES_256, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Byte512() { + VectorMask mask = VectorMask.fromLong(ByteVector.SPECIES_512, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Short64() { + VectorMask mask = VectorMask.fromLong(ShortVector.SPECIES_64, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Short128() { + VectorMask mask = VectorMask.fromLong(ShortVector.SPECIES_128, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Short256() { + VectorMask mask = VectorMask.fromLong(ShortVector.SPECIES_256, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Short512() { + VectorMask mask = VectorMask.fromLong(ShortVector.SPECIES_512, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Integer64() { + VectorMask mask = VectorMask.fromLong(IntVector.SPECIES_64, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Integer128() { + VectorMask mask = VectorMask.fromLong(IntVector.SPECIES_128, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Integer256() { + VectorMask mask = VectorMask.fromLong(IntVector.SPECIES_256, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Integer512() { + VectorMask mask = VectorMask.fromLong(IntVector.SPECIES_512, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Long64() { + VectorMask mask = VectorMask.fromLong(LongVector.SPECIES_64, val); + return mask.laneIsSet(0) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Long128() { + VectorMask mask = VectorMask.fromLong(LongVector.SPECIES_128, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Long256() { + VectorMask mask = VectorMask.fromLong(LongVector.SPECIES_256, val); + return mask.laneIsSet(1) ? 1 : 0; + } + + @Benchmark + public int microMaskFromLong_Long512() { + VectorMask mask = VectorMask.fromLong(LongVector.SPECIES_512, val); + return mask.laneIsSet(1) ? 1 : 0; + } + +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskedLogicOpts.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskedLogicOpts.java new file mode 100644 index 0000000000000000000000000000000000000000..97bfc5268086778a3d0ebb51e7c9f572d86b73c1 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskedLogicOpts.java @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.jdk.incubator.vector; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.*; + +import jdk.incubator.vector.*; +import java.util.concurrent.TimeUnit; +import java.util.Random; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class MaskedLogicOpts { + @Param({"256","512","1024"}) + private int ARRAYLEN; + + boolean [] mask_arr = { + false, false, false, true, false, false, false, false, + false, false, false, true, false, false, false, false, + false, false, false, true, false, false, false, false, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + false, false, false, true, false, false, false, false, + false, false, false, true, false, false, false, false, + false, false, false, true, false, false, false, false + }; + + int INVOC_COUNTER = 4096; + + int [] i1 = new int[ARRAYLEN]; + int [] i2 = new int[ARRAYLEN]; + int [] i3 = new int[ARRAYLEN]; + int [] i4 = new int[ARRAYLEN]; + int [] i5 = new int[ARRAYLEN]; + + long [] l1 = new long[ARRAYLEN]; + long [] l2 = new long[ARRAYLEN]; + long [] l3 = new long[ARRAYLEN]; + long [] l4 = new long[ARRAYLEN]; + long [] l5 = new long[ARRAYLEN]; + + Vector iv1; + Vector iv2; + Vector iv3; + Vector iv4; + Vector iv5; + + Vector lv1; + Vector lv2; + Vector lv3; + Vector lv4; + Vector lv5; + + VectorMask imask; + VectorMask lmask; + + VectorSpecies ispecies; + VectorSpecies lspecies; + + int int512_arr_idx; + int int256_arr_idx; + int int128_arr_idx; + int long256_arr_idx; + int long512_arr_idx; + + private Random r = new Random(); + + @Setup(Level.Trial) + public void init() { + int512_arr_idx = 0; + int256_arr_idx = 0; + int128_arr_idx = 0; + long256_arr_idx = 0; + long512_arr_idx = 0; + i1 = new int[ARRAYLEN]; + i2 = new int[ARRAYLEN]; + i3 = new int[ARRAYLEN]; + i4 = new int[ARRAYLEN]; + i5 = new int[ARRAYLEN]; + + l1 = new long[ARRAYLEN]; + l2 = new long[ARRAYLEN]; + l3 = new long[ARRAYLEN]; + l4 = new long[ARRAYLEN]; + l5 = new long[ARRAYLEN]; + + for (int i=0; i SPECIES) { + imask = VectorMask.fromArray(SPECIES, mask_arr, 0); + iv2 = IntVector.fromArray(SPECIES, i2, int512_arr_idx); + iv3 = IntVector.fromArray(SPECIES, i3, int512_arr_idx); + iv4 = IntVector.fromArray(SPECIES, i4, int512_arr_idx); + iv5 = IntVector.fromArray(SPECIES, i5, int512_arr_idx); + for(int i = 0; i < INVOC_COUNTER; i++) { + for(int j = 0 ; j < ARRAYLEN; j+= SPECIES.length()) { + IntVector.fromArray(SPECIES, i1, j) + .lanewise(VectorOperators.AND, iv2, imask) + .lanewise(VectorOperators.OR, iv2, imask) + .lanewise(VectorOperators.AND, iv3, imask) + .lanewise(VectorOperators.OR, iv3, imask) + .lanewise(VectorOperators.AND, iv4, imask) + .lanewise(VectorOperators.OR, iv4, imask) + .lanewise(VectorOperators.AND, iv5, imask) + .lanewise(VectorOperators.XOR, iv5, imask) + .intoArray(i1, j); + } + } + } + + @Benchmark + public void maskedLogicOperationsInt512() { + maskedLogicKernel(IntVector.SPECIES_512); + } + + @Benchmark + public void maskedLogicOperationsInt256() { + maskedLogicKernel(IntVector.SPECIES_256); + } + + @Benchmark + public void maskedLogicOperationsInt128() { + maskedLogicKernel(IntVector.SPECIES_128); + } + + @CompilerControl(CompilerControl.Mode.INLINE) + public void partiallyMaskedLogicOperationsIntKernel(VectorSpecies SPECIES) { + imask = VectorMask.fromArray(SPECIES, mask_arr, 0); + iv2 = IntVector.fromArray(SPECIES, i2, int512_arr_idx); + iv3 = IntVector.fromArray(SPECIES, i3, int512_arr_idx); + iv4 = IntVector.fromArray(SPECIES, i4, int512_arr_idx); + iv5 = IntVector.fromArray(SPECIES, i5, int512_arr_idx); + for(int i = 0; i < INVOC_COUNTER; i++) { + for(int j = 0 ; j < ARRAYLEN; j+= SPECIES.length()) { + IntVector.fromArray(SPECIES, i1, j) + .lanewise(VectorOperators.AND, iv2, imask) + .lanewise(VectorOperators.OR, iv2, imask) + .lanewise(VectorOperators.AND, iv3) + .lanewise(VectorOperators.OR, iv3) + .lanewise(VectorOperators.OR, iv4, imask) + .lanewise(VectorOperators.AND, iv4, imask) + .lanewise(VectorOperators.XOR, iv5, imask) + .intoArray(i1, j); + } + } + } + + @Benchmark + public void partiallyMaskedLogicOperationsInt512() { + partiallyMaskedLogicOperationsIntKernel(IntVector.SPECIES_512); + } + + @Benchmark + public void partiallyMaskedLogicOperationsInt256() { + partiallyMaskedLogicOperationsIntKernel(IntVector.SPECIES_256); + } + + @Benchmark + public void partiallyMaskedLogicOperationsInt128() { + partiallyMaskedLogicOperationsIntKernel(IntVector.SPECIES_128); + } + + @CompilerControl(CompilerControl.Mode.INLINE) + public void bitwiseBlendOperationIntKernel(VectorSpecies SPECIES) { + imask = VectorMask.fromArray(SPECIES, mask_arr, 0); + iv2 = IntVector.fromArray(SPECIES, i2, int512_arr_idx); + iv3 = IntVector.fromArray(SPECIES, i3, int512_arr_idx); + iv4 = IntVector.fromArray(SPECIES, i4, int512_arr_idx); + iv5 = IntVector.fromArray(SPECIES, i5, int512_arr_idx); + for(int i = 0; i < INVOC_COUNTER; i++) { + for(int j = 0 ; j < ARRAYLEN; j+= SPECIES.length()) { + IntVector.fromArray(SPECIES, i1, j) + .lanewise(VectorOperators.BITWISE_BLEND, iv2, iv3, imask) + .lanewise(VectorOperators.BITWISE_BLEND, iv3, iv4, imask) + .lanewise(VectorOperators.BITWISE_BLEND, iv4, iv5, imask) + .intoArray(i1, j); + } + } + } + + @Benchmark + public void bitwiseBlendOperationInt512() { + bitwiseBlendOperationIntKernel(IntVector.SPECIES_512); + } + + @Benchmark + public void bitwiseBlendOperationInt256() { + bitwiseBlendOperationIntKernel(IntVector.SPECIES_256); + } + + @Benchmark + public void bitwiseBlendOperationInt128() { + bitwiseBlendOperationIntKernel(IntVector.SPECIES_128); + } + + @CompilerControl(CompilerControl.Mode.INLINE) + public void maskedLogicOperationsLongKernel(VectorSpecies SPECIES) { + lmask = VectorMask.fromArray(SPECIES, mask_arr, 0); + lv2 = LongVector.fromArray(SPECIES, l2, long256_arr_idx); + lv3 = LongVector.fromArray(SPECIES, l3, long256_arr_idx); + lv4 = LongVector.fromArray(SPECIES, l4, long256_arr_idx); + lv5 = LongVector.fromArray(SPECIES, l5, long256_arr_idx); + for(int i = 0; i < INVOC_COUNTER; i++) { + for(int j = 0 ; j < ARRAYLEN; j+= SPECIES.length()) { + LongVector.fromArray(SPECIES, l1, j) + .lanewise(VectorOperators.AND, lv2, lmask) + .lanewise(VectorOperators.OR, lv3, lmask) + .lanewise(VectorOperators.AND, lv3, lmask) + .lanewise(VectorOperators.OR, lv4, lmask) + .lanewise(VectorOperators.AND, lv4, lmask) + .lanewise(VectorOperators.XOR, lv5, lmask) + .intoArray(l1, j); + } + } + } + + @Benchmark + public void maskedLogicOperationsLong512() { + maskedLogicOperationsLongKernel(LongVector.SPECIES_512); + } + @Benchmark + public void maskedLogicOperationsLong256() { + maskedLogicOperationsLongKernel(LongVector.SPECIES_256); + } + + @CompilerControl(CompilerControl.Mode.INLINE) + public void partiallyMaskedLogicOperationsLongKernel(VectorSpecies SPECIES) { + lmask = VectorMask.fromArray(SPECIES, mask_arr, 0); + lv2 = LongVector.fromArray(SPECIES, l2, long512_arr_idx); + lv3 = LongVector.fromArray(SPECIES, l3, long512_arr_idx); + lv4 = LongVector.fromArray(SPECIES, l4, long512_arr_idx); + lv5 = LongVector.fromArray(SPECIES, l5, long512_arr_idx); + for(int i = 0; i < INVOC_COUNTER; i++) { + for(int j = 0 ; j < ARRAYLEN; j+= SPECIES.length()) { + LongVector.fromArray(SPECIES, l1, j) + .lanewise(VectorOperators.AND, lv2, lmask) + .lanewise(VectorOperators.OR, lv2, lmask) + .lanewise(VectorOperators.AND, lv3) + .lanewise(VectorOperators.OR, lv3) + .lanewise(VectorOperators.AND, lv4) + .lanewise(VectorOperators.OR, lv4, lmask) + .lanewise(VectorOperators.XOR, lv5, lmask) + .intoArray(l1, j); + } + } + } + + @Benchmark + public void partiallyMaskedLogicOperationsLong512() { + partiallyMaskedLogicOperationsLongKernel(LongVector.SPECIES_512); + } + + @Benchmark + public void partiallyMaskedLogicOperationsLong256() { + partiallyMaskedLogicOperationsLongKernel(LongVector.SPECIES_256); + } + + @CompilerControl(CompilerControl.Mode.INLINE) + public void bitwiseBlendOperationLongKernel(VectorSpecies SPECIES) { + lmask = VectorMask.fromArray(SPECIES, mask_arr, 0); + lv2 = LongVector.fromArray(SPECIES, l2, long512_arr_idx); + lv3 = LongVector.fromArray(SPECIES, l3, long512_arr_idx); + lv4 = LongVector.fromArray(SPECIES, l4, long512_arr_idx); + lv5 = LongVector.fromArray(SPECIES, l5, long512_arr_idx); + for(int i = 0; i < INVOC_COUNTER; i++) { + for(int j = 0 ; j < ARRAYLEN; j+= SPECIES.length()) { + LongVector.fromArray(SPECIES, l1, j) + .lanewise(VectorOperators.BITWISE_BLEND, lv2, lv3, lmask) + .lanewise(VectorOperators.BITWISE_BLEND, lv3, lv4, lmask) + .lanewise(VectorOperators.BITWISE_BLEND, lv4, lv5, lmask) + .intoArray(l1, j); + } + } + } + + @Benchmark + public void bitwiseBlendOperationLong512() { + bitwiseBlendOperationLongKernel(LongVector.SPECIES_512); + } + + @Benchmark + public void bitwiseBlendOperationLong256() { + bitwiseBlendOperationLongKernel(LongVector.SPECIES_256); + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/AddIdealNotXPlusC.java b/test/micro/org/openjdk/bench/vm/compiler/AddIdealNotXPlusC.java new file mode 100644 index 0000000000000000000000000000000000000000..057a1dc6104c3c3fa95f23e18edbc0ebc9be61ce --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/AddIdealNotXPlusC.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.CompilerControl; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +/** + * Tests transformation that converts "~x + c" into "(c - 1) - x" in + * AddNode::IdealIL and "~(x+c)" into "(-c - 1) - x" in XorINode:Ideal + * and XorLNode::Ideal. + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) +public class AddIdealNotXPlusC { + + private static final int I_C = 1234567; + + private static final long L_C = 123_456_789_123_456L; + + private int iFld = 4711; + + private long lFld = 4711 * 4711 * 4711; + + private final int SIZE = 10; + + @Benchmark + public void baselineInt(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(iFld); + } + } + + @Benchmark + public void baselineLong(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(lFld); + } + } + + // Convert "~x + c" into "(c - 1) - x" for int. + // (c - 1) -x + x is then converted into c - 1. + @Benchmark + public void testInt1(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(~iFld + I_C + iFld); + } + } + + // Convert "~(x + c)" into "(-c - 1) - x" for int. + // (-c - 1) -x + x is then converted into -c - 1. + @Benchmark + public void testInt2(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(~(iFld + I_C) + iFld); + } + } + + // Convert "~x + c" into "(c - 1) - x" for long. + // (c - 1) -x + x is then converted into c - 1. + @Benchmark + public void testLong1(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(~lFld + L_C + lFld); + } + } + + // Convert "~(x + c)" into "(-c - 1) - x" for long. + // (-c - 1) -x + x is then converted into -c - 1. + @Benchmark + public void testLong2(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(~(lFld + L_C) + lFld); + } + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/AutoVectorization2DArray.java b/test/micro/org/openjdk/bench/vm/compiler/AutoVectorization2DArray.java new file mode 100644 index 0000000000000000000000000000000000000000..9155bfbd3de5f3169bc2a6597a583640e70a2bc6 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/AutoVectorization2DArray.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.*; +import java.util.concurrent.TimeUnit; + +@Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +@Fork(value=1) +public class AutoVectorization2DArray { + @Param({"16", "32", "64"}) + private int LEN; + + private byte[][] a_byte; + private byte[][] b_byte; + private byte[][] c_byte; + + private int[][] a_int; + private int[][] b_int; + private int[][] c_int; + + private double[][] a_double; + private double[][] b_double; + private double[][] c_double; + + @Setup + public void init() { + a_byte = new byte[LEN][LEN]; + b_byte = new byte[LEN][LEN]; + c_byte = new byte[LEN][LEN]; + + a_int = new int[LEN][LEN]; + b_int = new int[LEN][LEN]; + c_int = new int[LEN][LEN]; + + a_double = new double[LEN][LEN]; + b_double = new double[LEN][LEN]; + c_double = new double[LEN][LEN]; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + private int run_byte(int count, byte[][] a , byte[][] b, byte[][] c) { + for(int i = 0; i < a.length; i++) { + for (int j = 0; j < a[0].length; j++) { + a[i][j] = (byte)(b[i][j] + c[i][j]); + } + } + return a[count][count]; + } + + @Benchmark + public void test_run_byte(Blackhole bh) { + int r = 0; + for(int i = 0 ; i < 100; i++) { + r += run_byte(i % a_byte.length, a_byte, b_byte, c_byte); + } + bh.consume(r); + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + private int run_int(int count, int[][] a, int[][] b, int[][] c) { + for(int i = 0; i < a.length; i++) { + for (int j = 0; j < a[0].length; j++) { + a[i][j] = b[i][j] + c[i][j]; + } + } + return a[count][count]; + } + + @Benchmark + public void test_run_int(Blackhole bh) { + int r = 0; + for(int i = 0 ; i < 100; i++) { + r += run_int(i % a_int.length, a_int, b_int, c_int); + } + bh.consume(r); + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + private double run_double(int count, double[][] a, double[][] b, double[][] c) { + for(int i = 0; i < a.length; i++) { + for (int j = 0; j < a[0].length; j++) { + a[i][j] = b[i][j] + c[i][j]; + } + } + return a[count][count]; + } + + @Benchmark + public void test_run_double(Blackhole bh) { + double r = 0; + for(int i = 0 ; i < 100; i++) { + r += run_double(i % a_double.length, a_double, b_double, c_double); + } + bh.consume(r); + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/IterativeEA.java b/test/micro/org/openjdk/bench/vm/compiler/IterativeEA.java new file mode 100644 index 0000000000000000000000000000000000000000..26e75f0e05270783bcc677cf7ba7ae2b8b262809 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/IterativeEA.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Fork(1) + +public class IterativeEA { + + public static int ii = 1; + + static class A { + int i; + + public A(int i) { + this.i = i; + } + } + + static class B { + A a; + + public B(A a) { + this.a = a; + } + } + + static class C { + B b; + + public C(B b) { + this.b = b; + } + } + + @Benchmark + public int test1() { + C c = new C(new B(new A(ii))); + return c.b.a.i; + } + + static class Point { + int x; + int y; + int ax[]; + int ay[]; + } + + @Benchmark + public int test2() { + Point p = new Point(); + p.ax = new int[2]; + p.ay = new int[2]; + int x = 3; + p.ax[0] = x; + p.ay[1] = 3 * x + ii; + return p.ax[0] * p.ay[1]; + } + + public static final Double dbc = Double.valueOf(1.); + + @Benchmark + public double test3() { + Double j1 = Double.valueOf(1.); + Double j2 = Double.valueOf(1.); + for (int i = 0; i< 1000; i++) { + j1 = j1 + 1.; + j2 = j2 + 2.; + } + return j1 + j2; + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/LShiftIdeal_XPlusX_LShiftC.java b/test/micro/org/openjdk/bench/vm/compiler/LShiftIdeal_XPlusX_LShiftC.java new file mode 100644 index 0000000000000000000000000000000000000000..d2726706151a634d8ee63bcbc87799b9cc1b1268 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/LShiftIdeal_XPlusX_LShiftC.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.CompilerControl; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +/** + * Tests transformation from "(x + x) << c" to "x << (c + 1)". + *

        + * This benchmark needs to be run with {@code + * JAVA_OPTIONS=-Djmh.blackhole.mode=COMPILER} to force using compiler + * mode blackhole, which is enabled by default and thus not necessary + * since JMH 1.34. + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) +public class LShiftIdeal_XPlusX_LShiftC { + + private int iFld = 4711; + + private long lFld = 4711 * 4711 * 4711; + + private final int SIZE = 10; + + @Benchmark + public void baselineInt(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(iFld); + } + } + + @Benchmark + public void baselineLong(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(lFld); + } + } + + // Convert "(x + x) << 10" into "x << 11" for int. + // (x << 11) >>> 11 is then further converted into zero-extends. + @Benchmark + public void testInt(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(((iFld + iFld) << 10) >>> 11); + } + } + + // Convert "(x + x) << 40" into "x << 41" for long. + // (x << 41) >>> 41 is then further converted into zero-extends. + @Benchmark + public void testLong(Blackhole bh) { + for (int i = 0; i < SIZE; i++) { + bh.consume(((lFld + lFld) << 40) >>> 41); + } + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/MacroLogicOpt.java b/test/micro/org/openjdk/bench/vm/compiler/MacroLogicOpt.java index 58400cadf68280226b16c04c03e4e22772caee82..40c3ba1b2bac1171b977a976dab2d6c9bd9721a5 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/MacroLogicOpt.java +++ b/test/micro/org/openjdk/bench/vm/compiler/MacroLogicOpt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ import java.util.Random; @OutputTimeUnit(TimeUnit.SECONDS) @State(Scope.Thread) public class MacroLogicOpt { - @Param({"64","128","256","512","1024","2048","4096"}) private int VECLEN; + @Param({"64","128","256","512","1024"}) private int VECLEN; private int [] ai = new int[VECLEN]; private int [] bi = new int[VECLEN]; diff --git a/test/micro/org/openjdk/bench/vm/compiler/PointerBenchmarkFlat.java b/test/micro/org/openjdk/bench/vm/compiler/PointerBenchmarkFlat.java new file mode 100644 index 0000000000000000000000000000000000000000..f83e494b2c96df54c4975a5eab9ec32e75ae3dd3 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/PointerBenchmarkFlat.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; + +@Fork(value = 3) +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +public class PointerBenchmarkFlat { + + static final int ELEM_SIZE = 1_000_000; + + PointerImpl ptr_ptr; + PointerImplFlat ptr_ptr_flat; + + @Setup + public void setup() { + ptr_ptr = new PointerImpl(new FakeSegment(MemoryAddress.NULL, Long.MAX_VALUE)); + ptr_ptr_flat = new PointerImplFlat(new FakeSegmentFlat(MemoryAddress.NULL, Long.MAX_VALUE)); + } + + static class MemoryAddress { + private long addr; + + public MemoryAddress(long addr) { + this.addr = addr; + } + + long toRawLongValue() { + return addr; + } + + private static final MemoryAddress NULL = new MemoryAddress(0); + + static MemoryAddress ofLong(long val) { + return new MemoryAddress(val); + } + } + + static class PointerImpl { + final FakeSegment segment; + + public PointerImpl(FakeSegment segment) { + this.segment = segment; + } + + MemoryAddress address() { + return segment.address(); + } + + PointerImpl get(long index) { + MemoryAddress address = MemoryAddress.ofLong(index); + FakeSegment holder = new FakeSegment(address, Long.MAX_VALUE); + return new PointerImpl(holder); + } + } + + static class PointerImplFlat { + final FakeSegmentFlat segment; + + public PointerImplFlat(FakeSegmentFlat segment) { + this.segment = segment; + } + + MemoryAddress address() { + return segment.address(); + } + + PointerImplFlat get(long index) { + MemoryAddress address = MemoryAddress.ofLong(index); + FakeSegmentFlat holder = new FakeSegmentFlat(address, Long.MAX_VALUE); + return new PointerImplFlat(holder); + } + } + + static class AbstractFakeSegment { + final long size; + + public AbstractFakeSegment(long size) { + this.size = size; + } + } + + static class FakeSegment extends AbstractFakeSegment { + final MemoryAddress address; + + public FakeSegment(MemoryAddress address, long size) { + super(size); + this.address = address; + } + + MemoryAddress address() { + return address; + } + } + + static class FakeSegmentFlat { + final MemoryAddress address; + final long size; + + public FakeSegmentFlat(MemoryAddress address, long size) { + this.size = size; + this.address = address; + } + + MemoryAddress address() { + return address; + } + } + + @Benchmark + public int test() { + int sum = 0; + for (int i = 0 ; i < ELEM_SIZE ; i++) { + sum += ptr_ptr.get(i).address().toRawLongValue(); + } + return sum; + } + + @Benchmark + public int testFlat() { + int sum = 0; + for (int i = 0 ; i < ELEM_SIZE ; i++) { + sum += ptr_ptr_flat.get(i).address().toRawLongValue(); + } + return sum; + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java b/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java new file mode 100644 index 0000000000000000000000000000000000000000..e84ca35ab27658767987aff6506b4e73fd6b5d7f --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Mode; +import java.util.concurrent.TimeUnit; + +@State(Scope.Thread) +public class SharedLoopHeader { + + private static final int size = 1000; + private static final boolean branch[] = new boolean[size]; + private static final int count[] = new int[size]; + + @Setup + public void setup() { + for (int i = 0; i < branch.length; i++) { + branch[i] = ((i % 10) != 0); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void sharedHeader() { + int i = 0; + while (i < branch.length) { + if (branch[i]) { + // common branch + count[i]++; + i++; + continue; + } + i += 2; + } + } + +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java b/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java new file mode 100644 index 0000000000000000000000000000000000000000..4763c59629c5cd9aa10836fdd90bb830e3a59451 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Setup; +import java.util.concurrent.TimeUnit; +import java.nio.charset.StandardCharsets; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +public class StringConstructorBenchmark { + private byte[] array; + private String str; + + @Setup + public void setup() { + str = "Quizdeltagerne spiste jordb\u00e6r med fl\u00f8de, mens cirkusklovnen. \u042f";//Latin1 ending with Russian + array = str.getBytes(StandardCharsets.UTF_8); + } + + @Benchmark + public String newString() { + return new String(array, 0, array.length, StandardCharsets.UTF_8); + } + + @Benchmark + public String translateEscapes() { + return str.translateEscapes(); + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/SubIdealC0Minus_YPlusC1_.java b/test/micro/org/openjdk/bench/vm/compiler/SubIdealC0Minus_YPlusC1_.java new file mode 100644 index 0000000000000000000000000000000000000000..17728f6bc2589decdacbbe4dead337f4022b40c9 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/SubIdealC0Minus_YPlusC1_.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.CompilerControl; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +/** + * Tests transformation that converts "c0 - (x + c1)" into "(c0 - c1) + * - x" in SubINode::Ideal and SubLNode::Ideal. + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3 , jvmArgsAppend = {"-XX:-TieredCompilation", "-Xbatch", "-Xcomp"}) +public class SubIdealC0Minus_YPlusC1_ { + + private static final int I_C0 = 1234567; + + private static final int I_C1 = 1234567; + + private static final long L_C0 = 123_456_789_123_456L; + + private static final long L_C1 = 123_456_789_123_456L; + + private final int size = 100_000_000; + + private int[] ints_a; + + private long[] longs_a; + + @Setup + public void init() { + ints_a = new int[size]; + longs_a = new long[size]; + for (int i = 0; i < size; i++) { + ints_a[i] = i; + longs_a[i] = i * i; + } + } + + @Benchmark + public void baseline() { + for (int i = 0; i < size; i++) { + sink(ints_a[i]); + sink(longs_a[i]); + } + } + + @Benchmark + public void test() { + for (int i = 0; i < size; i++) { + sink(helper(ints_a[i])); + sink(helper(longs_a[i])); + } + } + + // Convert "c0 - (x + c1)" into "(c0 - c1) - x" for int. + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + private static int helper(int x) { + return I_C0 - (x + I_C1); + } + + // Convert "c0 - (x + c1)" into "(c0 - c1) - x" for long. + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + private static long helper(long x) { + return L_C0 - (x + L_C1); + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + private static void sink(int v) {} + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + private static void sink(long v) {} +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorBitCount.java b/test/micro/org/openjdk/bench/vm/compiler/VectorBitCount.java new file mode 100644 index 0000000000000000000000000000000000000000..e16cf422a9df19a668b36567b35da01b22887e37 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorBitCount.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.*; +import java.util.concurrent.TimeUnit; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +public abstract class VectorBitCount { + @Param({"1024"}) + public int SIZE; + + @Param("0") + private int seed; + private RandomGenerator rng = RandomGeneratorFactory.getDefault().create(seed); + private int[] bufferRandInts; + private long[] bufferRandLongs; + private int[] bitCounts; + @Setup + public void init() { + bufferRandInts = new int[SIZE]; + bufferRandLongs = new long[SIZE]; + bitCounts = new int[SIZE]; + + for (int i = 0; i < SIZE; i++) { + bufferRandInts[i] = rng.nextInt(); + bufferRandLongs[i] = rng.nextLong(); + } + } + + @Benchmark + public int[] intBitCount() { + for (int i = 0; i < SIZE; i++) { + bitCounts[i] = Integer.bitCount(bufferRandInts[i]); + } + return bitCounts; + } + + @Benchmark + public int[] longBitCount() { + for (int i = 0; i < SIZE; i++) { + bitCounts[i] = Long.bitCount(bufferRandLongs[i]); + } + return bitCounts; + } + + + @Fork(value = 1, jvmArgsPrepend = { + "-XX:+UseSuperWord" + }) + public static class WithSuperword extends VectorBitCount { + + } + + @Fork(value = 1, jvmArgsPrepend = { + "-XX:-UseSuperWord" + }) + public static class NoSuperword extends VectorBitCount { + } + +} +